@@ -248,6 +248,32 @@ contract P256Test is P256VerifierEtcher {
248248 assertEq (xDecoded, x);
249249 assertEq (yDecoded, y);
250250 }
251+
252+ function check_P256Normalized (uint256 s ) public pure {
253+ uint256 n = uint256 (P256.N);
254+ unchecked {
255+ uint256 expected = s > (n / 2 ) ? n - s : s;
256+ assert (uint256 (P256.normalized (bytes32 (s))) == expected);
257+ }
258+ }
259+
260+ function testP256Normalized (uint256 privateKey , bytes32 hash ) public {
261+ while (privateKey == 0 || privateKey >= P256.N) {
262+ privateKey = uint256 (keccak256 (abi.encode (privateKey)));
263+ }
264+ (uint256 x , uint256 y ) = vm.publicKeyP256 (privateKey);
265+
266+ // Note that `vm.signP256` can produce `s` above `N / 2`.
267+ (bytes32 r , bytes32 s ) = vm.signP256 (privateKey, hash);
268+
269+ if (uint256 (s) > P256.N / 2 ) {
270+ assertFalse (P256.verifySignature (hash, r, s, bytes32 (x), bytes32 (y)));
271+ assertTrue (P256.verifySignature (hash, r, P256.normalized (s), bytes32 (x), bytes32 (y)));
272+ } else {
273+ assertTrue (P256.verifySignature (hash, r, s, bytes32 (x), bytes32 (y)));
274+ }
275+ assertTrue (P256.verifySignatureAllowMalleability (hash, r, s, bytes32 (x), bytes32 (y)));
276+ }
251277}
252278
253279/// @dev Library to derive P256 public key from private key
0 commit comments