An Ethereum implementation of the BIP340 Schnorr Signatures specification. This project provides a gas-efficient way to verify Schnorr signatures on the Ethereum blockchain.
Traditional BIP340 signature verification in EVM has two main challenges:
- Computing point multiplication (ECMUL) on secp256k1 is expensive in EVM
- The BIP340 verification requires a specific hash construction:
which includes appending "BIP340" to the verification hash, making it gas-intensive on-chain.
e = int(hashBIP0340/challenge(bytes(r) || bytes(P) || m)) mod n
This implementation leverages two key optimizations:
-
Efficient ECMUL: Based on Vitalik's research, we use
ecrecoverto perform ECMUL operations cheaply. However, instead of using it for general ECMUL, we've adapted it specifically for Schnorr signature verification. -
Pre-computed Challenge: Rather than computing the full BIP340 challenge hash on-chain, we pre-compute it off-chain and pass it as part of the verification parameters. This significantly reduces gas costs while maintaining security.
These optimizations reduce the gas cost dramatically, making Schnorr signature verification practical for on-chain use.
https://hackmd.io/@nZ-twauPRISEa6G9zg3XRw/SyjJzSLt9
- Pure Solidity implementation of BIP340 signature verification
- Gas-optimized elliptic curve operations
- Comprehensive test suite with test vectors from the BIP340 specification
- TypeScript support with type definitions
- Node.js (>= 16.0.0)
- Yarn (>= 1.22.0)
# Clone the repository
git clone https://github.com/ckanthony/bip340eth.git
cd bip340eth
# Install dependencies
yarn installyarn compileyarn testThe main contract Bip340 provides the following function:
function verify(
uint256 publicKey,
uint256 publicNonce,
uint256 signatureScalar,
bytes32 message
) public pure returns (bool)publicKey: The BIP340 public key (x-coordinate only)publicNonce: The public nonce R (x-coordinate only)signatureScalar: The signature scalar smessage: The 32-byte message hash to verify
bool: True if the signature is valid, false otherwise
The verification function typically consumes around 61,000 gas, making it efficient for on-chain verification.
This implementation has been developed following the BIP340 specification closely. However, it has not been audited and should be used with caution in production environments.
├── contracts/ # Solidity contract files
├── test/ # Test files
├── scripts/ # Deployment and utility scripts
└── typechain-types/ # Generated TypeScript types
The test suite includes:
- Verification of valid signatures
- Rejection of invalid signatures
- Edge cases (zero values, tampered keys)
- Gas efficiency checks
MIT
Contributions are welcome! Please feel free to submit a Pull Request.