From c046707a2ee96dcff048b45ff2a7cba021a961ab Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Thu, 27 Aug 2026 06:53:50 -0700 Subject: [PATCH] Merge local buffers since execution is all synchronous. --- src/assembly/index.ts | 86 ++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/src/assembly/index.ts b/src/assembly/index.ts index cdf6cf5..b1d7f25 100644 --- a/src/assembly/index.ts +++ b/src/assembly/index.ts @@ -48,8 +48,11 @@ export function getSignaturePointer (): usize { return changetype(SIGNATURE_BUFFER) } -const derive_prv = new StaticArray(KEY_BYTELENGTH) -const derive_pub = new StaticArray(KEY_BYTELENGTH) +const h = new StaticArray(BLOCKHASH_BYTELENGTH) +const prv = new StaticArray(KEY_BYTELENGTH) +const pub = new StaticArray(KEY_BYTELENGTH) +const sig = new StaticArray(SIGNATURE_BYTELENGTH) + /** * Derive a 32-byte Nano public key from a 32-byte private key. Parameters are * read as bytes from the input buffer in the following order: @@ -63,27 +66,24 @@ export function derive (): void { OUTPUT_BUFFER.fill(0) // Clear local buffers - derive_prv.fill(0) - derive_pub.fill(0) + prv.fill(0) + pub.fill(0) // Copy input buffer to local parameterss, then clear input buffer - memory.copy(changetype(derive_prv), changetype(PRV_BUFFER), KEY_BYTELENGTH) + memory.copy(changetype(prv), changetype(PRV_BUFFER), KEY_BYTELENGTH) PRV_BUFFER.fill(0) // Derive, then clear local input - crypto_derive(derive_pub, derive_prv) - derive_prv.fill(0) + crypto_derive(pub, prv) + prv.fill(0) // Copy local result to output buffer - memory.copy(changetype(OUTPUT_BUFFER), changetype(derive_pub), KEY_BYTELENGTH) + memory.copy(changetype(OUTPUT_BUFFER), changetype(pub), KEY_BYTELENGTH) // Clear local result - derive_pub.fill(0) + pub.fill(0) } -const sign_prv = new StaticArray(KEY_BYTELENGTH) -const sign_pub = new StaticArray(KEY_BYTELENGTH) -const sign_sig = new StaticArray(SIGNATURE_BYTELENGTH) /** * Sign up to 32 KiB of data using a 64-byte secret key. Parameters are read as * bytes from the input buffer in the following order: @@ -100,9 +100,9 @@ export function sign (mlen: i32): void { OUTPUT_BUFFER.fill(0) // Clear local buffers - sign_prv.fill(0) - sign_pub.fill(0) - sign_sig.fill(0) + prv.fill(0) + pub.fill(0) + sig.fill(0) // Check message length if (mlen < 0 || mlen > MESSAGE_BUFFER_BYTELENGTH) { @@ -113,26 +113,24 @@ export function sign (mlen: i32): void { } // Copy input buffers to local parameters, then clear input buffer - memory.copy(changetype(sign_prv), changetype(PRV_BUFFER), KEY_BYTELENGTH) + memory.copy(changetype(prv), changetype(PRV_BUFFER), KEY_BYTELENGTH) PRV_BUFFER.fill(0) - memory.copy(changetype(sign_pub), changetype(PUB_BUFFER), KEY_BYTELENGTH) + memory.copy(changetype(pub), changetype(PUB_BUFFER), KEY_BYTELENGTH) PUB_BUFFER.fill(0) // Sign message from buffer, then clear local input - crypto_sign(sign_sig, MESSAGE_BUFFER, mlen, sign_prv, sign_pub) - sign_prv.fill(0) - sign_pub.fill(0) + crypto_sign(sig, MESSAGE_BUFFER, mlen, prv, pub) + prv.fill(0) + pub.fill(0) MESSAGE_BUFFER.fill(0) // Copy local result to output buffer - memory.copy(changetype(OUTPUT_BUFFER), changetype(sign_sig), SIGNATURE_BYTELENGTH) + memory.copy(changetype(OUTPUT_BUFFER), changetype(sig), SIGNATURE_BYTELENGTH) // Clear local result - sign_sig.fill(0) + sig.fill(0) } -const verify_pub = new StaticArray(KEY_BYTELENGTH) -const verify_sig = new StaticArray(SIGNATURE_BYTELENGTH) /** * Verify a 64-byte detached signature for a variable-length message against a * 32-byte public key. Input parameters are read as bytes from separate buffers. @@ -144,8 +142,8 @@ export function verify (mlen: i32): void { OUTPUT_BUFFER.fill(255) // Clear local buffers - verify_pub.fill(0) - verify_sig.fill(0) + pub.fill(0) + sig.fill(0) // Check message length if (mlen < 0 || mlen > MESSAGE_BUFFER_BYTELENGTH) { @@ -155,24 +153,20 @@ export function verify (mlen: i32): void { } // Copy input buffer to local parameters, then clear input buffer - memory.copy(changetype(verify_pub), changetype(PUB_BUFFER), KEY_BYTELENGTH) + memory.copy(changetype(pub), changetype(PUB_BUFFER), KEY_BYTELENGTH) PUB_BUFFER.fill(0) - memory.copy(changetype(verify_sig), changetype(SIGNATURE_BUFFER), SIGNATURE_BYTELENGTH) + memory.copy(changetype(sig), changetype(SIGNATURE_BUFFER), SIGNATURE_BYTELENGTH) SIGNATURE_BUFFER.fill(0) // Verify message from buffer, then write result to output buffer - OUTPUT_BUFFER[0] = u8(crypto_verify_strict(verify_sig, MESSAGE_BUFFER, mlen, verify_pub)) + OUTPUT_BUFFER[0] = u8(crypto_verify_strict(sig, MESSAGE_BUFFER, mlen, pub)) // Clear message buffer and input locals MESSAGE_BUFFER.fill(0) - verify_pub.fill(0) - verify_sig.fill(0) + pub.fill(0) + sig.fill(0) } - -const verify_blocks_msg = new StaticArray(BLOCKHASH_BYTELENGTH) -const verify_blocks_pub = new StaticArray(KEY_BYTELENGTH) -const verify_blocks_sig = new StaticArray(SIGNATURE_BYTELENGTH) /** * Verify a 64-byte detached signature for a 32-byte Nano block hash against a * 32-byte public key. Input parameters are read as bytes from separate buffers. @@ -191,9 +185,9 @@ export function verify_blocks (count: i32): void { OUTPUT_BUFFER.fill(255) // Clear local buffers - verify_blocks_msg.fill(0) - verify_blocks_pub.fill(0) - verify_blocks_sig.fill(0) + h.fill(0) + pub.fill(0) + sig.fill(0) // Check number of blocks is valid if (count < 1 || OUTPUT_BUFFER_BYTELENGTH < count) { @@ -203,26 +197,26 @@ export function verify_blocks (count: i32): void { } // Copy public key input buffer to local parameter, then clear input buffer - memory.copy(changetype(verify_blocks_pub), changetype(PUB_BUFFER), KEY_BYTELENGTH) + memory.copy(changetype(pub), changetype(PUB_BUFFER), KEY_BYTELENGTH) PUB_BUFFER.fill(0) // Verify public key before proceeding with signature verification - if (crypto_verify_pubkey(verify_blocks_pub) == 0) { + if (crypto_verify_pubkey(pub) == 0) { // Iterate over block hash/signature pairs for (let i = 0, j = changetype(MESSAGE_BUFFER); i < count; i++, j += 96) { // Copy message buffer to local block hash/signature buffers - memory.copy(changetype(verify_blocks_msg), j, BLOCKHASH_BYTELENGTH) - memory.copy(changetype(verify_blocks_sig), j + BLOCKHASH_BYTELENGTH, SIGNATURE_BYTELENGTH) + memory.copy(changetype(h), j, BLOCKHASH_BYTELENGTH) + memory.copy(changetype(sig), j + BLOCKHASH_BYTELENGTH, SIGNATURE_BYTELENGTH) // Verify hash and signature, then write result to output buffer - OUTPUT_BUFFER[i] = u8(crypto_verify_relaxed(verify_blocks_sig, verify_blocks_msg, BLOCKHASH_BYTELENGTH, verify_blocks_pub)) + OUTPUT_BUFFER[i] = u8(crypto_verify_relaxed(sig, h, BLOCKHASH_BYTELENGTH, pub)) } } // Clear message buffer and input locals MESSAGE_BUFFER.fill(0) - verify_blocks_msg.fill(0) - verify_blocks_pub.fill(0) - verify_blocks_sig.fill(0) + h.fill(0) + pub.fill(0) + sig.fill(0) } -- 2.52.0