{
  "format": "nodecrypto",
  "formatVersion": 1,
  "protection": "public",
  "manifest": {
    "label": "did-auth-demo",
    "version": "",
    "description": "학습용, 공개 데모 키, 매 실행마다 키쌍과 nonce가 새로 생성됨.",
    "category": "User Protocol",
    "inputs": [],
    "outputs": [
      {
        "id": "in_mvhhwt5n_hzn",
        "name": "Verified",
        "dataType": "bool"
      }
    ]
  },
  "requires": [],
  "workflow": {
    "name": "did-auth-demo",
    "description": "학습용, 공개 데모 키, 매 실행마다 키쌍과 nonce가 새로 생성됨.",
    "viewport": {
      "x": 372,
      "y": 96,
      "zoom": 1
    },
    "nodes": [
      {
        "id": "node-1792549010824-p91k",
        "type": "cryptoNode",
        "position": {
          "x": 704,
          "y": 192
        },
        "data": {
          "id": "node-1792549010824-p91k",
          "type": "cryptoNode",
          "nodeType": "sha256:24b2a81aaebc9bf83e6566f6d57fa402f664dcf918fdcfc5c20ee2156ea937ec",
          "label": "DID Auth - Server",
          "category": "User Protocol",
          "description": "",
          "inputs": [
            {
              "id": "nonce",
              "name": "Nonce",
              "dataType": "bytes",
              "spec": "32 B",
              "required": true
            },
            {
              "id": "prv",
              "name": "Server Private Key",
              "dataType": "bytes",
              "spec": "32 B",
              "required": true
            },
            {
              "id": "cpub",
              "name": "Client Public Key",
              "dataType": "bytes",
              "spec": "65 B",
              "required": true
            },
            {
              "id": "rmac",
              "name": "Received MAC",
              "dataType": "bytes",
              "spec": "8 B",
              "required": true
            }
          ],
          "outputs": [
            {
              "id": "ok",
              "name": "Verified",
              "dataType": "bool"
            }
          ],
          "properties": {},
          "customWidth": 352
        },
        "measured": {
          "width": 352,
          "height": 209
        },
        "selected": false,
        "dragging": false,
        "width": 352,
        "resizing": false,
        "style": {
          "width": 352
        }
      },
      {
        "id": "node-1792549047067-5x2i",
        "type": "cryptoNode",
        "position": {
          "x": -160,
          "y": 448
        },
        "data": {
          "id": "node-1792549047067-5x2i",
          "type": "cryptoNode",
          "nodeType": "asymmetric-ecc-keygen",
          "label": "Server Keypair",
          "category": "asymmetric",
          "description": "Generates Elliptic Curve keypair (NIST P-256/384/521, secp256k1, Brainpool)",
          "inputs": [],
          "outputs": [
            {
              "id": "privateKey",
              "name": "Private Key",
              "dataType": "bytes"
            },
            {
              "id": "publicKey",
              "name": "Public Key",
              "spec": "Uncompressed",
              "dataType": "bytes",
              "description": "Uncompressed EC point (0x04 prefix + X + Y coordinates)."
            }
          ],
          "properties": {
            "curve": "p256"
          },
          "customWidth": 208
        },
        "measured": {
          "width": 208,
          "height": 174
        },
        "selected": false,
        "width": 208,
        "resizing": false,
        "style": {
          "width": 208
        },
        "dragging": false
      },
      {
        "id": "asymmetric-ecc-keygen-mvhhfkg9-j5sb",
        "type": "cryptoNode",
        "position": {
          "x": -160,
          "y": 208
        },
        "data": {
          "id": "asymmetric-ecc-keygen-mvhhfkg9-j5sb",
          "type": "cryptoNode",
          "nodeType": "asymmetric-ecc-keygen",
          "label": "Client Keypair",
          "category": "asymmetric",
          "description": "Generates Elliptic Curve keypair (NIST P-256/384/521, secp256k1, Brainpool)",
          "inputs": [],
          "outputs": [
            {
              "id": "privateKey",
              "name": "Private Key",
              "dataType": "bytes"
            },
            {
              "id": "publicKey",
              "name": "Public Key",
              "spec": "Uncompressed",
              "dataType": "bytes",
              "description": "Uncompressed EC point (0x04 prefix + X + Y coordinates)."
            }
          ],
          "properties": {
            "curve": "p256"
          },
          "customWidth": 208
        },
        "measured": {
          "width": 208,
          "height": 174
        },
        "selected": false,
        "width": 208,
        "resizing": false,
        "style": {
          "width": 208
        },
        "dragging": false
      },
      {
        "id": "node-1792549090801-9jxf",
        "type": "cryptoNode",
        "position": {
          "x": -160,
          "y": -16
        },
        "data": {
          "id": "node-1792549090801-9jxf",
          "type": "cryptoNode",
          "nodeType": "input-random",
          "label": "Nonce",
          "category": "input",
          "description": "Generates a cryptographically secure random value of a user-selected type (bytes/string/int/bool)",
          "inputs": [],
          "outputs": [
            {
              "id": "bytes",
              "name": "Value",
              "dataType": "bytes",
              "description": "Cryptographically random value"
            }
          ],
          "size": "small",
          "properties": {
            "type": "bytes",
            "length": 32,
            "intMin": 0,
            "intMax": 100
          }
        },
        "measured": {
          "width": 208,
          "height": 144
        },
        "selected": false,
        "dragging": false
      },
      {
        "id": "node-1792549869185-16wd",
        "type": "cryptoNode",
        "position": {
          "x": 1184,
          "y": 192
        },
        "data": {
          "id": "node-1792549869185-16wd",
          "type": "cryptoNode",
          "nodeType": "workflow-output",
          "label": "Workflow Output",
          "category": "input",
          "description": "Workflow egress interface. Gathers final pipeline results for API response or caller return.",
          "inputs": [
            {
              "id": "in_mvhhwt5n_hzn",
              "name": "Verified",
              "dataType": "bool",
              "required": true
            }
          ],
          "outputs": [],
          "size": "small",
          "dynamicInputs": {
            "min": 0,
            "defaultNamePrefix": "Return",
            "defaultDataType": "bytes"
          },
          "properties": {}
        },
        "measured": {
          "width": 208,
          "height": 142
        },
        "selected": false,
        "dragging": false
      },
      {
        "id": "node-1792549974143-vfn8",
        "type": "cryptoNode",
        "position": {
          "x": 224,
          "y": 192
        },
        "data": {
          "id": "node-1792549974143-vfn8",
          "type": "cryptoNode",
          "nodeType": "sha256:c53068f42cb0268cb4167ba9e05cebc07fa0e889082ef7d509751919d69419a4",
          "label": "DID Auth - Client",
          "category": "User Protocol",
          "description": "",
          "inputs": [
            {
              "id": "nonce",
              "name": "Nonce",
              "dataType": "bytes",
              "spec": "32 B",
              "required": true
            },
            {
              "id": "prv",
              "name": "Client Private Key",
              "dataType": "bytes",
              "spec": "32 B",
              "required": true
            },
            {
              "id": "pub",
              "name": "Client Public Key",
              "dataType": "bytes",
              "spec": "65 B",
              "required": true
            },
            {
              "id": "spub",
              "name": "Server Public Key",
              "dataType": "bytes",
              "spec": "65 B",
              "required": true
            }
          ],
          "outputs": [
            {
              "id": "pub",
              "name": "Client Public Key",
              "dataType": "bytes"
            },
            {
              "id": "mac",
              "name": "MAC",
              "dataType": "bytes"
            }
          ],
          "properties": {},
          "customWidth": 352
        },
        "measured": {
          "width": 352,
          "height": 209
        },
        "selected": false,
        "dragging": false,
        "width": 352,
        "resizing": false,
        "style": {
          "width": 352
        }
      }
    ],
    "edges": [
      {
        "interactionWidth": 14,
        "selectable": false,
        "source": "node-1792549010824-p91k",
        "sourceHandle": "ok",
        "target": "node-1792549869185-16wd",
        "targetHandle": "in_mvhhwt5n_hzn",
        "animated": true,
        "style": {
          "stroke": "#3b82f6",
          "strokeWidth": 2
        },
        "id": "xy-edge__node-1792549010824-p91kok-node-1792549869185-16wdin_mvhhwt5n_hzn",
        "selected": false
      },
      {
        "interactionWidth": 14,
        "selectable": false,
        "source": "node-1792549090801-9jxf",
        "sourceHandle": "bytes",
        "target": "node-1792549010824-p91k",
        "targetHandle": "nonce",
        "animated": true,
        "style": {
          "stroke": "#3b82f6",
          "strokeWidth": 2
        },
        "selected": false,
        "type": "custom",
        "zIndex": 2000,
        "id": "xy-edge__node-1792549090801-9jxfbytes-node-1792549010824-p91knonce"
      },
      {
        "interactionWidth": 14,
        "selectable": false,
        "source": "node-1792549047067-5x2i",
        "sourceHandle": "privateKey",
        "target": "node-1792549010824-p91k",
        "targetHandle": "prv",
        "animated": true,
        "style": {
          "stroke": "#3b82f6",
          "strokeWidth": 2
        },
        "selected": false,
        "type": "custom",
        "zIndex": 2000,
        "id": "xy-edge__node-1792549047067-5x2iprivateKey-node-1792549010824-p91kprv"
      },
      {
        "interactionWidth": 14,
        "selectable": false,
        "source": "node-1792549974143-vfn8",
        "sourceHandle": "pub",
        "target": "node-1792549010824-p91k",
        "targetHandle": "cpub",
        "animated": true,
        "style": {
          "stroke": "#3b82f6",
          "strokeWidth": 2
        },
        "id": "xy-edge__node-1792549974143-vfn8pub-node-1792549010824-p91kcpub"
      },
      {
        "interactionWidth": 14,
        "selectable": false,
        "source": "node-1792549974143-vfn8",
        "sourceHandle": "mac",
        "target": "node-1792549010824-p91k",
        "targetHandle": "rmac",
        "animated": true,
        "style": {
          "stroke": "#3b82f6",
          "strokeWidth": 2
        },
        "id": "xy-edge__node-1792549974143-vfn8mac-node-1792549010824-p91krmac"
      },
      {
        "interactionWidth": 14,
        "selectable": false,
        "source": "asymmetric-ecc-keygen-mvhhfkg9-j5sb",
        "sourceHandle": "privateKey",
        "target": "node-1792549974143-vfn8",
        "targetHandle": "prv",
        "animated": true,
        "style": {
          "stroke": "#3b82f6",
          "strokeWidth": 2
        },
        "id": "xy-edge__asymmetric-ecc-keygen-mvhhfkg9-j5sbprivateKey-node-1792549974143-vfn8prv"
      },
      {
        "interactionWidth": 14,
        "selectable": false,
        "source": "asymmetric-ecc-keygen-mvhhfkg9-j5sb",
        "sourceHandle": "publicKey",
        "target": "node-1792549974143-vfn8",
        "targetHandle": "pub",
        "animated": true,
        "style": {
          "stroke": "#3b82f6",
          "strokeWidth": 2
        },
        "id": "xy-edge__asymmetric-ecc-keygen-mvhhfkg9-j5sbpublicKey-node-1792549974143-vfn8pub"
      },
      {
        "interactionWidth": 14,
        "selectable": false,
        "source": "node-1792549047067-5x2i",
        "sourceHandle": "publicKey",
        "target": "node-1792549974143-vfn8",
        "targetHandle": "spub",
        "animated": true,
        "style": {
          "stroke": "#3b82f6",
          "strokeWidth": 2
        },
        "id": "xy-edge__node-1792549047067-5x2ipublicKey-node-1792549974143-vfn8spub"
      },
      {
        "interactionWidth": 14,
        "selectable": false,
        "source": "node-1792549090801-9jxf",
        "sourceHandle": "bytes",
        "target": "node-1792549974143-vfn8",
        "targetHandle": "nonce",
        "animated": true,
        "style": {
          "stroke": "#3b82f6",
          "strokeWidth": 2
        },
        "id": "xy-edge__node-1792549090801-9jxfbytes-node-1792549974143-vfn8nonce"
      }
    ]
  },
  "definitions": {
    "sha256:24b2a81aaebc9bf83e6566f6d57fa402f664dcf918fdcfc5c20ee2156ea937ec": {
      "manifest": {
        "label": "DID Auth - Server",
        "version": "",
        "description": "",
        "category": "User Protocol",
        "inputs": [
          {
            "id": "prv",
            "name": "Server Private Key",
            "dataType": "bytes",
            "spec": "32 B",
            "required": true
          },
          {
            "id": "cpub",
            "name": "Client Public Key",
            "dataType": "bytes",
            "spec": "65 B",
            "required": true
          },
          {
            "id": "nonce",
            "name": "Nonce",
            "dataType": "bytes",
            "spec": "32 B",
            "required": true
          },
          {
            "id": "rmac",
            "name": "Received MAC",
            "dataType": "bytes",
            "spec": "8 B",
            "required": true
          }
        ],
        "outputs": [
          {
            "id": "ok",
            "name": "Verified",
            "dataType": "bool"
          }
        ]
      },
      "workflow": {
        "name": "did-auth-server",
        "description": "DID Auth, server side: recomputes the MAC from its own private key and compares it with the client MAC. Learning example, public demo keys.",
        "viewport": {
          "x": -409,
          "y": 143.5,
          "zoom": 1
        },
        "nodes": [
          {
            "id": "in",
            "type": "cryptoNode",
            "position": {
              "x": 64,
              "y": 64
            },
            "width": 208,
            "data": {
              "id": "in",
              "type": "cryptoNode",
              "nodeType": "workflow-input",
              "label": "Workflow Input",
              "category": "input",
              "description": "Workflow ingress interface. Injects external API inputs or custom-node caller parameters.",
              "inputs": [],
              "outputs": [
                {
                  "id": "prv",
                  "name": "Server Private Key",
                  "dataType": "bytes",
                  "constraint": {
                    "lengths": [
                      32
                    ]
                  },
                  "defaultValue": "a4b87f7821ada85b4e7f63618924b4c3f3bbb78cddcab485a7ee6f15fdfc7261"
                },
                {
                  "id": "cpub",
                  "name": "Client Public Key",
                  "dataType": "bytes",
                  "constraint": {
                    "lengths": [
                      65
                    ]
                  },
                  "defaultValue": "0415dc193b8e2a688d603303e85ec8fcc15dcba44ef2156a128c386b66b4f5e1d2188e7ca9d0385c02e72c6899f2771e86bb017a2d2903d89a2892c2199aec8f4d"
                },
                {
                  "id": "nonce",
                  "name": "Nonce",
                  "dataType": "bytes",
                  "constraint": {
                    "lengths": [
                      32
                    ]
                  },
                  "defaultValue": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
                },
                {
                  "id": "rmac",
                  "name": "Received MAC",
                  "dataType": "bytes",
                  "constraint": {
                    "lengths": [
                      8
                    ]
                  },
                  "defaultValue": "39b415c1dfeb8f52"
                }
              ],
              "size": "small",
              "dynamicOutputs": {
                "min": 0,
                "defaultNamePrefix": "Arg",
                "defaultDataType": "bytes"
              },
              "properties": {},
              "note": "# Server inputs\nThe nonce is the one the server issued. `Received MAC` defaults to the client workflow output for the default demo values. Change one bit to see `false`.\n\n> Learning example that explains the protocol. Do not use it in a real service. The keys are public demo keys.",
              "executionState": "success",
              "executionDurationMs": 12,
              "outputValues": {
                "prv": {
                  "0": 164,
                  "1": 184,
                  "2": 127,
                  "3": 120,
                  "4": 33,
                  "5": 173,
                  "6": 168,
                  "7": 91,
                  "8": 78,
                  "9": 127,
                  "10": 99,
                  "11": 97,
                  "12": 137,
                  "13": 36,
                  "14": 180,
                  "15": 195,
                  "16": 243,
                  "17": 187,
                  "18": 183,
                  "19": 140,
                  "20": 221,
                  "21": 202,
                  "22": 180,
                  "23": 133,
                  "24": 167,
                  "25": 238,
                  "26": 111,
                  "27": 21,
                  "28": 253,
                  "29": 252,
                  "30": 114,
                  "31": 97
                },
                "cpub": {
                  "0": 4,
                  "1": 21,
                  "2": 220,
                  "3": 25,
                  "4": 59,
                  "5": 142,
                  "6": 42,
                  "7": 104,
                  "8": 141,
                  "9": 96,
                  "10": 51,
                  "11": 3,
                  "12": 232,
                  "13": 94,
                  "14": 200,
                  "15": 252,
                  "16": 193,
                  "17": 93,
                  "18": 203,
                  "19": 164,
                  "20": 78,
                  "21": 242,
                  "22": 21,
                  "23": 106,
                  "24": 18,
                  "25": 140,
                  "26": 56,
                  "27": 107,
                  "28": 102,
                  "29": 180,
                  "30": 245,
                  "31": 225,
                  "32": 210,
                  "33": 24,
                  "34": 142,
                  "35": 124,
                  "36": 169,
                  "37": 208,
                  "38": 56,
                  "39": 92,
                  "40": 2,
                  "41": 231,
                  "42": 44,
                  "43": 104,
                  "44": 153,
                  "45": 242,
                  "46": 119,
                  "47": 30,
                  "48": 134,
                  "49": 187,
                  "50": 1,
                  "51": 122,
                  "52": 45,
                  "53": 41,
                  "54": 3,
                  "55": 216,
                  "56": 154,
                  "57": 40,
                  "58": 146,
                  "59": 194,
                  "60": 25,
                  "61": 154,
                  "62": 236,
                  "63": 143,
                  "64": 77
                },
                "nonce": {
                  "0": 0,
                  "1": 1,
                  "2": 2,
                  "3": 3,
                  "4": 4,
                  "5": 5,
                  "6": 6,
                  "7": 7,
                  "8": 8,
                  "9": 9,
                  "10": 10,
                  "11": 11,
                  "12": 12,
                  "13": 13,
                  "14": 14,
                  "15": 15,
                  "16": 16,
                  "17": 17,
                  "18": 18,
                  "19": 19,
                  "20": 20,
                  "21": 21,
                  "22": 22,
                  "23": 23,
                  "24": 24,
                  "25": 25,
                  "26": 26,
                  "27": 27,
                  "28": 28,
                  "29": 29,
                  "30": 30,
                  "31": 31
                },
                "rmac": {
                  "0": 57,
                  "1": 180,
                  "2": 21,
                  "3": 193,
                  "4": 223,
                  "5": 235,
                  "6": 143,
                  "7": 82
                }
              }
            },
            "measured": {
              "width": 208,
              "height": 232
            },
            "selected": false
          },
          {
            "id": "ecdh",
            "type": "cryptoNode",
            "position": {
              "x": 448,
              "y": -32
            },
            "width": 304,
            "data": {
              "id": "ecdh",
              "type": "cryptoNode",
              "nodeType": "asymmetric-ecc-ecdh",
              "label": "ECDH",
              "category": "asymmetric",
              "description": "Computes Elliptic Curve Diffie-Hellman shared secret on Weierstrass curves (NIST SP 800-56A / RFC 5903)",
              "inputs": [
                {
                  "id": "privateKey",
                  "name": "My Private Key",
                  "dataType": "bytes",
                  "required": true
                },
                {
                  "id": "peerPublicKey",
                  "name": "Peer Public Key",
                  "dataType": "bytes",
                  "required": true
                }
              ],
              "outputs": [
                {
                  "id": "sharedSecret",
                  "name": "Shared Secret",
                  "dataType": "bytes"
                },
                {
                  "id": "rawSecretX",
                  "name": "Raw Secret X",
                  "spec": "32B",
                  "dataType": "bytes",
                  "description": "Raw X-coordinate of the ECDH shared point, before any KDF (NIST SP 800-56A raw format)."
                }
              ],
              "properties": {
                "curve": "p256",
                "format": "raw_x"
              },
              "note": "# 1. Shared secret\n`secret = ECDH(prvServer, pubClient)`\n- P-256, output format `raw_x`: the 32-byte X coordinate (the DIDAuth text does not name the format, this is an assumption)\n- Public keys are uncompressed 65-byte points (assumption)",
              "executionState": "success",
              "executionDurationMs": 7,
              "outputValues": {
                "sharedSecret": {
                  "0": 233,
                  "1": 63,
                  "2": 19,
                  "3": 126,
                  "4": 35,
                  "5": 147,
                  "6": 85,
                  "7": 165,
                  "8": 113,
                  "9": 75,
                  "10": 131,
                  "11": 131,
                  "12": 212,
                  "13": 88,
                  "14": 131,
                  "15": 115,
                  "16": 33,
                  "17": 74,
                  "18": 172,
                  "19": 23,
                  "20": 140,
                  "21": 239,
                  "22": 23,
                  "23": 1,
                  "24": 180,
                  "25": 212,
                  "26": 103,
                  "27": 173,
                  "28": 199,
                  "29": 105,
                  "30": 125,
                  "31": 28
                },
                "rawSecretX": {
                  "0": 233,
                  "1": 63,
                  "2": 19,
                  "3": 126,
                  "4": 35,
                  "5": 147,
                  "6": 85,
                  "7": 165,
                  "8": 113,
                  "9": 75,
                  "10": 131,
                  "11": 131,
                  "12": 212,
                  "13": 88,
                  "14": 131,
                  "15": 115,
                  "16": 33,
                  "17": 74,
                  "18": 172,
                  "19": 23,
                  "20": 140,
                  "21": 239,
                  "22": 23,
                  "23": 1,
                  "24": 180,
                  "25": 212,
                  "26": 103,
                  "27": 173,
                  "28": 199,
                  "29": 105,
                  "30": 125,
                  "31": 28
                }
              }
            },
            "measured": {
              "width": 304,
              "height": 177
            },
            "selected": false,
            "dragging": false
          },
          {
            "id": "sha",
            "type": "cryptoNode",
            "position": {
              "x": 864,
              "y": -32
            },
            "width": 304,
            "data": {
              "id": "sha",
              "type": "cryptoNode",
              "nodeType": "hash-digest",
              "label": "SHA-256",
              "category": "hash",
              "description": "Computes cryptographic hash (SHA-2, SHA-3, BLAKE3)",
              "inputs": [
                {
                  "id": "data",
                  "name": "Data",
                  "dataType": "bytes",
                  "required": true
                }
              ],
              "outputs": [
                {
                  "id": "digest",
                  "name": "Digest",
                  "dataType": "bytes"
                }
              ],
              "properties": {
                "algorithm": "SHA-256"
              },
              "note": "# 2. Hash\n`hash = SHA2-256(secret)`",
              "executionState": "success",
              "executionDurationMs": 4,
              "outputValues": {
                "digest": {
                  "0": 219,
                  "1": 116,
                  "2": 224,
                  "3": 178,
                  "4": 155,
                  "5": 35,
                  "6": 94,
                  "7": 243,
                  "8": 128,
                  "9": 235,
                  "10": 90,
                  "11": 24,
                  "12": 119,
                  "13": 84,
                  "14": 183,
                  "15": 107,
                  "16": 88,
                  "17": 77,
                  "18": 52,
                  "19": 62,
                  "20": 241,
                  "21": 180,
                  "22": 40,
                  "23": 223,
                  "24": 43,
                  "25": 111,
                  "26": 114,
                  "27": 15,
                  "28": 53,
                  "29": 89,
                  "30": 189,
                  "31": 82
                }
              }
            },
            "measured": {
              "width": 304,
              "height": 147
            },
            "selected": false,
            "dragging": false
          },
          {
            "id": "ks",
            "type": "cryptoNode",
            "position": {
              "x": 1280,
              "y": -32
            },
            "width": 304,
            "data": {
              "id": "ks",
              "type": "cryptoNode",
              "nodeType": "utility-slicer",
              "label": "Key",
              "category": "utility",
              "description": "Extracts bytes like the script slice b[offset, length]: empty length = to the end, negative = end position counted from the back (excluded)",
              "inputs": [
                {
                  "id": "data",
                  "name": "Data",
                  "dataType": "bytes",
                  "required": true
                }
              ],
              "outputs": [
                {
                  "id": "sliced",
                  "name": "Sliced Bytes",
                  "dataType": "bytes"
                }
              ],
              "properties": {
                "offset": 0,
                "length": "16"
              },
              "note": "# 2. Key\n`key = hash[0,16]`: the left 16 bytes (AES-128 key)",
              "executionState": "success",
              "executionDurationMs": 4,
              "outputValues": {
                "sliced": {
                  "0": 219,
                  "1": 116,
                  "2": 224,
                  "3": 178,
                  "4": 155,
                  "5": 35,
                  "6": 94,
                  "7": 243,
                  "8": 128,
                  "9": 235,
                  "10": 90,
                  "11": 24,
                  "12": 119,
                  "13": 84,
                  "14": 183,
                  "15": 107
                }
              }
            },
            "measured": {
              "width": 304,
              "height": 147
            },
            "selected": false,
            "dragging": false
          },
          {
            "id": "ivs",
            "type": "cryptoNode",
            "position": {
              "x": 1296,
              "y": 240
            },
            "width": 304,
            "data": {
              "id": "ivs",
              "type": "cryptoNode",
              "nodeType": "utility-slicer",
              "label": "IV",
              "category": "utility",
              "description": "Extracts bytes like the script slice b[offset, length]: empty length = to the end, negative = end position counted from the back (excluded)",
              "inputs": [
                {
                  "id": "data",
                  "name": "Data",
                  "dataType": "bytes",
                  "required": true
                }
              ],
              "outputs": [
                {
                  "id": "sliced",
                  "name": "Sliced Bytes",
                  "dataType": "bytes"
                }
              ],
              "properties": {
                "offset": 16,
                "length": "16"
              },
              "note": "# 2. IV\n`iv = hash[16,16]`: the right 16 bytes",
              "executionState": "success",
              "executionDurationMs": 4,
              "outputValues": {
                "sliced": {
                  "0": 88,
                  "1": 77,
                  "2": 52,
                  "3": 62,
                  "4": 241,
                  "5": 180,
                  "6": 40,
                  "7": 223,
                  "8": 43,
                  "9": 111,
                  "10": 114,
                  "11": 15,
                  "12": 53,
                  "13": 89,
                  "14": 189,
                  "15": 82
                }
              }
            },
            "measured": {
              "width": 304,
              "height": 147
            },
            "selected": false,
            "dragging": false
          },
          {
            "id": "cbc",
            "type": "cryptoNode",
            "position": {
              "x": 1664,
              "y": 64
            },
            "width": 304,
            "data": {
              "id": "cbc",
              "type": "cryptoNode",
              "nodeType": "symmetric-aes-encrypt",
              "label": "AES-128-CBC",
              "category": "symmetric",
              "description": "Encrypts plaintext using NIST AES (128/192/256-bit)",
              "inputs": [
                {
                  "id": "key",
                  "name": "Key",
                  "spec": "16/24/32B",
                  "dataType": "bytes",
                  "required": true,
                  "description": "AES symmetric key. Length selects AES-128/192/256."
                },
                {
                  "id": "plaintext",
                  "name": "Plaintext",
                  "dataType": "bytes",
                  "required": true
                },
                {
                  "id": "iv",
                  "name": "IV",
                  "spec": "16B",
                  "dataType": "bytes",
                  "required": false,
                  "description": "Initialization vector/counter/tweak (16B). Defaults to 16 zero bytes if omitted."
                },
                {
                  "id": "nonce",
                  "name": "Nonce",
                  "spec": "12B",
                  "dataType": "bytes",
                  "required": false,
                  "description": "AEAD nonce (12B), used only in GCM/CCM mode. Defaults to 12 zero bytes if omitted."
                },
                {
                  "id": "aad",
                  "name": "AAD",
                  "spec": "GCM/CCM only",
                  "dataType": "bytes",
                  "required": false,
                  "description": "Additional Authenticated Data, used only in GCM/CCM mode."
                }
              ],
              "outputs": [
                {
                  "id": "ciphertext",
                  "name": "Ciphertext",
                  "dataType": "bytes"
                },
                {
                  "id": "tag",
                  "name": "Auth Tag",
                  "spec": "GCM/CCM",
                  "dataType": "bytes",
                  "description": "Authentication tag produced in GCM/CCM mode."
                }
              ],
              "properties": {
                "mode": "CBC",
                "padding": "None",
                "errorUnify": false,
                "errorUnifyCode": "",
                "errorUnifyMessage": ""
              },
              "note": "# 3. full_mac\n`full_mac = AES_ENC_CBC(key, nonce, iv)`\n- The 32-byte nonce is exactly two blocks, so no padding.",
              "executionState": "success",
              "executionDurationMs": 5,
              "outputValues": {
                "ciphertext": {
                  "0": 27,
                  "1": 212,
                  "2": 156,
                  "3": 196,
                  "4": 36,
                  "5": 237,
                  "6": 18,
                  "7": 25,
                  "8": 104,
                  "9": 200,
                  "10": 92,
                  "11": 208,
                  "12": 247,
                  "13": 146,
                  "14": 207,
                  "15": 130,
                  "16": 57,
                  "17": 180,
                  "18": 21,
                  "19": 193,
                  "20": 223,
                  "21": 235,
                  "22": 143,
                  "23": 82,
                  "24": 51,
                  "25": 100,
                  "26": 39,
                  "27": 157,
                  "28": 4,
                  "29": 253,
                  "30": 46,
                  "31": 243
                },
                "tag": {}
              }
            },
            "measured": {
              "width": 304,
              "height": 207
            },
            "selected": false
          },
          {
            "id": "cut",
            "type": "cryptoNode",
            "position": {
              "x": 2064,
              "y": 64
            },
            "width": 304,
            "data": {
              "id": "cut",
              "type": "cryptoNode",
              "nodeType": "utility-slicer",
              "label": "MAC",
              "category": "utility",
              "description": "Extracts bytes like the script slice b[offset, length]: empty length = to the end, negative = end position counted from the back (excluded)",
              "inputs": [
                {
                  "id": "data",
                  "name": "Data",
                  "dataType": "bytes",
                  "required": true
                }
              ],
              "outputs": [
                {
                  "id": "sliced",
                  "name": "Sliced Bytes",
                  "dataType": "bytes"
                }
              ],
              "properties": {
                "offset": -16,
                "length": "8"
              },
              "note": "# 3. mac\n`mac = full_mac[-16,8]`: the first 8 bytes of the last block (offset 16 bytes back from the end, length 8).",
              "executionState": "success",
              "executionDurationMs": 6,
              "outputValues": {
                "sliced": {
                  "0": 57,
                  "1": 180,
                  "2": 21,
                  "3": 193,
                  "4": 223,
                  "5": 235,
                  "6": 143,
                  "7": 82
                }
              }
            },
            "measured": {
              "width": 304,
              "height": 147
            },
            "selected": false
          },
          {
            "id": "cmp",
            "type": "cryptoNode",
            "position": {
              "x": 2032,
              "y": 336
            },
            "width": 304,
            "data": {
              "id": "cmp",
              "type": "cryptoNode",
              "nodeType": "utility-compare",
              "label": "MAC matches",
              "category": "utility",
              "description": "Compares two values of the same type (bytes, string, int, bool) with ==, !=, >, >=, <, <=",
              "inputs": [
                {
                  "id": "a",
                  "name": "Value A",
                  "dataType": "any",
                  "required": true,
                  "description": "First operand to compare"
                },
                {
                  "id": "b",
                  "name": "Value B",
                  "dataType": "any",
                  "required": true,
                  "description": "Second operand to compare"
                }
              ],
              "outputs": [
                {
                  "id": "result",
                  "name": "Result",
                  "dataType": "bool",
                  "description": "True if the comparison holds"
                }
              ],
              "properties": {
                "operator": "==",
                "errorOnValue": ""
              },
              "note": "# Verify\nCompares the recomputed mac with the client mac. Not constant time: acceptable for a learning example, use `ct_equals` in a script for a real comparison.",
              "executionState": "success",
              "executionDurationMs": 4,
              "outputValues": {
                "result": true
              }
            },
            "measured": {
              "width": 304,
              "height": 177
            },
            "selected": false,
            "dragging": false
          },
          {
            "id": "out",
            "type": "cryptoNode",
            "position": {
              "x": 2464,
              "y": 368
            },
            "width": 208,
            "data": {
              "id": "out",
              "type": "cryptoNode",
              "nodeType": "workflow-output",
              "label": "Workflow Output",
              "category": "input",
              "description": "Workflow egress interface. Gathers final pipeline results for API response or caller return.",
              "inputs": [
                {
                  "id": "ok",
                  "name": "Verified",
                  "dataType": "bool",
                  "required": true
                }
              ],
              "outputs": [],
              "size": "small",
              "dynamicInputs": {
                "min": 0,
                "defaultNamePrefix": "Return",
                "defaultDataType": "bytes"
              },
              "properties": {},
              "executionState": "success",
              "executionDurationMs": 5,
              "outputValues": {
                "result": {
                  "ok": true
                },
                "ok": true
              }
            },
            "measured": {
              "width": 208,
              "height": 142
            },
            "selected": false,
            "dragging": false
          }
        ],
        "edges": [
          {
            "id": "edge-in-prv-ecdh-privateKey",
            "source": "in",
            "sourceHandle": "prv",
            "target": "ecdh",
            "targetHandle": "privateKey",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            }
          },
          {
            "id": "edge-in-cpub-ecdh-peerPublicKey",
            "source": "in",
            "sourceHandle": "cpub",
            "target": "ecdh",
            "targetHandle": "peerPublicKey",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            }
          },
          {
            "id": "edge-ecdh-sharedSecret-sha-data",
            "source": "ecdh",
            "sourceHandle": "sharedSecret",
            "target": "sha",
            "targetHandle": "data",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            }
          },
          {
            "id": "edge-sha-digest-ks-data",
            "source": "sha",
            "sourceHandle": "digest",
            "target": "ks",
            "targetHandle": "data",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            }
          },
          {
            "id": "edge-sha-digest-ivs-data",
            "source": "sha",
            "sourceHandle": "digest",
            "target": "ivs",
            "targetHandle": "data",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            }
          },
          {
            "id": "edge-ks-sliced-cbc-key",
            "source": "ks",
            "sourceHandle": "sliced",
            "target": "cbc",
            "targetHandle": "key",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            }
          },
          {
            "id": "edge-ivs-sliced-cbc-iv",
            "source": "ivs",
            "sourceHandle": "sliced",
            "target": "cbc",
            "targetHandle": "iv",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            }
          },
          {
            "id": "edge-in-nonce-cbc-plaintext",
            "source": "in",
            "sourceHandle": "nonce",
            "target": "cbc",
            "targetHandle": "plaintext",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            }
          },
          {
            "id": "edge-cbc-ciphertext-cut-data",
            "source": "cbc",
            "sourceHandle": "ciphertext",
            "target": "cut",
            "targetHandle": "data",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            }
          },
          {
            "id": "edge-cut-sliced-cmp-a",
            "source": "cut",
            "sourceHandle": "sliced",
            "target": "cmp",
            "targetHandle": "a",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            }
          },
          {
            "id": "edge-in-rmac-cmp-b",
            "source": "in",
            "sourceHandle": "rmac",
            "target": "cmp",
            "targetHandle": "b",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            }
          },
          {
            "id": "edge-cmp-result-out-ok",
            "source": "cmp",
            "sourceHandle": "result",
            "target": "out",
            "targetHandle": "ok",
            "type": "custom",
            "data": {
              "dataType": "bool"
            }
          }
        ]
      }
    },
    "sha256:c53068f42cb0268cb4167ba9e05cebc07fa0e889082ef7d509751919d69419a4": {
      "manifest": {
        "label": "DID Auth - Client",
        "version": "",
        "description": "",
        "category": "User Protocol",
        "inputs": [
          {
            "id": "nonce",
            "name": "Nonce",
            "dataType": "bytes",
            "spec": "32 B",
            "required": true
          },
          {
            "id": "prv",
            "name": "Client Private Key",
            "dataType": "bytes",
            "spec": "32 B",
            "required": true
          },
          {
            "id": "pub",
            "name": "Client Public Key",
            "dataType": "bytes",
            "spec": "65 B",
            "required": true
          },
          {
            "id": "spub",
            "name": "Server Public Key",
            "dataType": "bytes",
            "spec": "65 B",
            "required": true
          }
        ],
        "outputs": [
          {
            "id": "pub",
            "name": "Client Public Key",
            "dataType": "bytes"
          },
          {
            "id": "mac",
            "name": "MAC",
            "dataType": "bytes"
          }
        ]
      },
      "workflow": {
        "name": "did-auth-client",
        "description": "DID Auth, client side: derives the MAC that answers the server challenge. Learning example, public demo keys.",
        "viewport": {
          "x": -104.625,
          "y": 86.5,
          "zoom": 1
        },
        "nodes": [
          {
            "id": "in",
            "type": "cryptoNode",
            "position": {
              "x": 64,
              "y": 64
            },
            "width": 208,
            "data": {
              "id": "in",
              "type": "cryptoNode",
              "nodeType": "workflow-input",
              "label": "Workflow Input",
              "category": "input",
              "description": "Workflow ingress interface. Injects external API inputs or custom-node caller parameters.",
              "inputs": [],
              "outputs": [
                {
                  "id": "nonce",
                  "name": "Nonce",
                  "dataType": "bytes",
                  "constraint": {
                    "lengths": [
                      32
                    ]
                  },
                  "defaultValue": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
                },
                {
                  "id": "prv",
                  "name": "Client Private Key",
                  "dataType": "bytes",
                  "constraint": {
                    "lengths": [
                      32
                    ]
                  },
                  "defaultValue": "2ad39d172118c0802359e6806b8939881b6a3fbcc9e89e307499a862acd4e3c9"
                },
                {
                  "id": "pub",
                  "name": "Client Public Key",
                  "dataType": "bytes",
                  "constraint": {
                    "lengths": [
                      65
                    ]
                  },
                  "defaultValue": "0415dc193b8e2a688d603303e85ec8fcc15dcba44ef2156a128c386b66b4f5e1d2188e7ca9d0385c02e72c6899f2771e86bb017a2d2903d89a2892c2199aec8f4d"
                },
                {
                  "id": "spub",
                  "name": "Server Public Key",
                  "dataType": "bytes",
                  "constraint": {
                    "lengths": [
                      65
                    ]
                  },
                  "defaultValue": "0447edf45c2c402ae4cfe8460fb208fbc0d6af18efa4b3d78d44c73fcb0c250ec08222f152af03468af65a74fbf89ecc763f19b0dadec5fd8df5cf76d7da097ae5"
                }
              ],
              "size": "small",
              "dynamicOutputs": {
                "min": 0,
                "defaultNamePrefix": "Arg",
                "defaultDataType": "bytes"
              },
              "properties": {},
              "note": "# Client inputs\nThe nonce is the server challenge (32 random bytes). The defaults are fixed demo values so the workflow runs as is.\n\n> Learning example that explains the protocol. Do not use it in a real service. The keys are public demo keys.",
              "executionState": "success",
              "executionDurationMs": 9,
              "outputValues": {
                "prv": {
                  "0": 42,
                  "1": 211,
                  "2": 157,
                  "3": 23,
                  "4": 33,
                  "5": 24,
                  "6": 192,
                  "7": 128,
                  "8": 35,
                  "9": 89,
                  "10": 230,
                  "11": 128,
                  "12": 107,
                  "13": 137,
                  "14": 57,
                  "15": 136,
                  "16": 27,
                  "17": 106,
                  "18": 63,
                  "19": 188,
                  "20": 201,
                  "21": 232,
                  "22": 158,
                  "23": 48,
                  "24": 116,
                  "25": 153,
                  "26": 168,
                  "27": 98,
                  "28": 172,
                  "29": 212,
                  "30": 227,
                  "31": 201
                },
                "pub": {
                  "0": 4,
                  "1": 21,
                  "2": 220,
                  "3": 25,
                  "4": 59,
                  "5": 142,
                  "6": 42,
                  "7": 104,
                  "8": 141,
                  "9": 96,
                  "10": 51,
                  "11": 3,
                  "12": 232,
                  "13": 94,
                  "14": 200,
                  "15": 252,
                  "16": 193,
                  "17": 93,
                  "18": 203,
                  "19": 164,
                  "20": 78,
                  "21": 242,
                  "22": 21,
                  "23": 106,
                  "24": 18,
                  "25": 140,
                  "26": 56,
                  "27": 107,
                  "28": 102,
                  "29": 180,
                  "30": 245,
                  "31": 225,
                  "32": 210,
                  "33": 24,
                  "34": 142,
                  "35": 124,
                  "36": 169,
                  "37": 208,
                  "38": 56,
                  "39": 92,
                  "40": 2,
                  "41": 231,
                  "42": 44,
                  "43": 104,
                  "44": 153,
                  "45": 242,
                  "46": 119,
                  "47": 30,
                  "48": 134,
                  "49": 187,
                  "50": 1,
                  "51": 122,
                  "52": 45,
                  "53": 41,
                  "54": 3,
                  "55": 216,
                  "56": 154,
                  "57": 40,
                  "58": 146,
                  "59": 194,
                  "60": 25,
                  "61": 154,
                  "62": 236,
                  "63": 143,
                  "64": 77
                },
                "spub": {
                  "0": 4,
                  "1": 71,
                  "2": 237,
                  "3": 244,
                  "4": 92,
                  "5": 44,
                  "6": 64,
                  "7": 42,
                  "8": 228,
                  "9": 207,
                  "10": 232,
                  "11": 70,
                  "12": 15,
                  "13": 178,
                  "14": 8,
                  "15": 251,
                  "16": 192,
                  "17": 214,
                  "18": 175,
                  "19": 24,
                  "20": 239,
                  "21": 164,
                  "22": 179,
                  "23": 215,
                  "24": 141,
                  "25": 68,
                  "26": 199,
                  "27": 63,
                  "28": 203,
                  "29": 12,
                  "30": 37,
                  "31": 14,
                  "32": 192,
                  "33": 130,
                  "34": 34,
                  "35": 241,
                  "36": 82,
                  "37": 175,
                  "38": 3,
                  "39": 70,
                  "40": 138,
                  "41": 246,
                  "42": 90,
                  "43": 116,
                  "44": 251,
                  "45": 248,
                  "46": 158,
                  "47": 204,
                  "48": 118,
                  "49": 63,
                  "50": 25,
                  "51": 176,
                  "52": 218,
                  "53": 222,
                  "54": 197,
                  "55": 253,
                  "56": 141,
                  "57": 245,
                  "58": 207,
                  "59": 118,
                  "60": 215,
                  "61": 218,
                  "62": 9,
                  "63": 122,
                  "64": 229
                },
                "nonce": {
                  "0": 0,
                  "1": 1,
                  "2": 2,
                  "3": 3,
                  "4": 4,
                  "5": 5,
                  "6": 6,
                  "7": 7,
                  "8": 8,
                  "9": 9,
                  "10": 10,
                  "11": 11,
                  "12": 12,
                  "13": 13,
                  "14": 14,
                  "15": 15,
                  "16": 16,
                  "17": 17,
                  "18": 18,
                  "19": 19,
                  "20": 20,
                  "21": 21,
                  "22": 22,
                  "23": 23,
                  "24": 24,
                  "25": 25,
                  "26": 26,
                  "27": 27,
                  "28": 28,
                  "29": 29,
                  "30": 30,
                  "31": 31
                }
              }
            },
            "measured": {
              "width": 208,
              "height": 232
            },
            "selected": false
          },
          {
            "id": "ecdh",
            "type": "cryptoNode",
            "position": {
              "x": 400,
              "y": 320
            },
            "width": 304,
            "data": {
              "id": "ecdh",
              "type": "cryptoNode",
              "nodeType": "asymmetric-ecc-ecdh",
              "label": "ECDH",
              "category": "asymmetric",
              "description": "Computes Elliptic Curve Diffie-Hellman shared secret on Weierstrass curves (NIST SP 800-56A / RFC 5903)",
              "inputs": [
                {
                  "id": "privateKey",
                  "name": "My Private Key",
                  "dataType": "bytes",
                  "required": true
                },
                {
                  "id": "peerPublicKey",
                  "name": "Peer Public Key",
                  "dataType": "bytes",
                  "required": true
                }
              ],
              "outputs": [
                {
                  "id": "sharedSecret",
                  "name": "Shared Secret",
                  "dataType": "bytes"
                },
                {
                  "id": "rawSecretX",
                  "name": "Raw Secret X",
                  "spec": "32B",
                  "dataType": "bytes",
                  "description": "Raw X-coordinate of the ECDH shared point, before any KDF (NIST SP 800-56A raw format)."
                }
              ],
              "properties": {
                "curve": "p256",
                "format": "raw_x"
              },
              "note": "# 1. Shared secret\n`secret = ECDH(prvClient, pubServer)`\n- P-256, output format `raw_x`: the 32-byte X coordinate (the DIDAuth text does not name the format, this is an assumption)\n- Public keys are uncompressed 65-byte points (assumption)",
              "executionState": "success",
              "executionDurationMs": 9,
              "outputValues": {
                "sharedSecret": {
                  "0": 233,
                  "1": 63,
                  "2": 19,
                  "3": 126,
                  "4": 35,
                  "5": 147,
                  "6": 85,
                  "7": 165,
                  "8": 113,
                  "9": 75,
                  "10": 131,
                  "11": 131,
                  "12": 212,
                  "13": 88,
                  "14": 131,
                  "15": 115,
                  "16": 33,
                  "17": 74,
                  "18": 172,
                  "19": 23,
                  "20": 140,
                  "21": 239,
                  "22": 23,
                  "23": 1,
                  "24": 180,
                  "25": 212,
                  "26": 103,
                  "27": 173,
                  "28": 199,
                  "29": 105,
                  "30": 125,
                  "31": 28
                },
                "rawSecretX": {
                  "0": 233,
                  "1": 63,
                  "2": 19,
                  "3": 126,
                  "4": 35,
                  "5": 147,
                  "6": 85,
                  "7": 165,
                  "8": 113,
                  "9": 75,
                  "10": 131,
                  "11": 131,
                  "12": 212,
                  "13": 88,
                  "14": 131,
                  "15": 115,
                  "16": 33,
                  "17": 74,
                  "18": 172,
                  "19": 23,
                  "20": 140,
                  "21": 239,
                  "22": 23,
                  "23": 1,
                  "24": 180,
                  "25": 212,
                  "26": 103,
                  "27": 173,
                  "28": 199,
                  "29": 105,
                  "30": 125,
                  "31": 28
                }
              }
            },
            "measured": {
              "width": 304,
              "height": 177
            },
            "selected": false,
            "dragging": false
          },
          {
            "id": "sha",
            "type": "cryptoNode",
            "position": {
              "x": 816,
              "y": 336
            },
            "width": 304,
            "data": {
              "id": "sha",
              "type": "cryptoNode",
              "nodeType": "hash-digest",
              "label": "SHA-256",
              "category": "hash",
              "description": "Computes cryptographic hash (SHA-2, SHA-3, BLAKE3)",
              "inputs": [
                {
                  "id": "data",
                  "name": "Data",
                  "dataType": "bytes",
                  "required": true
                }
              ],
              "outputs": [
                {
                  "id": "digest",
                  "name": "Digest",
                  "dataType": "bytes"
                }
              ],
              "properties": {
                "algorithm": "SHA-256"
              },
              "note": "# 2. Hash\n`hash = SHA2-256(secret)`",
              "executionState": "success",
              "executionDurationMs": 5,
              "outputValues": {
                "digest": {
                  "0": 219,
                  "1": 116,
                  "2": 224,
                  "3": 178,
                  "4": 155,
                  "5": 35,
                  "6": 94,
                  "7": 243,
                  "8": 128,
                  "9": 235,
                  "10": 90,
                  "11": 24,
                  "12": 119,
                  "13": 84,
                  "14": 183,
                  "15": 107,
                  "16": 88,
                  "17": 77,
                  "18": 52,
                  "19": 62,
                  "20": 241,
                  "21": 180,
                  "22": 40,
                  "23": 223,
                  "24": 43,
                  "25": 111,
                  "26": 114,
                  "27": 15,
                  "28": 53,
                  "29": 89,
                  "30": 189,
                  "31": 82
                }
              }
            },
            "measured": {
              "width": 304,
              "height": 147
            },
            "selected": false,
            "dragging": false
          },
          {
            "id": "ks",
            "type": "cryptoNode",
            "position": {
              "x": 1248,
              "y": 272
            },
            "width": 304,
            "data": {
              "id": "ks",
              "type": "cryptoNode",
              "nodeType": "utility-slicer",
              "label": "Key",
              "category": "utility",
              "description": "Extracts bytes like the script slice b[offset, length]: empty length = to the end, negative = end position counted from the back (excluded)",
              "inputs": [
                {
                  "id": "data",
                  "name": "Data",
                  "dataType": "bytes",
                  "required": true
                }
              ],
              "outputs": [
                {
                  "id": "sliced",
                  "name": "Sliced Bytes",
                  "dataType": "bytes"
                }
              ],
              "properties": {
                "offset": 0,
                "length": "16"
              },
              "note": "# 2. Key\n`key = hash[0,16]`: the left 16 bytes (AES-128 key)",
              "executionState": "success",
              "executionDurationMs": 5,
              "outputValues": {
                "sliced": {
                  "0": 219,
                  "1": 116,
                  "2": 224,
                  "3": 178,
                  "4": 155,
                  "5": 35,
                  "6": 94,
                  "7": 243,
                  "8": 128,
                  "9": 235,
                  "10": 90,
                  "11": 24,
                  "12": 119,
                  "13": 84,
                  "14": 183,
                  "15": 107
                }
              }
            },
            "measured": {
              "width": 304,
              "height": 147
            },
            "selected": false,
            "dragging": false
          },
          {
            "id": "ivs",
            "type": "cryptoNode",
            "position": {
              "x": 1296,
              "y": 512
            },
            "width": 304,
            "data": {
              "id": "ivs",
              "type": "cryptoNode",
              "nodeType": "utility-slicer",
              "label": "IV",
              "category": "utility",
              "description": "Extracts bytes like the script slice b[offset, length]: empty length = to the end, negative = end position counted from the back (excluded)",
              "inputs": [
                {
                  "id": "data",
                  "name": "Data",
                  "dataType": "bytes",
                  "required": true
                }
              ],
              "outputs": [
                {
                  "id": "sliced",
                  "name": "Sliced Bytes",
                  "dataType": "bytes"
                }
              ],
              "properties": {
                "offset": 16,
                "length": "16"
              },
              "note": "# 2. IV\n`iv = hash[16,16]`: the right 16 bytes",
              "executionState": "success",
              "executionDurationMs": 5,
              "outputValues": {
                "sliced": {
                  "0": 88,
                  "1": 77,
                  "2": 52,
                  "3": 62,
                  "4": 241,
                  "5": 180,
                  "6": 40,
                  "7": 223,
                  "8": 43,
                  "9": 111,
                  "10": 114,
                  "11": 15,
                  "12": 53,
                  "13": 89,
                  "14": 189,
                  "15": 82
                }
              }
            },
            "measured": {
              "width": 304,
              "height": 147
            },
            "selected": false,
            "dragging": false
          },
          {
            "id": "cbc",
            "type": "cryptoNode",
            "position": {
              "x": 1664,
              "y": 64
            },
            "width": 304,
            "data": {
              "id": "cbc",
              "type": "cryptoNode",
              "nodeType": "symmetric-aes-encrypt",
              "label": "AES-128-CBC",
              "category": "symmetric",
              "description": "Encrypts plaintext using NIST AES (128/192/256-bit)",
              "inputs": [
                {
                  "id": "plaintext",
                  "name": "Plaintext",
                  "dataType": "bytes",
                  "required": true
                },
                {
                  "id": "key",
                  "name": "Key",
                  "spec": "16/24/32B",
                  "dataType": "bytes",
                  "required": true,
                  "description": "AES symmetric key. Length selects AES-128/192/256."
                },
                {
                  "id": "iv",
                  "name": "IV",
                  "spec": "16B",
                  "dataType": "bytes",
                  "required": false,
                  "description": "Initialization vector/counter/tweak (16B). Defaults to 16 zero bytes if omitted."
                },
                {
                  "id": "nonce",
                  "name": "Nonce",
                  "spec": "12B",
                  "dataType": "bytes",
                  "required": false,
                  "description": "AEAD nonce (12B), used only in GCM/CCM mode. Defaults to 12 zero bytes if omitted."
                },
                {
                  "id": "aad",
                  "name": "AAD",
                  "spec": "GCM/CCM only",
                  "dataType": "bytes",
                  "required": false,
                  "description": "Additional Authenticated Data, used only in GCM/CCM mode."
                }
              ],
              "outputs": [
                {
                  "id": "ciphertext",
                  "name": "Ciphertext",
                  "dataType": "bytes"
                },
                {
                  "id": "tag",
                  "name": "Auth Tag",
                  "spec": "GCM/CCM",
                  "dataType": "bytes",
                  "description": "Authentication tag produced in GCM/CCM mode."
                }
              ],
              "properties": {
                "mode": "CBC",
                "padding": "None",
                "errorUnify": false,
                "errorUnifyCode": "",
                "errorUnifyMessage": ""
              },
              "note": "# 3. full_mac\n`full_mac = AES_ENC_CBC(key, nonce, iv)`\n- The 32-byte nonce is exactly two blocks, so no padding.",
              "executionState": "success",
              "executionDurationMs": 5,
              "outputValues": {
                "ciphertext": {
                  "0": 27,
                  "1": 212,
                  "2": 156,
                  "3": 196,
                  "4": 36,
                  "5": 237,
                  "6": 18,
                  "7": 25,
                  "8": 104,
                  "9": 200,
                  "10": 92,
                  "11": 208,
                  "12": 247,
                  "13": 146,
                  "14": 207,
                  "15": 130,
                  "16": 57,
                  "17": 180,
                  "18": 21,
                  "19": 193,
                  "20": 223,
                  "21": 235,
                  "22": 143,
                  "23": 82,
                  "24": 51,
                  "25": 100,
                  "26": 39,
                  "27": 157,
                  "28": 4,
                  "29": 253,
                  "30": 46,
                  "31": 243
                },
                "tag": {}
              }
            },
            "measured": {
              "width": 304,
              "height": 207
            },
            "selected": false
          },
          {
            "id": "cut",
            "type": "cryptoNode",
            "position": {
              "x": 2064,
              "y": 64
            },
            "width": 304,
            "data": {
              "id": "cut",
              "type": "cryptoNode",
              "nodeType": "utility-slicer",
              "label": "MAC",
              "category": "utility",
              "description": "Extracts bytes like the script slice b[offset, length]: empty length = to the end, negative = end position counted from the back (excluded)",
              "inputs": [
                {
                  "id": "data",
                  "name": "Data",
                  "dataType": "bytes",
                  "required": true
                }
              ],
              "outputs": [
                {
                  "id": "sliced",
                  "name": "Sliced Bytes",
                  "dataType": "bytes"
                }
              ],
              "properties": {
                "offset": -16,
                "length": "8"
              },
              "note": "# 3. mac\n`mac = full_mac[-16,8]`: the first 8 bytes of the last block (offset 16 bytes back from the end, length 8).",
              "executionState": "success",
              "executionDurationMs": 4,
              "outputValues": {
                "sliced": {
                  "0": 57,
                  "1": 180,
                  "2": 21,
                  "3": 193,
                  "4": 223,
                  "5": 235,
                  "6": 143,
                  "7": 82
                }
              }
            },
            "measured": {
              "width": 304,
              "height": 147
            },
            "selected": false
          },
          {
            "id": "out",
            "type": "cryptoNode",
            "position": {
              "x": 2544,
              "y": 64
            },
            "width": 208,
            "data": {
              "id": "out",
              "type": "cryptoNode",
              "nodeType": "workflow-output",
              "label": "Workflow Output",
              "category": "input",
              "description": "Workflow egress interface. Gathers final pipeline results for API response or caller return.",
              "inputs": [
                {
                  "id": "pub",
                  "name": "Client Public Key",
                  "dataType": "bytes",
                  "required": true
                },
                {
                  "id": "mac",
                  "name": "MAC",
                  "dataType": "bytes",
                  "required": true
                }
              ],
              "outputs": [],
              "size": "small",
              "dynamicInputs": {
                "min": 0,
                "defaultNamePrefix": "Return",
                "defaultDataType": "bytes"
              },
              "properties": {},
              "note": "# Request DID Auth\nThe client sends `{pubKey_client, mac}` to the server.",
              "executionState": "success",
              "executionDurationMs": 5,
              "outputValues": {
                "result": {
                  "pub": {
                    "0": 4,
                    "1": 21,
                    "2": 220,
                    "3": 25,
                    "4": 59,
                    "5": 142,
                    "6": 42,
                    "7": 104,
                    "8": 141,
                    "9": 96,
                    "10": 51,
                    "11": 3,
                    "12": 232,
                    "13": 94,
                    "14": 200,
                    "15": 252,
                    "16": 193,
                    "17": 93,
                    "18": 203,
                    "19": 164,
                    "20": 78,
                    "21": 242,
                    "22": 21,
                    "23": 106,
                    "24": 18,
                    "25": 140,
                    "26": 56,
                    "27": 107,
                    "28": 102,
                    "29": 180,
                    "30": 245,
                    "31": 225,
                    "32": 210,
                    "33": 24,
                    "34": 142,
                    "35": 124,
                    "36": 169,
                    "37": 208,
                    "38": 56,
                    "39": 92,
                    "40": 2,
                    "41": 231,
                    "42": 44,
                    "43": 104,
                    "44": 153,
                    "45": 242,
                    "46": 119,
                    "47": 30,
                    "48": 134,
                    "49": 187,
                    "50": 1,
                    "51": 122,
                    "52": 45,
                    "53": 41,
                    "54": 3,
                    "55": 216,
                    "56": 154,
                    "57": 40,
                    "58": 146,
                    "59": 194,
                    "60": 25,
                    "61": 154,
                    "62": 236,
                    "63": 143,
                    "64": 77
                  },
                  "mac": {
                    "0": 57,
                    "1": 180,
                    "2": 21,
                    "3": 193,
                    "4": 223,
                    "5": 235,
                    "6": 143,
                    "7": 82
                  }
                },
                "pub": {
                  "0": 4,
                  "1": 21,
                  "2": 220,
                  "3": 25,
                  "4": 59,
                  "5": 142,
                  "6": 42,
                  "7": 104,
                  "8": 141,
                  "9": 96,
                  "10": 51,
                  "11": 3,
                  "12": 232,
                  "13": 94,
                  "14": 200,
                  "15": 252,
                  "16": 193,
                  "17": 93,
                  "18": 203,
                  "19": 164,
                  "20": 78,
                  "21": 242,
                  "22": 21,
                  "23": 106,
                  "24": 18,
                  "25": 140,
                  "26": 56,
                  "27": 107,
                  "28": 102,
                  "29": 180,
                  "30": 245,
                  "31": 225,
                  "32": 210,
                  "33": 24,
                  "34": 142,
                  "35": 124,
                  "36": 169,
                  "37": 208,
                  "38": 56,
                  "39": 92,
                  "40": 2,
                  "41": 231,
                  "42": 44,
                  "43": 104,
                  "44": 153,
                  "45": 242,
                  "46": 119,
                  "47": 30,
                  "48": 134,
                  "49": 187,
                  "50": 1,
                  "51": 122,
                  "52": 45,
                  "53": 41,
                  "54": 3,
                  "55": 216,
                  "56": 154,
                  "57": 40,
                  "58": 146,
                  "59": 194,
                  "60": 25,
                  "61": 154,
                  "62": 236,
                  "63": 143,
                  "64": 77
                },
                "mac": {
                  "0": 57,
                  "1": 180,
                  "2": 21,
                  "3": 193,
                  "4": 223,
                  "5": 235,
                  "6": 143,
                  "7": 82
                }
              }
            },
            "measured": {
              "width": 208,
              "height": 172
            },
            "selected": false,
            "dragging": false
          }
        ],
        "edges": [
          {
            "id": "edge-in-prv-ecdh-privateKey",
            "source": "in",
            "sourceHandle": "prv",
            "target": "ecdh",
            "targetHandle": "privateKey",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            },
            "selected": false
          },
          {
            "id": "edge-in-spub-ecdh-peerPublicKey",
            "source": "in",
            "sourceHandle": "spub",
            "target": "ecdh",
            "targetHandle": "peerPublicKey",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            },
            "selected": false
          },
          {
            "id": "edge-ecdh-sharedSecret-sha-data",
            "source": "ecdh",
            "sourceHandle": "sharedSecret",
            "target": "sha",
            "targetHandle": "data",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            },
            "selected": false
          },
          {
            "id": "edge-sha-digest-ks-data",
            "source": "sha",
            "sourceHandle": "digest",
            "target": "ks",
            "targetHandle": "data",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            },
            "selected": false
          },
          {
            "id": "edge-sha-digest-ivs-data",
            "source": "sha",
            "sourceHandle": "digest",
            "target": "ivs",
            "targetHandle": "data",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            },
            "selected": false
          },
          {
            "id": "edge-ks-sliced-cbc-key",
            "source": "ks",
            "sourceHandle": "sliced",
            "target": "cbc",
            "targetHandle": "key",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            },
            "selected": false
          },
          {
            "id": "edge-ivs-sliced-cbc-iv",
            "source": "ivs",
            "sourceHandle": "sliced",
            "target": "cbc",
            "targetHandle": "iv",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            },
            "selected": false
          },
          {
            "id": "edge-in-nonce-cbc-plaintext",
            "source": "in",
            "sourceHandle": "nonce",
            "target": "cbc",
            "targetHandle": "plaintext",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            },
            "selected": false
          },
          {
            "id": "edge-cbc-ciphertext-cut-data",
            "source": "cbc",
            "sourceHandle": "ciphertext",
            "target": "cut",
            "targetHandle": "data",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            },
            "selected": false
          },
          {
            "id": "edge-cut-sliced-out-mac",
            "source": "cut",
            "sourceHandle": "sliced",
            "target": "out",
            "targetHandle": "mac",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            },
            "selected": false
          },
          {
            "interactionWidth": 14,
            "selectable": false,
            "source": "in",
            "sourceHandle": "pub",
            "target": "out",
            "targetHandle": "pub",
            "type": "custom",
            "data": {
              "dataType": "bytes"
            },
            "selected": false,
            "zIndex": 2000,
            "animated": false,
            "id": "xy-edge__inpub-outpub"
          }
        ]
      }
    }
  }
}