P256.t.sol 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.20;
  3. import {Test} from "forge-std/Test.sol";
  4. import {P256} from "@openzeppelin/contracts/utils/cryptography/P256.sol";
  5. import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
  6. contract P256Test is Test {
  7. /// forge-config: default.fuzz.runs = 512
  8. function testVerify(bytes32 digest, uint256 seed) public view {
  9. uint256 privateKey = _asPrivateKey(seed);
  10. (uint256 x, uint256 y) = vm.publicKeyP256(privateKey);
  11. (bytes32 r, bytes32 s) = vm.signP256(privateKey, digest);
  12. s = _ensureLowerS(s);
  13. assertTrue(P256.verify(digest, r, s, bytes32(x), bytes32(y)));
  14. assertTrue(P256.verifySolidity(digest, r, s, bytes32(x), bytes32(y)));
  15. }
  16. /// forge-config: default.fuzz.runs = 512
  17. function testRecover(bytes32 digest, uint256 seed) public view {
  18. uint256 privateKey = _asPrivateKey(seed);
  19. (uint256 x, uint256 y) = vm.publicKeyP256(privateKey);
  20. (bytes32 r, bytes32 s) = vm.signP256(privateKey, digest);
  21. s = _ensureLowerS(s);
  22. (bytes32 qx0, bytes32 qy0) = P256.recovery(digest, 0, r, s);
  23. (bytes32 qx1, bytes32 qy1) = P256.recovery(digest, 1, r, s);
  24. assertTrue((qx0 == bytes32(x) && qy0 == bytes32(y)) || (qx1 == bytes32(x) && qy1 == bytes32(y)));
  25. }
  26. function _asPrivateKey(uint256 seed) private pure returns (uint256) {
  27. return bound(seed, 1, P256.N - 1);
  28. }
  29. function _ensureLowerS(bytes32 s) private pure returns (bytes32) {
  30. uint256 _s = uint256(s);
  31. unchecked {
  32. return _s > P256.N / 2 ? bytes32(P256.N - _s) : s;
  33. }
  34. }
  35. }