]> git.codecow.com Git - nano25519.git/commitdiff
Rename NaCl input constants. Fix parameters and argument parsing for derive and verif...
authorChris Duncan <chris@zoso.dev>
Sun, 15 Feb 2026 22:41:57 +0000 (14:41 -0800)
committerChris Duncan <chris@zoso.dev>
Sun, 15 Feb 2026 22:41:57 +0000 (14:41 -0800)
assembly/nano-nacl.ts

index c0245e986dbe5bca80b83a3a0cb619732cfe6552..f7691ef9b5050c1d4aaa45298c8ee76d3d8b9a90 100644 (file)
@@ -182,10 +182,10 @@ class Blake2b {
        }\r
 }\r
 \r
-const crypto_sign_BYTES: u8 = 64\r
-const crypto_sign_PUBLICKEYBYTES: u8 = 32\r
-const crypto_sign_PRIVATEKEYBYTES: u8 = 32\r
-const crypto_sign_SEEDBYTES: u8 = 32\r
+const BLOCKHASH_BYTES: u8 = 32\r
+const PRIVATEKEY_BYTES: u8 = 32\r
+const PUBLICKEY_BYTES: u8 = 32\r
+const SIGNATURE_BYTES: u8 = 64\r
 const D: Int64Array = new Int64Array(16); D.set([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203])\r
 const D2: Int64Array = new Int64Array(16); D2.set([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406])\r
 const X: Int64Array = new Int64Array(16); X.set([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169])\r
@@ -621,33 +621,36 @@ function crypto_sign_open (m: Uint8Array, sm: Uint8Array, n: i32, pk: Uint8Array
 }\r
 \r
 /**\r
-* Derives a public key from a private key "seed".\r
+* Derives a Nano public key from a private key. This mirrors the functionality\r
+* of `nacl.sign.keyPair.fromSeed()`, returning just the `publicKey` property.\r
 *\r
-* @param {Uint8Array} seed - 32-byte private key\r
+* @param {Uint8Array} privateKey - 32-byte private key\r
 * @returns {Uint8Array} 32-byte public key\r
 */\r
