"use strict"; const test = require("node:test"); const assert = require("node:assert/strict"); const crypto = require("node:crypto"); const fs = require("node:fs"); const os = require("node:os"); const path = require("node:path"); const { fingerprint, handshake } = require("../src/identity"); test("handshake binds caller nonce, agent identity and state version", () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), "chenglu-identity-")); try { const { privateKey, publicKey } = crypto.generateKeyPairSync("ed25519"); const privatePath = path.join(dir, "identity.key"); const publicPath = path.join(dir, "identity.pub"); fs.writeFileSync(privatePath, privateKey.export({ type: "pkcs8", format: "pem" })); fs.writeFileSync(publicPath, publicKey.export({ type: "spki", format: "pem" })); const result = handshake({ privateKeyPath: privatePath, publicKeyPath: publicPath, callerNonce: "ice-shuo-test-nonce-0001", stateVersion: 7 }); assert.equal(result.agent_id, "CHENGLU-AGENT-001"); assert.equal(result.payload.state_version, 7); assert.equal(result.identity_fingerprint, fingerprint(fs.readFileSync(publicPath, "utf8"))); assert.equal(crypto.verify(null, Buffer.from(JSON.stringify(result.payload)), publicKey, Buffer.from(result.signature, "base64")), true); } finally { fs.rmSync(dir, { recursive: true, force: true }); } }); test("handshake rejects short or malformed caller nonce", () => { assert.throws(() => handshake({ callerNonce: "short", privateKeyPath: "x", publicKeyPath: "y", stateVersion: 0 }), /invalid_caller_nonce/); });