From 9d86438c49a5ce87e0984d745d5ac88b08ac0568 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Thu, 1 Oct 2026 14:37:31 -0700 Subject: [PATCH] Extract signature check for multiple verification call sites. --- src/assembly/crypto_verify.ts | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/assembly/crypto_verify.ts b/src/assembly/crypto_verify.ts index 6540c5c..f03cbde 100644 --- a/src/assembly/crypto_verify.ts +++ b/src/assembly/crypto_verify.ts @@ -74,12 +74,7 @@ export function crypto_verify_sodium (sig: StaticArray, M: StaticArray, if (!verify_pubkey(pub)) return 0 - // fail if private scalar `S` is non-canonical (`L ≤ S`) - memory.copy(changetype(S), changetype(sig) + 32, 32) - if (!sc_is_canonical(S)) return 0 - - if (ge_frombytes(expected_r, sig) != 0) return 0 - if (ge_has_small_order(expected_r) != 0) return 0 + if (!verify_signature(sig)) return 0 // signature is nonce point R and scalar S (R || S) // data to hash is nonce point R, public key A, and message M @@ -107,12 +102,7 @@ export function crypto_verify_strict (sig: StaticArray, M: StaticArray, if (!verify_pubkey(pub)) return 0 - // fail if scalar `S` is non-canonical (`L ≤ S`) - memory.copy(changetype(S), changetype(sig) + 32, 32) - if (!sc_is_canonical(S)) return 0 - - if (ge_frombytes(expected_r, sig) != 0) return 0 - if (ge_has_small_order(expected_r) != 0) return 0 + if (!verify_signature(sig)) return 0 // signature is nonce point R and scalar S (R || S) // data to hash is nonce point R, public key A, and message M @@ -146,3 +136,20 @@ function verify_pubkey (pub: StaticArray): boolean { return true } + +/** + * Verify signature `s` is canonical, decodeable, and not small order. Used by + * `crypto_verify_sodium` and `crypto_verify_strict`. + * @returns 0 if signature fails checks, else return 1 if signature is good + */ +function verify_signature (sig: StaticArray): boolean { + // fail if scalar `S` is non-canonical (`L ≤ S`) + memory.copy(changetype(S), changetype(sig) + 32, 32) + if (!sc_is_canonical(S)) return false + + // fail if nonce `R` is not a valid point on the curve + if (ge_frombytes(expected_r, sig) != 0) return false + if (ge_has_small_order(expected_r) != 0) return false + + return true +} -- 2.52.0