]> git.codecow.com Git - nano25519.git/commitdiff
Use type guard to enable direct use of typechecked output buffer.
authorChris Duncan <chris@zoso.dev>
Thu, 13 Aug 2026 04:27:52 +0000 (21:27 -0700)
committerChris Duncan <chris@zoso.dev>
Thu, 13 Aug 2026 04:27:52 +0000 (21:27 -0700)
src/lib/nano25519.ts

index 4d86043aa7ee8a8ac88e3267ac1e2e35a2494883..61fa85fdd6e97e3e125625563590712704465940 100644 (file)
@@ -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<ArrayBuffer>')
                        }
                        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<ArrayBuffer>')
                }
-               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<ArrayBuffer> {
+               return a instanceof Uint8Array && a.buffer instanceof ArrayBuffer
+       }
+
        function normalize (name: string, byteLengthMin: number, byteLengthMax: number, value: unknown): Uint8Array<ArrayBuffer> {
                if (typeof name !== 'string') {
                        throw new TypeError(`Invalid name ${name}`)