mirror of
https://github.com/serai-dex/serai.git
synced 2024-12-23 12:09:37 +00:00
63521f6a96
* start Router contract * use calldata for function args * var name changes * start testing router contract * test with and without abi.encode * cleanup * why tf isn't tests/utils working * cleanup tests * remove unused files * wip * fix router contract and tests, add set/update public keys funcs * impl some Froms * make execute non-reentrant * cleanup * update Router to use ReentrancyGuard * update contract to use errors, use bitfield in Executed event, minor other fixes * wip * fix build issues from merge, tests ok * Router.sol cleanup * cleanup, uncomment stuff * bump ethers.rs version to latest * make contract functions take generic middleware * update build script to assert no compiler errors * hardcode pubkey parity into contract, update tests * Polish coins/ethereum in various ways --------- Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
39 lines
1.2 KiB
Solidity
39 lines
1.2 KiB
Solidity
// SPDX-License-Identifier: AGPLv3
|
|
pragma solidity ^0.8.0;
|
|
|
|
// see https://github.com/noot/schnorr-verify for implementation details
|
|
contract Schnorr {
|
|
// secp256k1 group order
|
|
uint256 constant public Q =
|
|
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
|
|
|
|
error InvalidSOrA();
|
|
error InvalidSignature();
|
|
|
|
// parity := public key y-coord parity (27 or 28)
|
|
// px := public key x-coord
|
|
// message := 32-byte hash of the message
|
|
// c := schnorr signature challenge
|
|
// s := schnorr signature
|
|
function verify(
|
|
uint8 parity,
|
|
bytes32 px,
|
|
bytes32 message,
|
|
bytes32 c,
|
|
bytes32 s
|
|
) public view returns (bool) {
|
|
// ecrecover = (m, v, r, s);
|
|
bytes32 sa = bytes32(Q - mulmod(uint256(s), uint256(px), Q));
|
|
bytes32 ca = bytes32(Q - mulmod(uint256(c), uint256(px), Q));
|
|
|
|
if (sa == 0) revert InvalidSOrA();
|
|
// the ecrecover precompile implementation checks that the `r` and `s`
|
|
// inputs are non-zero (in this case, `px` and `ca`), thus we don't need to
|
|
// check if they're zero.
|
|
address R = ecrecover(sa, parity, px, ca);
|
|
if (R == address(0)) revert InvalidSignature();
|
|
return c == keccak256(
|
|
abi.encodePacked(R, uint8(parity), px, block.chainid, message)
|
|
);
|
|
}
|
|
}
|