]> git.codecow.com Git - nano25519.git/commitdiff
Fix output buffer population.
authorChris Duncan <chris@zoso.dev>
Sat, 15 Aug 2026 07:38:09 +0000 (00:38 -0700)
committerChris Duncan <chris@zoso.dev>
Sat, 15 Aug 2026 07:38:09 +0000 (00:38 -0700)
src/lib/nano25519.ts

index e876fc81dfce874de0e6a74522d3d29ae3ba4553..3d9945e71e277a106ebe7107b4249eaaff4f90b9 100644 (file)
@@ -67,15 +67,15 @@ export const nano25519_init = (bytes: number[]): { derive: typeof derive, sign:
                }
        }) as Exports
 
-       function derive (prv: unknown, pub?: unknown): string | Uint8Array<ArrayBuffer> | void {
-               const out = pub ?? new Uint8Array(32)
-               if (!(isBytes(out) && out.byteLength === 32)) {
+       function derive (k: unknown, out?: unknown): string | Uint8Array<ArrayBuffer> | void {
+               if (typeof out !== 'undefined' && !(isBytes(out) && out.byteLength === 32)) {
                        throw new TypeError('Derive output buffer must be 32-byte Uint8Array<ArrayBuffer>')
                }
-               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<ArrayBuffer> {
-               s ??= new Uint8Array(64)
-               if (!(isBytes(s) && s.byteLength === 64)) {
+       function sign (m: unknown, k: unknown, s?: unknown): string | Uint8Array<ArrayBuffer> | void {
+               if (typeof s !== 'undefined' && !(isBytes(s) && s.byteLength === 64)) {
                        throw new TypeError('Sign output buffer must be 64-byte Uint8Array<ArrayBuffer>')
                }
-               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)
                }
        }