From 8f8278fb1474f2d27a769834caa6eef866c0fb01 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Sat, 15 Aug 2026 00:38:09 -0700 Subject: [PATCH] Fix output buffer population. --- src/lib/nano25519.ts | 58 ++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/src/lib/nano25519.ts b/src/lib/nano25519.ts index e876fc8..3d9945e 100644 --- a/src/lib/nano25519.ts +++ b/src/lib/nano25519.ts @@ -67,15 +67,15 @@ export const nano25519_init = (bytes: number[]): { derive: typeof derive, sign: } }) as Exports - function derive (prv: unknown, pub?: unknown): string | Uint8Array | void { - const out = pub ?? new Uint8Array(32) - if (!(isBytes(out) && out.byteLength === 32)) { + function derive (k: unknown, out?: unknown): string | Uint8Array | void { + if (typeof out !== 'undefined' && !(isBytes(out) && out.byteLength === 32)) { throw new TypeError('Derive output buffer must be 32-byte Uint8Array') } - let privateKey = new Uint8Array(32) + const privateKey = new Uint8Array(32) + const publicKey = new Uint8Array(32) let buffer = new DataView(exports.memory.buffer) try { - privateKey.set(normalize('private key', 32, 32, prv)) + privateKey.set(normalize('private key', 32, 32, k)) let inPtr = exports.getInputPointer() for (let i = 0; i < 32; i++) { buffer.setUint8(inPtr + i, privateKey[i]) @@ -84,31 +84,35 @@ export const nano25519_init = (bytes: number[]): { derive: typeof derive, sign: const outPtr = exports.getOutputPointer() buffer = new DataView(exports.memory.buffer) for (let i = 0; i < 32; i++) { - out[i] = buffer.getUint8(outPtr + i) + publicKey[i] = buffer.getUint8(outPtr + i) } - if (typeof pub === 'undefined') { - return - } else if (typeof prv === 'string') { + if (typeof k === 'string') { let hex = '' - for (const byte of out) { + for (const byte of publicKey) { hex += byte.toString(16).padStart(2, '0') } return hex + } else if (isBytes(k) && out != null) { + for (let i = 0; i < 32; i++) { + out[i] = publicKey[i] + } + return } else { - return out + return publicKey } } finally { - privateKey.fill(0) clear(buffer) + privateKey.fill(0) + publicKey.fill(0) } } - function sign (m: unknown, k: unknown, s?: unknown): string | Uint8Array { - s ??= new Uint8Array(64) - if (!(isBytes(s) && s.byteLength === 64)) { + function sign (m: unknown, k: unknown, s?: unknown): string | Uint8Array | void { + if (typeof s !== 'undefined' && !(isBytes(s) && s.byteLength === 64)) { throw new TypeError('Sign output buffer must be 64-byte Uint8Array') } - let secretKey = new Uint8Array(64) + const secretKey = new Uint8Array(64) + const signature = new Uint8Array(64) let buffer: DataView | undefined = new DataView(exports.memory.buffer) try { secretKey.set(normalize('secret key', 64, 64, k)) @@ -125,14 +129,26 @@ export const nano25519_init = (bytes: number[]): { derive: typeof derive, sign: const outPtr = exports.getOutputPointer() buffer = new DataView(exports.memory.buffer) for (let i = 0; i < 64; i++) { - s[i] = buffer.getUint8(outPtr + i) + signature[i] = buffer.getUint8(outPtr + i) + } + if (typeof k === 'string') { + let hex = '' + for (const byte of signature) { + hex += byte.toString(16).padStart(2, '0') + } + return hex + } else if (isBytes(k) && s != null) { + for (let i = 0; i < 32; i++) { + s[i] = signature[i] + } + return + } else { + return signature } - return typeof k === 'string' - ? [...s].map(b => b.toString(16).padStart(2, '0')).join('') - : s } finally { - secretKey.fill(0) clear(buffer) + secretKey.fill(0) + signature.fill(0) } } -- 2.52.0