From: Chris Duncan Date: Thu, 13 Aug 2026 04:27:52 +0000 (-0700) Subject: Use type guard to enable direct use of typechecked output buffer. X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=86e01f1831b929af74be98c896f0085e47222944;p=nano25519.git Use type guard to enable direct use of typechecked output buffer. --- diff --git a/src/lib/nano25519.ts b/src/lib/nano25519.ts index 4d86043..61fa85f 100644 --- a/src/lib/nano25519.ts +++ b/src/lib/nano25519.ts @@ -72,7 +72,7 @@ const nano25519_init = (bytes: number[]): { derive: typeof derive, sign: typeof let buffer = new DataView(exports.memory.buffer) try { out ??= new Uint8Array(32) - if (!(out instanceof Uint8Array && out.buffer instanceof ArrayBuffer && out.byteLength === 32)) { + if (!(isBytes(out) && out.byteLength === 32)) { throw new TypeError('Derive output buffer must be 32-byte Uint8Array') } privateKey.set(normalize('private key', 32, 32, k)) @@ -83,20 +83,19 @@ const nano25519_init = (bytes: number[]): { derive: typeof derive, sign: typeof privateKey.fill(0) exports.derive() const outPtr = exports.getOutputPointer() - const publicKey = new Uint8Array(out.buffer) buffer = new DataView(exports.memory.buffer) for (let i = 0; i < 32; i++) { - publicKey[i] = buffer.getUint8(outPtr + i + 32) + out[i] = buffer.getUint8(outPtr + i + 32) } clear(buffer) if (typeof k === 'string') { let hex = '' - for (const byte of publicKey) { + for (const byte of out) { hex += byte.toString(16).padStart(2, '0') } return hex } else { - return publicKey + return out } } finally { privateKey.fill(0) @@ -120,18 +119,17 @@ const nano25519_init = (bytes: number[]): { derive: typeof derive, sign: typeof exports.sign(message.byteLength) const outPtr = exports.getOutputPointer() s ??= new Uint8Array(64) - if (!(s instanceof Uint8Array && s.buffer instanceof ArrayBuffer && s.byteLength === 64)) { + if (!(isBytes(s) && s.byteLength === 64)) { throw new TypeError('Sign output buffer must be 64-byte Uint8Array') } - const signature = new Uint8Array(s.buffer) buffer = new DataView(exports.memory.buffer) for (let i = 0; i < 64; i++) { - signature[i] = buffer.getUint8(outPtr + i) + s[i] = buffer.getUint8(outPtr + i) } clear(buffer) return typeof k === 'string' - ? [...signature].map(b => b.toString(16).padStart(2, '0')).join('') - : signature + ? [...s].map(b => b.toString(16).padStart(2, '0')).join('') + : s } function verify (s: unknown, m: unknown, k: unknown): boolean { @@ -169,6 +167,10 @@ const nano25519_init = (bytes: number[]): { derive: typeof derive, sign: typeof } } + function isBytes (a: unknown): a is Uint8Array { + return a instanceof Uint8Array && a.buffer instanceof ArrayBuffer + } + function normalize (name: string, byteLengthMin: number, byteLengthMax: number, value: unknown): Uint8Array { if (typeof name !== 'string') { throw new TypeError(`Invalid name ${name}`)