]> git.codecow.com Git - nano25519.git/commitdiff
Extract signature check for multiple verification call sites.
authorChris Duncan <chris@codecow.com>
Thu, 1 Oct 2026 21:37:31 +0000 (14:37 -0700)
committerChris Duncan <chris@codecow.com>
Thu, 1 Oct 2026 21:37:31 +0000 (14:37 -0700)
src/assembly/crypto_verify.ts

index 6540c5c106156d69e9924ab73208338266a586b7..f03cbde0195bf777cf740f33970f184dd7c35e8a 100644 (file)
@@ -74,12 +74,7 @@ export function crypto_verify_sodium (sig: StaticArray<u8>, M: StaticArray<u8>,
 
        if (!verify_pubkey(pub)) return 0
 
-       // fail if private scalar `S` is non-canonical (`L ≤ S`)
-       memory.copy(changetype<usize>(S), changetype<usize>(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<u8>, M: StaticArray<u8>,
 
        if (!verify_pubkey(pub)) return 0
 
-       // fail if scalar `S` is non-canonical (`L ≤ S`)
-       memory.copy(changetype<usize>(S), changetype<usize>(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<u8>): 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<u8>): boolean {
+       // fail if scalar `S` is non-canonical (`L ≤ S`)
+       memory.copy(changetype<usize>(S), changetype<usize>(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
+}