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
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
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
+}