-export function derive (seed: Uint8Array): Uint8Array {\r
-       if (seed.length !== crypto_sign_SEEDBYTES) {\r
-               const err = `Invalid private key byte length to convert to public key, expected ${crypto_sign_SEEDBYTES}, actual ${seed.byteLength}`\r
-               trace(err, 1, seed.byteLength)\r
+export function derive (k0: u64, k1: u64, k2: u64, k3: u64): Uint8Array {\r
+       const k = new Uint64Array(4); k.set([k0, k1, k2, k3])\r
+       const privateKey = Uint8Array.wrap(k.buffer)\r
+       if (privateKey.byteLength !== PRIVATEKEY_BYTES) {\r
+               const err = `Invalid private key byte length to convert to public key, expected ${PRIVATEKEY_BYTES}, actual ${privateKey.byteLength}`\r
+               trace(err, 1, privateKey.byteLength)\r
                throw new Error(err)\r
        }\r
-       const pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES)\r
+       const publicKey = new Uint8Array(PUBLICKEY_BYTES)\r
        const p: Int64Array[] = [new Int64Array(16), new Int64Array(16), new Int64Array(16), new Int64Array(16)]\r
 \r
-       const h: Uint8Array = new Blake2b(64).update(seed).digest()\r
+       const h: Uint8Array = new Blake2b(64).update(privateKey).digest()\r
        h[0] &= 248\r
        h[31] &= 127\r
        h[31] |= 64\r
 \r
        scalarbase(p, h)\r
-       pack(pk, p)\r
+       pack(publicKey, p)\r
 \r
-       return pk\r
+       return publicKey\r
 }\r
 \r
 /**\r
-* Signs the message using the secret key and returns a signature.\r
+* Signs the message using the private key and returns a signature.\r
 *\r
 * @param {Uint8Array} message - Message to sign\r
 * @param {Uint8Array} privateKey - 32-byte key to use for signing\r
@@ -658,15 +661,15 @@ export function sign (h0: u64, h1: u64, h2: u64, h3: u64, k0: u64, k1: u64, k2:
        const k = new Uint64Array(4); k.set([k0, k1, k2, k3])\r
        const message = Uint8Array.wrap(h.buffer)\r
        const privateKey = Uint8Array.wrap(k.buffer)\r
-       if (privateKey.byteLength !== crypto_sign_PRIVATEKEYBYTES) {\r
-               const err = `Invalid key byte length to sign message, expected ${crypto_sign_PRIVATEKEYBYTES}, actual ${privateKey.byteLength}`\r
+       if (privateKey.byteLength !== PRIVATEKEY_BYTES) {\r
+               const err = `Invalid key byte length to sign message, expected ${PRIVATEKEY_BYTES}, actual ${privateKey.byteLength}`\r
                trace(err, 1, privateKey.byteLength)\r
                throw new Error(err)\r
        }\r
-       const signed = new Uint8Array(crypto_sign_BYTES + message.length)\r
-       const publicKey = derive(privateKey)\r
+       const signed = new Uint8Array(SIGNATURE_BYTES + message.length)\r
+       const publicKey = derive(k0, k1, k2, k3)\r
        crypto_sign(signed, message, message.length, privateKey, publicKey)\r
-       const sig = new Uint8Array(crypto_sign_BYTES)\r
+       const sig = new Uint8Array(SIGNATURE_BYTES)\r
        for (let i = 0; i < sig.length; i++) {\r
                sig[i] = signed[i]\r
        }\r
@@ -674,27 +677,38 @@ export function sign (h0: u64, h1: u64, h2: u64, h3: u64, k0: u64, k1: u64, k2:
 }\r
 \r
 /**\r
-* Verifies a detached signature for a message.\r
+* Verifies a signature on a blockhash against a public key.\r
 *\r
-* @param {Uint8Array} message - Signed message\r
+* @param {Uint8Array} blockhash - 32-byte hash of signed Nano block\r
 * @param {Uint8Array} signature - 64-byte signature\r
 * @param {Uint8Array} publicKey - 32-byte key used for signing\r
-* @returns {boolean} - True if `publicKey` was used to sign `msg` and generate `sig`, else false\r
+* @returns {boolean} - True if `publicKey` was used to sign `blockhash` and generate `signature`, else false\r
 */\r
-export function verify (message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean {\r
-       if (signature.byteLength !== crypto_sign_BYTES) {\r
-               const err = `Invalid signature size to verify signature, expected ${crypto_sign_BYTES}, actual ${signature.byteLength}`\r
+export function verify (h0: u64, h1: u64, h2: u64, h3: u64, s0: u64, s1: u64, s2: u64, s3: u64, s4: u64, s5: u64, s6: u64, s7: u64, k0: u64, k1: u64, k2: u64, k3: u64): boolean {\r
+       const h = new Uint64Array(4); h.set([h0, h1, h2, h3])\r
+       const s = new Uint64Array(8); s.set([s0, s1, s2, s3, s4, s5, s6, s7])\r
+       const k = new Uint64Array(4); k.set([k0, k1, k2, k3])\r
+       const blockhash = Uint8Array.wrap(h.buffer)\r
+       const signature = Uint8Array.wrap(s.buffer)\r
+       const publicKey = Uint8Array.wrap(k.buffer)\r
+       if (blockhash.byteLength !== BLOCKHASH_BYTES) {\r
+               const err = `Invalid blockhash size to verify signature, expected ${BLOCKHASH_BYTES}, actual ${blockhash.byteLength}`\r
+               trace(err, 1, blockhash.byteLength)\r
+               throw new Error(err)\r
+       }\r
+       if (signature.byteLength !== SIGNATURE_BYTES) {\r
+               const err = `Invalid signature size to verify signature, expected ${SIGNATURE_BYTES}, actual ${signature.byteLength}`\r
                trace(err, 1, signature.byteLength)\r
                throw new Error(err)\r
        }\r
-       if (publicKey.byteLength !== crypto_sign_PUBLICKEYBYTES) {\r
-               const err = `Invalid public key size to verify signature, expected ${crypto_sign_PUBLICKEYBYTES}, actual ${publicKey.byteLength}`\r
+       if (publicKey.byteLength !== PUBLICKEY_BYTES) {\r
+               const err = `Invalid public key size to verify signature, expected ${PUBLICKEY_BYTES}, actual ${publicKey.byteLength}`\r
                trace(err, 1, signature.byteLength)\r
                throw new Error(err)\r
        }\r
-       const sm = new Uint8Array(crypto_sign_BYTES + message.length)\r
-       const m = new Uint8Array(crypto_sign_BYTES + message.length)\r
+       const sm = new Uint8Array(SIGNATURE_BYTES + blockhash.length)\r
+       const m = new Uint8Array(SIGNATURE_BYTES + blockhash.length)\r
        sm.set(signature, 0)\r
-       sm.set(message, crypto_sign_BYTES)\r
+       sm.set(blockhash, SIGNATURE_BYTES)\r
        return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0)\r
 }\r