123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- // SPDX-License-Identifier: MIT
- pragma solidity ^0.8.20;
- import {Test} from "forge-std/Test.sol";
- import {P256} from "@openzeppelin/contracts/utils/cryptography/P256.sol";
- import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
- import {Errors} from "@openzeppelin/contracts/utils/Errors.sol";
- contract P256Test is Test {
- /// forge-config: default.fuzz.runs = 512
- function testVerify(bytes32 digest, uint256 seed) public view {
- uint256 privateKey = _asPrivateKey(seed);
- (uint256 x, uint256 y) = vm.publicKeyP256(privateKey);
- (bytes32 r, bytes32 s) = vm.signP256(privateKey, digest);
- s = _ensureLowerS(s);
- assertTrue(P256.verify(digest, r, s, bytes32(x), bytes32(y)));
- assertTrue(P256.verifySolidity(digest, r, s, bytes32(x), bytes32(y)));
- }
- /// forge-config: default.fuzz.runs = 512
- function testRecover(bytes32 digest, uint256 seed) public view {
- uint256 privateKey = _asPrivateKey(seed);
- (uint256 x, uint256 y) = vm.publicKeyP256(privateKey);
- (bytes32 r, bytes32 s) = vm.signP256(privateKey, digest);
- s = _ensureLowerS(s);
- (bytes32 qx0, bytes32 qy0) = P256.recovery(digest, 0, r, s);
- (bytes32 qx1, bytes32 qy1) = P256.recovery(digest, 1, r, s);
- assertTrue((qx0 == bytes32(x) && qy0 == bytes32(y)) || (qx1 == bytes32(x) && qy1 == bytes32(y)));
- }
- function testVerifyNativeUnsupportedRIP7212(bytes32 digest, uint256 seed) public {
- // By default, the precompile at address 0x100 is not supported.
- uint256 privateKey = _asPrivateKey(seed);
- (uint256 x, uint256 y) = vm.publicKeyP256(privateKey);
- (bytes32 r, bytes32 s) = vm.signP256(privateKey, digest);
- s = _ensureLowerS(s);
- (bool success, bytes memory returndata) = address(this).call(
- abi.encodeCall(P256Test.verifyNative, (digest, r, s, bytes32(x), bytes32(y)))
- );
- assertFalse(success);
- assertEq(returndata, abi.encodeWithSelector(Errors.MissingPrecompile.selector, address(0x100)));
- }
- function _asPrivateKey(uint256 seed) private pure returns (uint256) {
- return bound(seed, 1, P256.N - 1);
- }
- function _ensureLowerS(bytes32 s) private pure returns (bytes32) {
- uint256 _s = uint256(s);
- unchecked {
- return _s > P256.N / 2 ? bytes32(P256.N - _s) : s;
- }
- }
- // See https://github.com/foundry-rs/foundry/issues/10237
- function verifyNative(bytes32 digest, bytes32 r, bytes32 s, bytes32 x, bytes32 y) external view {
- P256.verifyNative(digest, r, s, x, y);
- }
- }
|