cpace-ts 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +20 -0
- package/dist/index.cjs +797 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +135 -0
- package/dist/index.d.ts +135 -0
- package/dist/index.js +759 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
- package/wasm/pkg/.gitignore +1 -0
- package/wasm/pkg/cpace_wasm.d.ts +38 -0
- package/wasm/pkg/cpace_wasm.js +180 -0
- package/wasm/pkg/cpace_wasm_bg.js +81 -0
- package/wasm/pkg/cpace_wasm_bg.wasm +0 -0
- package/wasm/pkg/cpace_wasm_bg.wasm.d.ts +9 -0
- package/wasm/pkg/package.json +15 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cpace-errors.ts","../src/bytes.ts","../src/cpace-strings.ts","../src/elligator2-curve25519.ts","../src/x25519-noble.ts","../src/cpace-group-x25519.ts","../src/cpace-validation.ts","../src/cpace-audit.ts","../src/cpace-crypto.ts","../src/cpace-message.ts","../src/cpace-transcript.ts","../src/cpace-session.ts","../src/hash.ts"],"sourcesContent":["export class InvalidPeerElementError extends Error {\n\tconstructor(\n\t\tmessage = \"CPaceSession: invalid peer element\",\n\t\toptions?: ErrorOptions,\n\t) {\n\t\tsuper(message, options);\n\t\tthis.name = \"InvalidPeerElementError\";\n\t}\n}\n","export function compareBytes(a: Uint8Array, b: Uint8Array): number {\n\tconst len = Math.min(a.length, b.length);\n\tfor (let i = 0; i < len; i += 1) {\n\t\tconst ai = a[i] ?? 0;\n\t\tconst bi = b[i] ?? 0;\n\t\tif (ai !== bi) return ai - bi;\n\t}\n\treturn a.length - b.length;\n}\n\nexport function equalBytes(a: Uint8Array, b: Uint8Array): boolean {\n\tif (a.length !== b.length) return false;\n\tlet diff = 0;\n\tfor (let i = 0; i < a.length; i += 1) {\n\t\tconst ai = a[i] ?? 0;\n\t\tconst bi = b[i] ?? 0;\n\t\tdiff |= ai ^ bi;\n\t}\n\treturn diff === 0;\n}\n","const textEncoder = new TextEncoder();\n\nexport function utf8(value: string): Uint8Array {\n\treturn textEncoder.encode(value);\n}\n\nexport function leb128Encode(n: number): Uint8Array {\n\tif (!Number.isSafeInteger(n) || n < 0) {\n\t\tthrow new RangeError(\"leb128Encode: n must be a non-negative safe integer\");\n\t}\n\tconst bytes: number[] = [];\n\tlet v = n;\n\twhile (true) {\n\t\tlet byte = v & 0x7f;\n\t\tv = Math.floor(v / 128);\n\t\tif (v !== 0) byte |= 0x80;\n\t\tbytes.push(byte);\n\t\tif (v === 0) break;\n\t}\n\treturn new Uint8Array(bytes);\n}\n\n// A.1.1\nexport function prependLen(data: Uint8Array): Uint8Array {\n\tconst lenEnc = leb128Encode(data.length);\n\tconst out = new Uint8Array(lenEnc.length + data.length);\n\tout.set(lenEnc, 0);\n\tout.set(data, lenEnc.length);\n\treturn out;\n}\n\n// A.1.3\nexport function lvCat(...parts: Uint8Array[]): Uint8Array {\n\tlet total = 0;\n\tconst prepped: Uint8Array[] = [];\n\tfor (const p of parts) {\n\t\tconst withLen = prependLen(p);\n\t\tprepped.push(withLen);\n\t\ttotal += withLen.length;\n\t}\n\tconst out = new Uint8Array(total);\n\tlet off = 0;\n\tfor (const w of prepped) {\n\t\tout.set(w, off);\n\t\toff += w.length;\n\t}\n\treturn out;\n}\n\nexport function zeroBytes(n: number): Uint8Array {\n\treturn new Uint8Array(n);\n}\n\n// A.2\nexport function generatorString(\n\tdsi: Uint8Array,\n\tprs: Uint8Array,\n\tci: Uint8Array | undefined,\n\tsid: Uint8Array | undefined,\n\tsInBytes: number,\n): Uint8Array {\n\tconst prsPl = prependLen(prs);\n\tconst dsiPl = prependLen(dsi);\n\tconst lenZpad = Math.max(0, sInBytes - 1 - prsPl.length - dsiPl.length);\n\tconst zpad = zeroBytes(lenZpad);\n\treturn lvCat(\n\t\tdsi,\n\t\tprs,\n\t\tzpad,\n\t\tci ?? new Uint8Array(0),\n\t\tsid ?? new Uint8Array(0),\n\t);\n}\n\nexport function bytesToHex(u: Uint8Array): string {\n\treturn Array.from(u)\n\t\t.map((b) => b.toString(16).padStart(2, \"0\"))\n\t\t.join(\"\");\n}\n\n// =========================\n// A.3 ordered concatenation\n// =========================\n\n// A.3.1\nexport function lexicographicallyLarger(\n\tbytes1: Uint8Array,\n\tbytes2: Uint8Array,\n): boolean {\n\tconst minLen = Math.min(bytes1.length, bytes2.length);\n\tfor (let i = 0; i < minLen; i += 1) {\n\t\tconst b1 = bytes1[i] as number;\n\t\tconst b2 = bytes2[i] as number;\n\t\tif (b1 > b2) {\n\t\t\treturn true;\n\t\t} else if (b1 < b2) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn bytes1.length > bytes2.length;\n}\n\n// A.3.2\nexport function oCat(bytes1: Uint8Array, bytes2: Uint8Array): Uint8Array {\n\tif (lexicographicallyLarger(bytes1, bytes2)) {\n\t\treturn concat([utf8(\"oc\"), bytes1, bytes2]);\n\t}\n\treturn concat([utf8(\"oc\"), bytes2, bytes1]);\n}\n\n// A.3.4\nexport function transcriptIr(\n\tya: Uint8Array,\n\tada: Uint8Array,\n\tyb: Uint8Array,\n\tadb: Uint8Array,\n): Uint8Array {\n\tconst left = lvCat(ya, ada);\n\tconst right = lvCat(yb, adb);\n\treturn concat([left, right]);\n}\n\n// A.3.6\nexport function transcriptOc(\n\tya: Uint8Array,\n\tada: Uint8Array,\n\tyb: Uint8Array,\n\tadb: Uint8Array,\n): Uint8Array {\n\tconst left = lvCat(ya, ada);\n\tconst right = lvCat(yb, adb);\n\treturn oCat(left, right);\n}\n\n// общий concat, чтобы не дублировать\nexport function concat(chunks: Uint8Array[]): Uint8Array {\n\tlet total = 0;\n\tfor (const c of chunks) total += c.length;\n\tconst out = new Uint8Array(total);\n\tlet off = 0;\n\tfor (const c of chunks) {\n\t\tout.set(c, off);\n\t\toff += c.length;\n\t}\n\treturn out;\n}\n","// src/elligator2-curve25519.ts\n//\n// Invariant: wasm is built with `wasm-pack build --target web` (manual instantiation). [web:13][web:36]\n// Vite does not support the \"ESM integration proposal for Wasm\" used by `--target bundler`. [web:166][web:13]\n\nimport init, {\n\telligator2_curve25519_u,\n\tinitSync,\n} from \"../wasm/pkg/cpace_wasm.js\";\n\nlet ready: Promise<void> | null = null;\nlet inited = false;\n\nasync function initOnce(): Promise<void> {\n\tconst wasmUrl = new URL(\"../wasm/pkg/cpace_wasm_bg.wasm\", import.meta.url);\n\n\tif (wasmUrl.protocol === \"file:\") {\n\t\tconst { readFile } = await import(\"node:fs/promises\");\n\t\tconst bytes = await readFile(wasmUrl);\n\t\tinitSync({ module: bytes }); // sync instantiation from bytes is supported. [web:193]\n\t\treturn;\n\t}\n\n\tconst resp = await fetch(wasmUrl);\n\tif (!resp.ok)\n\t\tthrow new Error(`Failed to load WASM: ${resp.status} ${resp.statusText}`);\n\tawait init(resp);\n}\n\nexport function initElligator2Wasm(): Promise<void> {\n\tif (inited) return Promise.resolve();\n\n\tif (!ready) {\n\t\tready = initOnce()\n\t\t\t.then(() => {\n\t\t\t\tinited = true;\n\t\t\t})\n\t\t\t.catch((e) => {\n\t\t\t\tready = null; // allow retry after transient failure\n\t\t\t\tinited = false;\n\t\t\t\tthrow e;\n\t\t\t});\n\t}\n\n\treturn ready;\n}\n\nexport async function mapToCurveElligator2(\n\tu: Uint8Array,\n): Promise<Uint8Array> {\n\tif (u.length !== 32) throw new Error(\"Expected 32-byte input\");\n\tawait initElligator2Wasm();\n\treturn elligator2_curve25519_u(u);\n}\n\nexport async function mapToCurveElligator2Async(\n\tu: Uint8Array,\n): Promise<Uint8Array> {\n\treturn mapToCurveElligator2(u);\n}\n","// src/x25519-noble.ts\nimport { x25519 } from \"@noble/curves/ed25519.js\";\n\n// приватный: 32 байта (LE), публичный: 32 байта (u)\nexport function x25519Noble(\n\tprivScalar: Uint8Array,\n\tpubU: Uint8Array,\n): Uint8Array {\n\tif (privScalar.length !== 32) {\n\t\tthrow new Error(\n\t\t\t`x25519Noble: privScalar must be 32 bytes, got ${privScalar.length}`,\n\t\t);\n\t}\n\tif (pubU.length !== 32) {\n\t\tthrow new Error(`x25519Noble: pubU must be 32 bytes, got ${pubU.length}`);\n\t}\n\n\t// noble сам делает clamp приватного скаляра (как RFC 7748)\n\tconst shared = x25519.getSharedSecret(privScalar, pubU);\n\n\t// Для X25519 общий секрет должен быть 32 байта\n\tif (shared.length !== 32) {\n\t\t// на случай, если API/обвязка когда-то вернёт не 32 (маловероятно для x25519)\n\t\treturn shared.slice(0, 32);\n\t}\n\n\t// Опционально: защита от small-order/invalid public key (all-zero shared secret)\n\t// (в некоторых протоколах это важно; в PAKE — зависит от конкретной схемы)\n\tlet allZero = true;\n\tfor (let i = 0; i < 32; i++) allZero = allZero && shared[i] === 0;\n\tif (allZero) {\n\t\tthrow new Error(\n\t\t\t\"x25519Noble: invalid public key (shared secret is all-zero)\",\n\t\t);\n\t}\n\n\treturn shared;\n}\n","import { compareBytes } from \"./bytes\";\nimport { generatorString, utf8 } from \"./cpace-strings\";\nimport { mapToCurveElligator2 } from \"./elligator2-curve25519\";\nimport type { HashFn } from \"./hash\";\nimport { x25519Noble } from \"./x25519-noble\";\n\nexport interface GroupEnv {\n\tname: string;\n\tfieldSizeBytes: number;\n\tfieldSizeBits: number;\n\tsInBytes: number;\n\tcalculateGenerator(\n\t\thash: HashFn,\n\t\tprs: Uint8Array,\n\t\tci?: Uint8Array,\n\t\tsid?: Uint8Array,\n\t): Promise<Uint8Array>;\n\tsampleScalar(): Uint8Array;\n\tscalarMult(scalar: Uint8Array, point: Uint8Array): Promise<Uint8Array>;\n\tscalarMultVfy(scalar: Uint8Array, point: Uint8Array): Promise<Uint8Array>;\n\tI: Uint8Array;\n\tDSI: Uint8Array;\n\tserialize(point: Uint8Array): Uint8Array;\n\tdeserialize(buf: Uint8Array): Uint8Array;\n}\n\n// general helper\nconst MAX = 65_536;\n\nexport function getRandomBytes(len: number): Uint8Array {\n\tif (!Number.isInteger(len) || len < 0)\n\t\tthrow new RangeError(\"len must be a non-negative integer\");\n\n\tconst c = globalThis.crypto;\n\tif (!c?.getRandomValues) {\n\t\tthrow new Error(\n\t\t\t\"WebCrypto is unavailable. Requires secure context (HTTPS) or an environment with WebCrypto.\",\n\t\t);\n\t}\n\n\tconst out = new Uint8Array(len);\n\tfor (let i = 0; i < len; i += MAX) {\n\t\tc.getRandomValues(out.subarray(i, Math.min(i + MAX, len)));\n\t}\n\treturn out;\n}\n\n// general x25519 wrapper — single entry point\nexport async function x25519(\n\tscalar: Uint8Array,\n\tpoint: Uint8Array,\n): Promise<Uint8Array> {\n\treturn x25519Noble(scalar, point);\n}\n\nexport type LowOrderPointReason =\n\t| \"length\"\n\t| \"missing-last-byte\"\n\t| \"multiply-failed\"\n\t| \"low-order\"\n\t| \"shared-secret-length\";\n\nexport interface LowOrderPointErrorOptions extends ErrorOptions {\n\treason?: LowOrderPointReason;\n}\n\nexport class LowOrderPointError extends Error {\n\treadonly reason: LowOrderPointReason;\n\n\tconstructor(\n\t\tmessage = \"X25519Group.scalarMultVfy: low-order or invalid point\",\n\t\toptions?: LowOrderPointErrorOptions,\n\t) {\n\t\tsuper(message, options);\n\t\tthis.name = \"LowOrderPointError\";\n\t\tthis.reason = options?.reason ?? \"low-order\";\n\t}\n}\n\nexport class X25519Group implements GroupEnv {\n\treadonly name = \"X25519\";\n\treadonly fieldSizeBytes = 32;\n\treadonly fieldSizeBits = 255;\n\t// for SHA-512 (128 byte block)\n\treadonly sInBytes = 128;\n\treadonly DSI = utf8(\"CPace255\");\n\t// neutral element (0^32)\n\treadonly I = new Uint8Array(32);\n\n\tasync calculateGenerator(\n\t\thash: HashFn,\n\t\tprs: Uint8Array,\n\t\tci?: Uint8Array,\n\t\tsid?: Uint8Array,\n\t): Promise<Uint8Array> {\n\t\t// d18: gen_str = generator_string(G.DSI, PRS, CI, sid, H.s_in_bytes)\n\t\tconst genStr = generatorString(this.DSI, prs, ci, sid, this.sInBytes);\n\n\t\t// d18: gen_str_hash = H.hash(gen_str, G.field_size_bytes)\n\t\tconst h = await hash(genStr);\n\t\tif (h.length < this.fieldSizeBytes) {\n\t\t\tthrow new Error(\"X25519Group.calculateGenerator: hash output too short\");\n\t\t}\n\t\tconst genStrHash = h.slice(0, this.fieldSizeBytes);\n\n\t\t// d18: u = decodeUCoordinate(gen_str_hash, G.field_size_bits)\n\t\t// For X25519 (255 bits): clear unused MSB (bit #255).\n\t\tconst lastIndex = this.fieldSizeBytes - 1;\n\t\tconst lastByte = genStrHash[lastIndex];\n\t\tif (lastByte === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t\"X25519Group.calculateGenerator: invalid generator hash length\",\n\t\t\t);\n\t\t}\n\t\tgenStrHash[lastIndex] = lastByte & 0x7f;\n\n\t\t// d18: (g, v) = map_to_curve_elligator2(u); v discarded\n\t\t// IMPORTANT (d18 §9.10): mapping MUST be constant-time.\n\t\tconst gU = await mapToCurveElligator2(genStrHash);\n\n\t\treturn this.serialize(gU);\n\t}\n\n\tsampleScalar(): Uint8Array {\n\t\treturn getRandomBytes(this.fieldSizeBytes);\n\t}\n\n\tasync scalarMult(scalar: Uint8Array, point: Uint8Array): Promise<Uint8Array> {\n\t\treturn x25519(scalar, point);\n\t}\n\n\tasync scalarMultVfy(\n\t\tscalar: Uint8Array,\n\t\tpoint: Uint8Array,\n\t): Promise<Uint8Array> {\n\t\tconst u = point.slice();\n\t\tif (u.length !== this.fieldSizeBytes) {\n\t\t\tthrow new LowOrderPointError(\n\t\t\t\t`X25519Group.scalarMultVfy: invalid point length (expected ${this.fieldSizeBytes} bytes, got ${u.length})`,\n\t\t\t\t{ reason: \"length\" },\n\t\t\t);\n\t\t}\n\t\t// RFC 7748 §5: inputs are interpreted modulo p with the unused MSB cleared.\n\t\tconst inputLastIndex = u.length - 1;\n\t\tconst inputLastByte = u[inputLastIndex];\n\t\tif (inputLastByte === undefined) {\n\t\t\tthrow new LowOrderPointError(\n\t\t\t\t\"X25519Group.scalarMultVfy: invalid point length (missing last byte)\",\n\t\t\t\t{ reason: \"missing-last-byte\" },\n\t\t\t);\n\t\t}\n\t\tu[inputLastIndex] = inputLastByte & 0x7f;\n\n\t\tlet r: Uint8Array;\n\t\ttry {\n\t\t\tr = await x25519(scalar, u);\n\t\t} catch (err) {\n\t\t\tthrow new LowOrderPointError(\n\t\t\t\t\"X25519Group.scalarMultVfy: invalid point multiplication failed\",\n\t\t\t\t{ cause: err, reason: \"multiply-failed\" },\n\t\t\t);\n\t\t}\n\n\t\tif (compareBytes(r, this.I) === 0) {\n\t\t\tthrow new LowOrderPointError(\n\t\t\t\t\"X25519Group.scalarMultVfy: low-order result (all-zero shared secret)\",\n\t\t\t\t{ reason: \"low-order\" },\n\t\t\t);\n\t\t}\n\n\t\t// RFC 7748 §5: clear the unused most significant bit before returning.\n\t\tconst masked = r.slice();\n\t\tif (masked.length !== this.fieldSizeBytes) {\n\t\t\tthrow new LowOrderPointError(\n\t\t\t\t`X25519Group.scalarMultVfy: invalid shared secret length (expected ${this.fieldSizeBytes} bytes, got ${masked.length})`,\n\t\t\t\t{ reason: \"shared-secret-length\" },\n\t\t\t);\n\t\t}\n\t\tconst outputLastIndex = masked.length - 1;\n\t\tconst outputLastByte = masked[outputLastIndex];\n\t\tif (outputLastByte === undefined) {\n\t\t\tthrow new LowOrderPointError(\n\t\t\t\t\"X25519Group.scalarMultVfy: invalid shared secret length (missing last byte)\",\n\t\t\t\t{ reason: \"shared-secret-length\" },\n\t\t\t);\n\t\t}\n\t\tmasked[outputLastIndex] = outputLastByte & 0x7f;\n\n\t\treturn masked;\n\t}\n\n\tserialize(point: Uint8Array): Uint8Array {\n\t\tif (point.length !== this.fieldSizeBytes) {\n\t\t\tthrow new Error(\n\t\t\t\t`X25519Group.serialize: expected ${this.fieldSizeBytes} bytes, got ${point.length}`,\n\t\t\t);\n\t\t}\n\t\treturn point.slice();\n\t}\n\n\tdeserialize(buf: Uint8Array): Uint8Array {\n\t\tif (buf.length !== this.fieldSizeBytes) {\n\t\t\tthrow new Error(\n\t\t\t\t`X25519Group.deserialize: expected ${this.fieldSizeBytes} bytes, got ${buf.length}`,\n\t\t\t);\n\t\t}\n\t\treturn buf.slice();\n\t}\n}\n\nexport const G_X25519 = new X25519Group();\n","const MAX_INPUT_LENGTH = Number.MAX_SAFE_INTEGER;\n\nexport type EnsureBytesOptions = {\n\toptional?: boolean;\n\tminLength?: number;\n\tmaxLength?: number;\n};\n\nexport type EnsureFieldErrorHandler = (\n\terr: unknown,\n\tcontext: {\n\t\tfield: string;\n\t\tvalue: Uint8Array | undefined;\n\t\toptions?: EnsureBytesOptions;\n\t},\n) => void;\n\nexport function ensureBytes(\n\tname: string,\n\tvalue: Uint8Array | undefined,\n\t{\n\t\toptional = true,\n\t\tminLength = 0,\n\t\tmaxLength = MAX_INPUT_LENGTH,\n\t}: EnsureBytesOptions = {},\n): Uint8Array {\n\tif (!Number.isSafeInteger(maxLength) || maxLength < 0) {\n\t\tthrow new RangeError(\n\t\t\t`CPaceSession: ${name} maxLength must be a non-negative safe integer`,\n\t\t);\n\t}\n\n\tif (value === undefined) {\n\t\tif (!optional) {\n\t\t\tthrow new Error(`CPaceSession: ${name} is required`);\n\t\t}\n\t\treturn new Uint8Array(0);\n\t}\n\tif (!(value instanceof Uint8Array)) {\n\t\tthrow new TypeError(`CPaceSession: ${name} must be a Uint8Array`);\n\t}\n\tif (value.length < minLength) {\n\t\tthrow new Error(\n\t\t\t`CPaceSession: ${name} must be at least ${minLength} bytes`,\n\t\t);\n\t}\n\tif (value.length > maxLength) {\n\t\tthrow new Error(`CPaceSession: ${name} must be at most ${maxLength} bytes`);\n\t}\n\treturn value;\n}\n\nexport function ensureField(\n\tfield: string,\n\tvalue: Uint8Array | undefined,\n\toptions?: EnsureBytesOptions,\n\tonError?: EnsureFieldErrorHandler,\n): Uint8Array {\n\ttry {\n\t\treturn ensureBytes(field, value, options);\n\t} catch (err) {\n\t\tconst context =\n\t\t\toptions === undefined ? { field, value } : { field, value, options };\n\t\tonError?.(err, context);\n\t\tthrow err;\n\t}\n}\n\nexport type ExpectedRange = {\n\tmin?: number;\n\tmax?: number;\n};\n\nexport function extractExpected(\n\toptions?: EnsureBytesOptions,\n): ExpectedRange | undefined {\n\tif (!options) return undefined;\n\tconst expected: ExpectedRange = {};\n\tif (options.minLength !== undefined) expected.min = options.minLength;\n\tif (options.maxLength !== undefined) expected.max = options.maxLength;\n\treturn Object.keys(expected).length > 0 ? expected : undefined;\n}\n\nexport function cleanObject(\n\tdata?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n\tif (!data) return undefined;\n\tconst cleaned: Record<string, unknown> = {};\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tif (value === undefined) continue;\n\t\tcleaned[key] = value;\n\t}\n\treturn cleaned;\n}\n\nexport function generateSessionId(): string {\n\tconst length = 16;\n\tconst bytes = new Uint8Array(length);\n\tif (\n\t\ttypeof globalThis.crypto !== \"undefined\" &&\n\t\ttypeof globalThis.crypto.getRandomValues === \"function\"\n\t) {\n\t\tglobalThis.crypto.getRandomValues(bytes);\n\t} else {\n\t\tfor (let i = 0; i < length; i += 1) {\n\t\t\tbytes[i] = Math.floor(Math.random() * 256);\n\t\t}\n\t}\n\treturn Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n","import { cleanObject } from \"./cpace-validation\";\n\nexport type AuditLevel = \"info\" | \"warn\" | \"error\" | \"security\";\n\nexport type AuditEvent = {\n\tts: string;\n\tsessionId: string;\n\tlevel: AuditLevel;\n\tcode: string;\n\tmessage?: string;\n\tdata?: Record<string, unknown>;\n};\n\nexport interface AuditLogger {\n\taudit(event: AuditEvent): void | Promise<void>;\n}\n\nexport const AUDIT_CODES = Object.freeze({\n\tCPACE_SESSION_CREATED: \"CPACE_SESSION_CREATED\",\n\tCPACE_START_BEGIN: \"CPACE_START_BEGIN\",\n\tCPACE_START_SENT: \"CPACE_START_SENT\",\n\tCPACE_RX_RECEIVED: \"CPACE_RX_RECEIVED\",\n\tCPACE_FINISH_BEGIN: \"CPACE_FINISH_BEGIN\",\n\tCPACE_FINISH_OK: \"CPACE_FINISH_OK\",\n\tCPACE_INPUT_INVALID: \"CPACE_INPUT_INVALID\",\n\tCPACE_PEER_INVALID: \"CPACE_PEER_INVALID\",\n\tCPACE_LOW_ORDER_POINT: \"CPACE_LOW_ORDER_POINT\",\n} as const);\n\nexport function emitAuditEvent(\n\tlogger: AuditLogger | undefined,\n\tsessionId: string,\n\tcode: string,\n\tlevel: AuditLevel,\n\tdata?: Record<string, unknown>,\n) {\n\tif (!logger) return;\n\tconst cleaned = cleanObject(data);\n\tconst event: AuditEvent = {\n\t\tts: new Date().toISOString(),\n\t\tsessionId,\n\t\tlevel,\n\t\tcode,\n\t\t...(cleaned ? { data: cleaned } : {}),\n\t};\n\tvoid logger.audit(event);\n}\n","import { compareBytes } from \"./bytes\";\nimport { LowOrderPointError } from \"./cpace-group-x25519\";\nimport type { CPaceSuiteDesc } from \"./cpace-session\";\nimport { InvalidPeerElementError } from \"./cpace-session\";\nimport { concat, lvCat, utf8 } from \"./cpace-strings\";\n\nconst EMPTY = new Uint8Array(0);\n\n/**\n * @internal Generate this party's CPace element and serialized message payload.\n */\nexport async function computeLocalElement(\n\tsuite: CPaceSuiteDesc,\n\tprs: Uint8Array,\n\tci?: Uint8Array,\n\tsid?: Uint8Array,\n): Promise<{ scalar: Uint8Array; serialized: Uint8Array }> {\n\tconst pwdPoint = await suite.group.calculateGenerator(\n\t\tsuite.hash,\n\t\tprs,\n\t\tci ?? EMPTY,\n\t\tsid ?? EMPTY,\n\t);\n\tconst scalar = suite.group.sampleScalar();\n\tconst point = await suite.group.scalarMult(scalar, pwdPoint);\n\tconst serialized = suite.group.serialize(point);\n\treturn { scalar, serialized };\n}\n\n/**\n * @internal Derive the shared secret from the peer's message or throw if invalid.\n * @throws InvalidPeerElementError when deserialization or scalar multiplication fails.\n */\nexport async function deriveSharedSecretOrThrow(\n\tsuite: CPaceSuiteDesc,\n\tephemeralScalar: Uint8Array,\n\tpeerPayload: Uint8Array,\n\tonPeerInvalid: (errName: string, message?: string) => void,\n\tonLowOrder: () => void,\n): Promise<Uint8Array> {\n\tlet peerPoint: Uint8Array;\n\ttry {\n\t\tpeerPoint = suite.group.deserialize(peerPayload);\n\t} catch (err) {\n\t\tonPeerInvalid(\n\t\t\terr instanceof Error ? (err.name ?? \"Error\") : \"UnknownError\",\n\t\t\terr instanceof Error ? err.message : undefined,\n\t\t);\n\t\tthrow new InvalidPeerElementError(undefined, {\n\t\t\tcause: err instanceof Error ? err : undefined,\n\t\t});\n\t}\n\n\tlet sharedSecret: Uint8Array;\n\ttry {\n\t\tsharedSecret = await suite.group.scalarMultVfy(ephemeralScalar, peerPoint);\n\t} catch (err) {\n\t\tif (err instanceof LowOrderPointError) {\n\t\t\tonLowOrder();\n\t\t} else {\n\t\t\tonPeerInvalid(\n\t\t\t\terr instanceof Error ? (err.name ?? \"Error\") : \"UnknownError\",\n\t\t\t\terr instanceof Error ? err.message : undefined,\n\t\t\t);\n\t\t}\n\t\tthrow new InvalidPeerElementError(undefined, {\n\t\t\tcause: err instanceof Error ? err : undefined,\n\t\t});\n\t}\n\n\tif (compareBytes(sharedSecret, suite.group.I) === 0) {\n\t\tonLowOrder();\n\t\tthrow new InvalidPeerElementError();\n\t}\n\n\treturn sharedSecret;\n}\n\n/**\n * @internal Obtain the session key material and sid output from transcript data.\n */\nexport async function deriveIskAndSid(\n\tsuite: CPaceSuiteDesc,\n\ttranscript: Uint8Array,\n\tsharedSecret: Uint8Array,\n\tsid?: Uint8Array,\n): Promise<{ isk: Uint8Array; sidOutput?: Uint8Array }> {\n\tconst dsiIsk = concat([suite.group.DSI, utf8(\"_ISK\")]);\n\n\t// In CPace, sid is an input string. If not present, treat as empty string.\n\tconst sidBytes = sid ?? EMPTY;\n\n\t// ISK = H.hash(lv_cat(DSI||\"_ISK\", sid, K) || transcript)\n\tconst lvPart = lvCat(dsiIsk, sidBytes, sharedSecret);\n\tconst isk = await suite.hash(concat([lvPart, transcript]));\n\n\t// sid_output exists only for the \"empty sid\" run (Section 9.6)\n\tif (sidBytes.length === 0) {\n\t\tconst sidOutput = await suite.hash(\n\t\t\tconcat([utf8(\"CPaceSidOutput\"), transcript]),\n\t\t);\n\t\treturn { isk, sidOutput }; // full hash output (SHA-512 => 64 bytes)\n\t}\n\n\treturn { isk };\n}\n","import { InvalidPeerElementError } from \"./cpace-errors\";\nimport type { CPaceMessage, CPaceSuiteDesc } from \"./cpace-session\";\n\n/**\n * @internal Validate and normalise a received CPace message.\n * @throws InvalidPeerElementError when the payload is malformed.\n */\nexport function validateAndSanitizePeerMessage(\n\tsuite: CPaceSuiteDesc,\n\tmsg: CPaceMessage,\n\tensureBytes: (field: string, value: Uint8Array) => Uint8Array,\n\tonInvalid: (\n\t\tfield: string,\n\t\treason: string,\n\t\textra?: Record<string, unknown>,\n\t) => void,\n): CPaceMessage {\n\tif (!(msg.payload instanceof Uint8Array)) {\n\t\tthrow new InvalidPeerElementError(\n\t\t\t\"CPaceSession.receive: peer payload must be a Uint8Array\",\n\t\t);\n\t}\n\tconst expectedPayloadLength = suite.group.fieldSizeBytes;\n\tif (msg.payload.length !== expectedPayloadLength) {\n\t\tonInvalid(\"peer.payload\", \"invalid length\", {\n\t\t\texpected: expectedPayloadLength,\n\t\t\tactual: msg.payload.length,\n\t\t});\n\t\tthrow new InvalidPeerElementError(\n\t\t\t`CPaceSession.receive: peer payload must be ${expectedPayloadLength} bytes`,\n\t\t);\n\t}\n\n\tif (!(msg.ad instanceof Uint8Array)) {\n\t\tonInvalid(\"peer.ad\", \"peer ad must be a Uint8Array\");\n\t\tthrow new InvalidPeerElementError(\n\t\t\t\"CPaceSession.receive: peer ad must be a Uint8Array\",\n\t\t);\n\t}\n\n\t// Allow empty ad; normalization/validation (e.g. max length) can be done by ensureBytes\n\tconst peerAd = ensureBytes(\"peer ad\", msg.ad);\n\n\treturn { type: \"msg\", payload: msg.payload, ad: peerAd };\n}\n","import { transcriptIr, transcriptOc } from \"./cpace-strings\";\n\n/**\n * @internal Construct the initiator-responder transcript in IR order.\n *\n * The message on the wire is (Y, AD) where AD belongs to the sender.\n * In IR mode, AD is named ADa for the initiator and ADb for the responder.\n */\nexport function makeTranscriptIR(\n\trole: \"initiator\" | \"responder\",\n\tlocalMsg: Uint8Array,\n\tlocalAd: Uint8Array,\n\tpeerPayload: Uint8Array,\n\tpeerAd: Uint8Array,\n): Uint8Array {\n\treturn role === \"initiator\"\n\t\t? transcriptIr(localMsg, localAd, peerPayload, peerAd)\n\t\t: transcriptIr(peerPayload, peerAd, localMsg, localAd);\n}\n\n/**\n * @internal Construct the symmetric-mode transcript using ordered concatenation.\n */\nexport function makeTranscriptOC(\n\tlocalMsg: Uint8Array,\n\tlocalAd: Uint8Array,\n\tpeerPayload: Uint8Array,\n\tpeerAd: Uint8Array,\n): Uint8Array {\n\treturn transcriptOc(localMsg, localAd, peerPayload, peerAd);\n}\n","import type { AuditLevel, AuditLogger } from \"./cpace-audit\";\nimport { AUDIT_CODES, emitAuditEvent } from \"./cpace-audit\";\nimport {\n\tcomputeLocalElement,\n\tderiveIskAndSid,\n\tderiveSharedSecretOrThrow,\n} from \"./cpace-crypto\";\nimport type { GroupEnv } from \"./cpace-group-x25519\";\nimport { validateAndSanitizePeerMessage } from \"./cpace-message\";\nimport { makeTranscriptIR, makeTranscriptOC } from \"./cpace-transcript\";\nimport {\n\tcleanObject,\n\ttype EnsureBytesOptions,\n\tensureField as ensureFieldValidated,\n\textractExpected,\n\tgenerateSessionId,\n} from \"./cpace-validation\";\nimport type { HashFn } from \"./hash\";\n\nconst EMPTY = new Uint8Array(0);\n\nexport type { AuditEvent, AuditLevel, AuditLogger } from \"./cpace-audit\";\nexport { InvalidPeerElementError } from \"./cpace-errors\";\n\n/**\n * Description of the cryptographic suite used for CPace.\n */\nexport interface CPaceSuiteDesc {\n\tname: string;\n\tgroup: GroupEnv;\n\thash: HashFn;\n}\n\nexport type CPaceMode = \"initiator-responder\" | \"symmetric\";\nexport type CPaceRole = \"initiator\" | \"responder\" | \"symmetric\";\n\n/**\n * All inputs required to initialize a CPace session.\n */\nexport type CPaceInputs = {\n\tprs: Uint8Array;\n\tsuite: CPaceSuiteDesc;\n\tmode: CPaceMode;\n\trole: CPaceRole;\n\tad?: Uint8Array;\n\tci?: Uint8Array;\n\tsid?: Uint8Array;\n};\n\n/**\n * Wire-format CPace message exchanged between peers.\n */\nexport type CPaceMessage = { type: \"msg\"; payload: Uint8Array; ad: Uint8Array };\n\nexport class CPaceSession {\n\tprivate readonly auditLogger: AuditLogger | undefined;\n\tprivate readonly sessionId: string;\n\tprivate readonly inputs: CPaceInputs;\n\n\tprivate ephemeralScalar: Uint8Array | undefined;\n\tprivate localMsg: Uint8Array | undefined;\n\tprivate iskValue: Uint8Array | undefined;\n\tprivate sidValue: Uint8Array | undefined;\n\n\t/**\n\t * Instantiate a CPace session for a local participant.\n\t *\n\t * @param options Protocol inputs and optional audit logger/session id.\n\t */\n\tconstructor(\n\t\toptions: CPaceInputs & { audit?: AuditLogger; sessionId?: string },\n\t) {\n\t\tconst { audit, sessionId, ...inputs } = options;\n\t\tthis.auditLogger = audit;\n\t\tthis.sessionId = sessionId ?? generateSessionId();\n\n\t\t// normalize ad once\n\t\tthis.inputs = {\n\t\t\t...inputs,\n\t\t\tad: inputs.ad ?? EMPTY,\n\t\t\tci: inputs.ci ?? EMPTY,\n\t\t\tsid: inputs.sid ?? EMPTY,\n\t\t};\n\n\t\tconst { mode, role, suite, ci, sid, ad } = this.inputs;\n\n\t\tif (\n\t\t\t(mode === \"symmetric\" && role !== \"symmetric\") ||\n\t\t\t(mode === \"initiator-responder\" && role === \"symmetric\")\n\t\t) {\n\t\t\tthis.reportInputInvalid(\"role\", \"role must match selected mode\", {\n\t\t\t\tmode,\n\t\t\t\trole,\n\t\t\t});\n\t\t\tthrow new Error(\"CPaceSession: invalid mode/role combination\");\n\t\t}\n\n\t\tthis.emitAudit(AUDIT_CODES.CPACE_SESSION_CREATED, \"info\", {\n\t\t\tmode,\n\t\t\trole,\n\t\t\tsuite: suite.name,\n\t\t\tci_len: ci?.length ?? 0,\n\t\t\tsid_len: sid?.length ?? 0,\n\t\t\tad_len: ad?.length,\n\t\t});\n\t}\n\n\t/**\n\t * Produce the local CPace message when acting as initiator or symmetric peer.\n\t *\n\t * @returns The outbound CPace message, or `undefined` when a responder should wait.\n\t * @throws Error if required inputs are missing or invalid.\n\t */\n\tasync start(): Promise<CPaceMessage | undefined> {\n\t\tconst { suite, prs, ci, sid, ad, role, mode } = this.inputs;\n\n\t\tconst normalizedPrs = this.ensureRequired(\"prs\", prs, { minLength: 1 });\n\n\t\t// ad is always defined if you normalized in ctor; allow empty\n\t\tconst normalizedAd = this.ensureRequired(\"ad\", ad); // no minLength => empty ok\n\n\t\tthis.emitAudit(AUDIT_CODES.CPACE_START_BEGIN, \"info\", { mode, role });\n\n\t\tconst { scalar: ephemeralScalar, serialized: localMsg } =\n\t\t\tawait computeLocalElement(suite, normalizedPrs, ci, sid);\n\n\t\tthis.ephemeralScalar = ephemeralScalar;\n\t\tthis.localMsg = localMsg;\n\n\t\tif (mode === \"initiator-responder\" && role === \"responder\") {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst outbound: CPaceMessage = {\n\t\t\ttype: \"msg\",\n\t\t\tpayload: this.localMsg,\n\t\t\tad: normalizedAd,\n\t\t};\n\n\t\tthis.emitAudit(AUDIT_CODES.CPACE_START_SENT, \"info\", {\n\t\t\tpayload_len: outbound.payload.length,\n\t\t\tad_len: outbound.ad.length,\n\t\t});\n\n\t\treturn outbound;\n\t}\n\t/**\n\t * Consume a peer CPace message and, when required, return a response.\n\t *\n\t * @param msg Peer message containing the serialized group element and optional AD.\n\t * @returns A response message for responder roles, otherwise `undefined`.\n\t * @throws InvalidPeerElementError when peer inputs are malformed or low-order.\n\t */\n\tasync receive(msg: CPaceMessage): Promise<CPaceMessage | undefined> {\n\t\tconst { prs, sid, ad, role, mode, suite } = this.inputs;\n\n\t\tthis.ensureRequired(\"prs\", prs, { minLength: 1 });\n\n\t\t// local AD is required semantically, but empty is allowed\n\t\tconst localAd = this.ensureRequired(\"ad\", ad); // no minLength => empty ok\n\n\t\tconst sanitizedPeerMsg = validateAndSanitizePeerMessage(\n\t\t\tsuite,\n\t\t\tmsg,\n\t\t\t(field, value) => this.ensureRequired(field, value),\n\t\t\t(field, reason, extra) => this.reportInputInvalid(field, reason, extra),\n\t\t);\n\n\t\tawait this.ensureResponderHasLocalMsg(mode, role);\n\n\t\tthis.emitAudit(AUDIT_CODES.CPACE_RX_RECEIVED, \"info\", {\n\t\t\tpayload_len: sanitizedPeerMsg.payload.length,\n\t\t\tad_len: sanitizedPeerMsg.ad.length,\n\t\t});\n\n\t\tthis.iskValue = await this.finish(sid, sanitizedPeerMsg);\n\n\t\t// IR responder sends its single response message (Yb, ADb)\n\t\tif (mode === \"initiator-responder\" && role === \"responder\") {\n\t\t\tif (!this.localMsg) {\n\t\t\t\tthrow new Error(\"CPaceSession.receive: missing outbound message\");\n\t\t\t}\n\t\t\tconst response: CPaceMessage = {\n\t\t\t\ttype: \"msg\",\n\t\t\t\tpayload: this.localMsg,\n\t\t\t\tad: localAd, // responder's ADb (may be EMPTY)\n\t\t\t};\n\n\t\t\tthis.emitAudit(AUDIT_CODES.CPACE_START_SENT, \"info\", {\n\t\t\t\tpayload_len: response.payload.length,\n\t\t\t\tad_len: response.ad.length,\n\t\t\t});\n\n\t\t\treturn response;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Export the derived session key after `receive` completes the handshake.\n\t *\n\t * @returns The session's intermediate shared key (ISK).\n\t * @throws Error if the session has not successfully finished.\n\t */\n\texportISK(): Uint8Array {\n\t\tif (!this.iskValue) throw new Error(\"CPaceSession: not finished\");\n\t\treturn this.iskValue.slice();\n\t}\n\n\t/**\n\t * Obtain the session identifier output negotiated during the handshake, if any.\n\t */\n\tget sidOutput(): Uint8Array | undefined {\n\t\treturn this.sidValue ? this.sidValue.slice() : undefined;\n\t}\n\n\tprivate async finish(\n\t\tsid: Uint8Array | undefined,\n\t\tpeerMsg: CPaceMessage,\n\t): Promise<Uint8Array> {\n\t\tif (!this.ephemeralScalar || !this.localMsg) {\n\t\t\tthrow new Error(\"CPaceSession.finish: session not started\");\n\t\t}\n\n\t\tconst { suite, mode, role, ad } = this.inputs;\n\t\tconst localAd = this.ensureRequired(\"ad\", ad); // empty ok\n\t\tconst peerAd = this.ensureRequired(\"peer ad\", peerMsg.ad); // after sanitize it should exist\n\n\t\tthis.emitAudit(AUDIT_CODES.CPACE_FINISH_BEGIN, \"info\", { mode, role });\n\n\t\tconst sharedSecret = await deriveSharedSecretOrThrow(\n\t\t\tsuite,\n\t\t\tthis.ephemeralScalar,\n\t\t\tpeerMsg.payload,\n\t\t\t(errorName, message) => {\n\t\t\t\tthis.emitAudit(AUDIT_CODES.CPACE_PEER_INVALID, \"error\", {\n\t\t\t\t\terror: errorName,\n\t\t\t\t\tmessage,\n\t\t\t\t});\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tthis.emitAudit(AUDIT_CODES.CPACE_LOW_ORDER_POINT, \"security\", {});\n\t\t\t},\n\t\t);\n\n\t\tlet transcript: Uint8Array;\n\t\tif (mode === \"initiator-responder\") {\n\t\t\t// IR order depends on role\n\t\t\tif (role === \"initiator\") {\n\t\t\t\ttranscript = makeTranscriptIR(\n\t\t\t\t\t\"initiator\",\n\t\t\t\t\tthis.localMsg,\n\t\t\t\t\tlocalAd,\n\t\t\t\t\tpeerMsg.payload,\n\t\t\t\t\tpeerAd,\n\t\t\t\t);\n\t\t\t} else if (role === \"responder\") {\n\t\t\t\ttranscript = makeTranscriptIR(\n\t\t\t\t\t\"responder\",\n\t\t\t\t\tthis.localMsg,\n\t\t\t\t\tlocalAd,\n\t\t\t\t\tpeerMsg.payload,\n\t\t\t\t\tpeerAd,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"CPaceSession.finish: symmetric role in initiator-responder mode\",\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// symmetric: ordered concatenation will canonicalize (Y,AD) pairs\n\t\t\ttranscript = makeTranscriptOC(\n\t\t\t\tthis.localMsg,\n\t\t\t\tlocalAd,\n\t\t\t\tpeerMsg.payload,\n\t\t\t\tpeerAd,\n\t\t\t);\n\t\t}\n\n\t\tconst { isk, sidOutput } = await deriveIskAndSid(\n\t\t\tsuite,\n\t\t\ttranscript,\n\t\t\tsharedSecret,\n\t\t\tsid,\n\t\t);\n\n\t\tthis.sidValue = sidOutput;\n\t\tthis.zeroizeSecrets(sharedSecret);\n\n\t\tthis.emitAudit(AUDIT_CODES.CPACE_FINISH_OK, \"info\", {\n\t\t\ttranscript_type: mode === \"initiator-responder\" ? \"ir\" : \"oc\",\n\t\t\tsid_provided: Boolean(sid?.length),\n\t\t});\n\n\t\treturn isk;\n\t}\n\n\t/** @internal */\n\tprivate async ensureResponderHasLocalMsg(\n\t\tmode: CPaceMode,\n\t\trole: CPaceRole,\n\t): Promise<void> {\n\t\tif (\n\t\t\tmode === \"initiator-responder\" &&\n\t\t\trole === \"responder\" &&\n\t\t\t!this.localMsg\n\t\t) {\n\t\t\tawait this.start();\n\t\t}\n\t}\n\n\t/** @internal */\n\tprivate zeroizeSecrets(...buffers: Uint8Array[]): void {\n\t\tif (this.ephemeralScalar) {\n\t\t\tthis.ephemeralScalar.fill(0);\n\t\t\tthis.ephemeralScalar = undefined;\n\t\t}\n\t\tfor (const buffer of buffers) {\n\t\t\tbuffer.fill(0);\n\t\t}\n\t}\n\n\tprivate ensureRequired(\n\t\tfield: string,\n\t\tvalue: Uint8Array | undefined,\n\t\toptions?: EnsureBytesOptions,\n\t): Uint8Array {\n\t\tconst enforcedOptions: EnsureBytesOptions = { ...options, optional: false };\n\t\treturn ensureFieldValidated(field, value, enforcedOptions, (err, ctx) => {\n\t\t\tthis.reportInputInvalid(\n\t\t\t\tfield,\n\t\t\t\terr instanceof Error ? err.message : \"validation failed\",\n\t\t\t\tthis.buildValidationAuditExtra(ctx),\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate buildValidationAuditExtra(ctx: {\n\t\toptions?: EnsureBytesOptions;\n\t\tvalue: Uint8Array | undefined;\n\t}): {\n\t\texpected?: ReturnType<typeof extractExpected>;\n\t\tactual: number | \"undefined\" | null;\n\t} {\n\t\treturn {\n\t\t\texpected: extractExpected(ctx.options),\n\t\t\tactual:\n\t\t\t\tctx.value instanceof Uint8Array\n\t\t\t\t\t? ctx.value.length\n\t\t\t\t\t: ctx.value === undefined\n\t\t\t\t\t\t? \"undefined\"\n\t\t\t\t\t\t: null,\n\t\t};\n\t}\n\n\tprivate reportInputInvalid(\n\t\tfield: string,\n\t\treason: string,\n\t\textra?: Record<string, unknown>,\n\t): void {\n\t\tconst extras = cleanObject(extra);\n\t\tthis.emitAudit(AUDIT_CODES.CPACE_INPUT_INVALID, \"warn\", {\n\t\t\tfield,\n\t\t\treason,\n\t\t\t...(extras ?? {}),\n\t\t});\n\t}\n\n\tprivate emitAudit(\n\t\tcode: string,\n\t\tlevel: AuditLevel,\n\t\tdata?: Record<string, unknown>,\n\t): void {\n\t\temitAuditEvent(this.auditLogger, this.sessionId, code, level, data);\n\t}\n}\n","export type HashFn = (input: Uint8Array) => Promise<Uint8Array>;\n\nexport async function sha512(input: Uint8Array): Promise<Uint8Array> {\n\tif (typeof crypto === \"undefined\" || !crypto.subtle) {\n\t\tthrow new Error(\"sha512: WebCrypto SubtleCrypto is not available\");\n\t}\n\tconst digest = await crypto.subtle.digest(\"SHA-512\", input);\n\treturn new Uint8Array(digest);\n}\n"],"mappings":"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","names":["x25519","ensureBytes","EMPTY"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cpace-ts",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CPace for TypeScript",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/slava-nikulin/cpace-ts.git"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"cpace",
|
|
12
|
+
"pake"
|
|
13
|
+
],
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@biomejs/biome": "2.3.2",
|
|
16
|
+
"@types/node": "^24.9.2",
|
|
17
|
+
"@typescript-eslint/parser": "^8.46.2",
|
|
18
|
+
"rimraf": "^6.1.0",
|
|
19
|
+
"ts-node": "^10.9.2",
|
|
20
|
+
"tsup": "^8.5.0",
|
|
21
|
+
"typescript": "^5.9.3",
|
|
22
|
+
"vitest": "^4.0.4"
|
|
23
|
+
},
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./dist/index.cjs",
|
|
26
|
+
"module": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"require": "./dist/index.cjs"
|
|
33
|
+
},
|
|
34
|
+
"./wasm": {
|
|
35
|
+
"types": "./wasm/pkg/cpace_wasm.d.ts",
|
|
36
|
+
"import": "./wasm/pkg/cpace_wasm.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist/**",
|
|
41
|
+
"wasm/pkg/**",
|
|
42
|
+
"README.md",
|
|
43
|
+
"LICENSE"
|
|
44
|
+
],
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@noble/curves": "^2.0.1"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "pnpm clean && pnpm build:wasm && tsup",
|
|
50
|
+
"build:wasm": "wasm-pack build crates/cpace-wasm --target web --release --out-dir ../../wasm/pkg",
|
|
51
|
+
"dev": "tsup --watch",
|
|
52
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
53
|
+
"clean": "rimraf dist",
|
|
54
|
+
"test:unit": "vitest run --project unit",
|
|
55
|
+
"test:int": "vitest run --project integration",
|
|
56
|
+
"test": "pnpm test:unit && pnpm test:int"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
export function elligator2_curve25519_u(rep: Uint8Array): Uint8Array;
|
|
5
|
+
|
|
6
|
+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
7
|
+
|
|
8
|
+
export interface InitOutput {
|
|
9
|
+
readonly memory: WebAssembly.Memory;
|
|
10
|
+
readonly elligator2_curve25519_u: (a: number, b: number) => [number, number, number, number];
|
|
11
|
+
readonly __wbindgen_externrefs: WebAssembly.Table;
|
|
12
|
+
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
13
|
+
readonly __externref_table_dealloc: (a: number) => void;
|
|
14
|
+
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
15
|
+
readonly __wbindgen_start: () => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
22
|
+
* a precompiled `WebAssembly.Module`.
|
|
23
|
+
*
|
|
24
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
25
|
+
*
|
|
26
|
+
* @returns {InitOutput}
|
|
27
|
+
*/
|
|
28
|
+
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
32
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
33
|
+
*
|
|
34
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
35
|
+
*
|
|
36
|
+
* @returns {Promise<InitOutput>}
|
|
37
|
+
*/
|
|
38
|
+
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/* @ts-self-types="./cpace_wasm.d.ts" */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {Uint8Array} rep
|
|
5
|
+
* @returns {Uint8Array}
|
|
6
|
+
*/
|
|
7
|
+
export function elligator2_curve25519_u(rep) {
|
|
8
|
+
const ptr0 = passArray8ToWasm0(rep, wasm.__wbindgen_malloc);
|
|
9
|
+
const len0 = WASM_VECTOR_LEN;
|
|
10
|
+
const ret = wasm.elligator2_curve25519_u(ptr0, len0);
|
|
11
|
+
if (ret[3]) {
|
|
12
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
13
|
+
}
|
|
14
|
+
var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
15
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
16
|
+
return v2;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function __wbg_get_imports() {
|
|
20
|
+
const import0 = {
|
|
21
|
+
__proto__: null,
|
|
22
|
+
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
|
23
|
+
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
24
|
+
const ret = getStringFromWasm0(arg0, arg1);
|
|
25
|
+
return ret;
|
|
26
|
+
},
|
|
27
|
+
__wbindgen_init_externref_table: function() {
|
|
28
|
+
const table = wasm.__wbindgen_externrefs;
|
|
29
|
+
const offset = table.grow(4);
|
|
30
|
+
table.set(0, undefined);
|
|
31
|
+
table.set(offset + 0, undefined);
|
|
32
|
+
table.set(offset + 1, null);
|
|
33
|
+
table.set(offset + 2, true);
|
|
34
|
+
table.set(offset + 3, false);
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
__proto__: null,
|
|
39
|
+
"./cpace_wasm_bg.js": import0,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getArrayU8FromWasm0(ptr, len) {
|
|
44
|
+
ptr = ptr >>> 0;
|
|
45
|
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function getStringFromWasm0(ptr, len) {
|
|
49
|
+
ptr = ptr >>> 0;
|
|
50
|
+
return decodeText(ptr, len);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let cachedUint8ArrayMemory0 = null;
|
|
54
|
+
function getUint8ArrayMemory0() {
|
|
55
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
56
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
57
|
+
}
|
|
58
|
+
return cachedUint8ArrayMemory0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function passArray8ToWasm0(arg, malloc) {
|
|
62
|
+
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
63
|
+
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
64
|
+
WASM_VECTOR_LEN = arg.length;
|
|
65
|
+
return ptr;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function takeFromExternrefTable0(idx) {
|
|
69
|
+
const value = wasm.__wbindgen_externrefs.get(idx);
|
|
70
|
+
wasm.__externref_table_dealloc(idx);
|
|
71
|
+
return value;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
75
|
+
cachedTextDecoder.decode();
|
|
76
|
+
const MAX_SAFARI_DECODE_BYTES = 2146435072;
|
|
77
|
+
let numBytesDecoded = 0;
|
|
78
|
+
function decodeText(ptr, len) {
|
|
79
|
+
numBytesDecoded += len;
|
|
80
|
+
if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
|
|
81
|
+
cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
82
|
+
cachedTextDecoder.decode();
|
|
83
|
+
numBytesDecoded = len;
|
|
84
|
+
}
|
|
85
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let WASM_VECTOR_LEN = 0;
|
|
89
|
+
|
|
90
|
+
let wasmModule, wasm;
|
|
91
|
+
function __wbg_finalize_init(instance, module) {
|
|
92
|
+
wasm = instance.exports;
|
|
93
|
+
wasmModule = module;
|
|
94
|
+
cachedUint8ArrayMemory0 = null;
|
|
95
|
+
wasm.__wbindgen_start();
|
|
96
|
+
return wasm;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function __wbg_load(module, imports) {
|
|
100
|
+
if (typeof Response === 'function' && module instanceof Response) {
|
|
101
|
+
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
|
102
|
+
try {
|
|
103
|
+
return await WebAssembly.instantiateStreaming(module, imports);
|
|
104
|
+
} catch (e) {
|
|
105
|
+
const validResponse = module.ok && expectedResponseType(module.type);
|
|
106
|
+
|
|
107
|
+
if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
|
|
108
|
+
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
|
|
109
|
+
|
|
110
|
+
} else { throw e; }
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const bytes = await module.arrayBuffer();
|
|
115
|
+
return await WebAssembly.instantiate(bytes, imports);
|
|
116
|
+
} else {
|
|
117
|
+
const instance = await WebAssembly.instantiate(module, imports);
|
|
118
|
+
|
|
119
|
+
if (instance instanceof WebAssembly.Instance) {
|
|
120
|
+
return { instance, module };
|
|
121
|
+
} else {
|
|
122
|
+
return instance;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function expectedResponseType(type) {
|
|
127
|
+
switch (type) {
|
|
128
|
+
case 'basic': case 'cors': case 'default': return true;
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function initSync(module) {
|
|
135
|
+
if (wasm !== undefined) return wasm;
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
if (module !== undefined) {
|
|
139
|
+
if (Object.getPrototypeOf(module) === Object.prototype) {
|
|
140
|
+
({module} = module)
|
|
141
|
+
} else {
|
|
142
|
+
console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const imports = __wbg_get_imports();
|
|
147
|
+
if (!(module instanceof WebAssembly.Module)) {
|
|
148
|
+
module = new WebAssembly.Module(module);
|
|
149
|
+
}
|
|
150
|
+
const instance = new WebAssembly.Instance(module, imports);
|
|
151
|
+
return __wbg_finalize_init(instance, module);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function __wbg_init(module_or_path) {
|
|
155
|
+
if (wasm !== undefined) return wasm;
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
if (module_or_path !== undefined) {
|
|
159
|
+
if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
|
|
160
|
+
({module_or_path} = module_or_path)
|
|
161
|
+
} else {
|
|
162
|
+
console.warn('using deprecated parameters for the initialization function; pass a single object instead')
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (module_or_path === undefined) {
|
|
167
|
+
module_or_path = new URL('cpace_wasm_bg.wasm', import.meta.url);
|
|
168
|
+
}
|
|
169
|
+
const imports = __wbg_get_imports();
|
|
170
|
+
|
|
171
|
+
if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
|
|
172
|
+
module_or_path = fetch(module_or_path);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const { instance, module } = await __wbg_load(await module_or_path, imports);
|
|
176
|
+
|
|
177
|
+
return __wbg_finalize_init(instance, module);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export { initSync, __wbg_init as default };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {Uint8Array} rep
|
|
3
|
+
* @returns {Uint8Array}
|
|
4
|
+
*/
|
|
5
|
+
export function elligator2_curve25519_u(rep) {
|
|
6
|
+
const ptr0 = passArray8ToWasm0(rep, wasm.__wbindgen_malloc);
|
|
7
|
+
const len0 = WASM_VECTOR_LEN;
|
|
8
|
+
const ret = wasm.elligator2_curve25519_u(ptr0, len0);
|
|
9
|
+
if (ret[3]) {
|
|
10
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
11
|
+
}
|
|
12
|
+
var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
13
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
14
|
+
return v2;
|
|
15
|
+
}
|
|
16
|
+
export function __wbindgen_cast_0000000000000001(arg0, arg1) {
|
|
17
|
+
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
18
|
+
const ret = getStringFromWasm0(arg0, arg1);
|
|
19
|
+
return ret;
|
|
20
|
+
}
|
|
21
|
+
export function __wbindgen_init_externref_table() {
|
|
22
|
+
const table = wasm.__wbindgen_externrefs;
|
|
23
|
+
const offset = table.grow(4);
|
|
24
|
+
table.set(0, undefined);
|
|
25
|
+
table.set(offset + 0, undefined);
|
|
26
|
+
table.set(offset + 1, null);
|
|
27
|
+
table.set(offset + 2, true);
|
|
28
|
+
table.set(offset + 3, false);
|
|
29
|
+
}
|
|
30
|
+
function getArrayU8FromWasm0(ptr, len) {
|
|
31
|
+
ptr = ptr >>> 0;
|
|
32
|
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function getStringFromWasm0(ptr, len) {
|
|
36
|
+
ptr = ptr >>> 0;
|
|
37
|
+
return decodeText(ptr, len);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let cachedUint8ArrayMemory0 = null;
|
|
41
|
+
function getUint8ArrayMemory0() {
|
|
42
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
43
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
44
|
+
}
|
|
45
|
+
return cachedUint8ArrayMemory0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function passArray8ToWasm0(arg, malloc) {
|
|
49
|
+
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
50
|
+
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
51
|
+
WASM_VECTOR_LEN = arg.length;
|
|
52
|
+
return ptr;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function takeFromExternrefTable0(idx) {
|
|
56
|
+
const value = wasm.__wbindgen_externrefs.get(idx);
|
|
57
|
+
wasm.__externref_table_dealloc(idx);
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
62
|
+
cachedTextDecoder.decode();
|
|
63
|
+
const MAX_SAFARI_DECODE_BYTES = 2146435072;
|
|
64
|
+
let numBytesDecoded = 0;
|
|
65
|
+
function decodeText(ptr, len) {
|
|
66
|
+
numBytesDecoded += len;
|
|
67
|
+
if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
|
|
68
|
+
cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
69
|
+
cachedTextDecoder.decode();
|
|
70
|
+
numBytesDecoded = len;
|
|
71
|
+
}
|
|
72
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let WASM_VECTOR_LEN = 0;
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
let wasm;
|
|
79
|
+
export function __wbg_set_wasm(val) {
|
|
80
|
+
wasm = val;
|
|
81
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
export const memory: WebAssembly.Memory;
|
|
4
|
+
export const elligator2_curve25519_u: (a: number, b: number) => [number, number, number, number];
|
|
5
|
+
export const __wbindgen_externrefs: WebAssembly.Table;
|
|
6
|
+
export const __wbindgen_malloc: (a: number, b: number) => number;
|
|
7
|
+
export const __externref_table_dealloc: (a: number) => void;
|
|
8
|
+
export const __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
9
|
+
export const __wbindgen_start: () => void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cpace-wasm",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"files": [
|
|
6
|
+
"cpace_wasm_bg.wasm",
|
|
7
|
+
"cpace_wasm.js",
|
|
8
|
+
"cpace_wasm.d.ts"
|
|
9
|
+
],
|
|
10
|
+
"main": "cpace_wasm.js",
|
|
11
|
+
"types": "cpace_wasm.d.ts",
|
|
12
|
+
"sideEffects": [
|
|
13
|
+
"./snippets/*"
|
|
14
|
+
]
|
|
15
|
+
}
|