-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* improve usage code * review comment rename
- Loading branch information
1 parent
402e7b4
commit 024caa5
Showing
5 changed files
with
137 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.21; | ||
|
||
/** | ||
* Helper library for external contracts to verify P256 signatures. | ||
**/ | ||
library P256 { | ||
address constant VERIFIER = 0xc2b78104907F722DABAc4C69f826a522B2754De4; | ||
|
||
function verifySignatureAllowMalleability( | ||
bytes32 message_hash, | ||
uint256 r, | ||
uint256 s, | ||
uint256 x, | ||
uint256 y | ||
) public view returns (bool) { | ||
bytes memory args = abi.encode(message_hash, r, s, x, y); | ||
(bool success, bytes memory ret) = VERIFIER.staticcall(args); | ||
assert(success); // never reverts, always returns 0 or 1 | ||
|
||
return abi.decode(ret, (uint256)) == 1; | ||
} | ||
|
||
/// P256 curve order n/2 for malleability check | ||
uint256 constant P256_N_DIV_2 = | ||
57896044605178124381348723474703786764998477612067880171211129530534256022184; | ||
|
||
function verifySignature( | ||
bytes32 message_hash, | ||
uint256 r, | ||
uint256 s, | ||
uint256 x, | ||
uint256 y | ||
) public view returns (bool) { | ||
// check for signature malleability | ||
if (s > P256_N_DIV_2) { | ||
return false; | ||
} | ||
|
||
return verifySignatureAllowMalleability(message_hash, r, s, x, y); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.21; | ||
|
||
import {Test, console2} from "forge-std/Test.sol"; | ||
import {stdJson} from "forge-std/StdJson.sol"; | ||
import {P256} from "../src/P256.sol"; | ||
import {P256Verifier} from "../src/P256Verifier.sol"; | ||
|
||
contract P256Test is Test { | ||
uint256[2] public pubKey; | ||
|
||
function setUp() public { | ||
pubKey = [ | ||
0x65a2fa44daad46eab0278703edb6c4dcf5e30b8a9aec09fdc71a56f52aa392e4, | ||
0x4a7a9e4604aa36898209997288e902ac544a555e4b5e0a9efef2b59233f3f437 | ||
]; | ||
} | ||
|
||
function testMalleable() public { | ||
// Malleable signature. s is > n/2 | ||
uint256 r = 0x01655c1753db6b61a9717e4ccc5d6c4bf7681623dd54c2d6babc55125756661c; | ||
uint256 s = 0xf073023b6de130f18510af41f64f067c39adccd59f8789a55dbbe822b0ea2317; | ||
|
||
bytes32 hash = 0x267f9ea080b54bbea2443dff8aa543604564329783b6a515c6663a691c555490; | ||
|
||
bool res = P256.verifySignatureAllowMalleability( | ||
hash, | ||
r, | ||
s, | ||
pubKey[0], | ||
pubKey[1] | ||
); | ||
assertEq(res, true); | ||
|
||
res = P256.verifySignature(hash, r, s, pubKey[0], pubKey[1]); | ||
assertEq(res, false); | ||
} | ||
|
||
function testNonMalleable() public { | ||
// Non-malleable signature. s is <= n/2 | ||
uint256 r = 0x01655c1753db6b61a9717e4ccc5d6c4bf7681623dd54c2d6babc55125756661c; | ||
uint256 s = 7033802732221576339889804108463427183539365869906989872244893535944704590394; | ||
|
||
bytes32 hash = 0x267f9ea080b54bbea2443dff8aa543604564329783b6a515c6663a691c555490; | ||
|
||
bool res = P256.verifySignatureAllowMalleability( | ||
hash, | ||
r, | ||
s, | ||
pubKey[0], | ||
pubKey[1] | ||
); | ||
assertEq(res, true); | ||
|
||
res = P256.verifySignature(hash, r, s, pubKey[0], pubKey[1]); | ||
assertEq(res, true); | ||
} | ||
} |