Skip to content
Lattice

P256

Git Source

Authors: Solady (https://github.com/vectorized/solady/blob/main/src/utils/P256.sol), Modified from Daimo P256 Verifier (https://github.com/daimo-eth/p256-verifier/blob/master/src/P256.sol), Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/P256.sol)

Gas optimized P256 wrapper.

Constants

VERIFIER

Address of the Solidity P256 verifier. Please make sure the contract is deployed onto the chain you are working on. See: https://gist.github.com/Vectorized/599b0d8a94d21bc74700eb1354e2f55c Unlike RIP-7212, this verifier returns uint256(0) on failure, to facilitate easier existence check. This verifier will also never revert.

address internal constant VERIFIER = 0x000000000000D01eA45F9eFD5c54f037Fa57Ea1a;

CANARY

The existence of this contract, as determined by non-empty bytecode, implies the existence of the RIP-7212 precompile. See: https://gist.github.com/Vectorized/3c69dcf4604b9e1216525cabcd06ee34 This is to enable the optimization to skip the VERIFIER entirely when the RIP_PRECOMPILE returns empty returndata for an invalid signature.

address internal constant CANARY = 0x0000000000001Ab2e8006Fd8B71907bf06a5BDEE;

RIP_PRECOMPILE

Address of the RIP-7212 P256 verifier precompile. Currently, we don't support EIP-7212's precompile at 0x0b as it has not been finalized. See: https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md

address internal constant RIP_PRECOMPILE = 0x0000000000000000000000000000000000000100;

N

The order of the secp256r1 elliptic curve.

uint256 internal constant N =
        0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;

_HALF_N

N/2. Used for checking the malleability of the signature.

uint256 private constant _HALF_N =
        0x7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8;

Functions

verifySignatureAllowMalleability

Returns if the signature (r, s) is valid for hash and public key (x, y). Does NOT include the malleability check.

function verifySignatureAllowMalleability(
        bytes32 hash,
        bytes32 r,
        bytes32 s,
        bytes32 x,
        bytes32 y
    ) internal view returns (bool isValid);

Parameters

NameTypeDescription
hashbytes32
rbytes32
sbytes32
xbytes32
ybytes32

Returns

NameTypeDescription
isValidbool

verifySignature

Returns if the signature (r, s) is valid for hash and public key (x, y). Includes the malleability check.

function verifySignature(bytes32 hash, bytes32 r, bytes32 s, bytes32 x, bytes32 y)
        internal
        view
        returns (bool isValid);

Parameters

NameTypeDescription
hashbytes32
rbytes32
sbytes32
xbytes32
ybytes32

Returns

NameTypeDescription
isValidbool

hasPrecompile

Returns if the RIP-7212 precompile exists.

function hasPrecompile() internal view returns (bool result);

Returns

NameTypeDescription
resultbool

hasPrecompileOrVerifier

Returns if either the RIP-7212 precompile or the verifier exists. Since verifySignature is made not reverting, this function can be used to manually implement a revert if the current chain does not have the contracts to support secp256r1 signature recovery.

function hasPrecompileOrVerifier() internal view returns (bool result);

Returns

NameTypeDescription
resultbool

normalized

Returns s normalized to the lower half of the curve.

function normalized(bytes32 s) internal pure returns (bytes32 result);

Parameters

NameTypeDescription
sbytes32

Returns

NameTypeDescription
resultbytes32

tryDecodePoint

Helper function for abi.decode(encoded, (bytes32, bytes32)). If encoded.length < 64, (x, y) will be (0, 0), which is an invalid point.

function tryDecodePoint(bytes memory encoded) internal pure returns (bytes32 x, bytes32 y);

Parameters

NameTypeDescription
encodedbytes

Returns

NameTypeDescription
xbytes32
ybytes32

tryDecodePointCalldata

Helper function for abi.decode(encoded, (bytes32, bytes32)). If encoded.length < 64, (x, y) will be (0, 0), which is an invalid point.

function tryDecodePointCalldata(bytes calldata encoded)
        internal
        pure
        returns (bytes32 x, bytes32 y);

Parameters

NameTypeDescription
encodedbytes

Returns

NameTypeDescription
xbytes32
ybytes32