Skip to content

An Ethereum implementation of the BIP340 Schnorr Signatures specification.

Notifications You must be signed in to change notification settings

ckanthony/bip340eth

Repository files navigation

BIP340 Ethereum Implementation

An Ethereum implementation of the BIP340 Schnorr Signatures specification. This project provides a gas-efficient way to verify Schnorr signatures on the Ethereum blockchain.

Problem & Solution

The Challenge

Traditional BIP340 signature verification in EVM has two main challenges:

  1. Computing point multiplication (ECMUL) on secp256k1 is expensive in EVM
  2. The BIP340 verification requires a specific hash construction:
    e = int(hashBIP0340/challenge(bytes(r) || bytes(P) || m)) mod n
    
    which includes appending "BIP340" to the verification hash, making it gas-intensive on-chain.

Our Approach

This implementation leverages two key optimizations:

  1. Efficient ECMUL: Based on Vitalik's research, we use ecrecover to perform ECMUL operations cheaply. However, instead of using it for general ECMUL, we've adapted it specifically for Schnorr signature verification.

  2. 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.

Reference

https://hackmd.io/@nZ-twauPRISEa6G9zg3XRw/SyjJzSLt9

Features

  • 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

Prerequisites

  • Node.js (>= 16.0.0)
  • Yarn (>= 1.22.0)

Installation

# Clone the repository
git clone https://github.com/ckanthony/bip340eth.git
cd bip340eth

# Install dependencies
yarn install

Usage

Compile Contracts

yarn compile

Run Tests

yarn test

Contract Interface

The main contract Bip340 provides the following function:

function verify(
    uint256 publicKey,
    uint256 publicNonce,
    uint256 signatureScalar,
    bytes32 message
) public pure returns (bool)

Parameters:

  • publicKey: The BIP340 public key (x-coordinate only)
  • publicNonce: The public nonce R (x-coordinate only)
  • signatureScalar: The signature scalar s
  • message: The 32-byte message hash to verify

Returns:

  • bool: True if the signature is valid, false otherwise

Gas Consumption

The verification function typically consumes around 61,000 gas, making it efficient for on-chain verification.

Security

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.

Development

Project Structure

├── contracts/          # Solidity contract files
├── test/              # Test files
├── scripts/           # Deployment and utility scripts
└── typechain-types/   # Generated TypeScript types

Testing

The test suite includes:

  • Verification of valid signatures
  • Rejection of invalid signatures
  • Edge cases (zero values, tampered keys)
  • Gas efficiency checks

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

An Ethereum implementation of the BIP340 Schnorr Signatures specification.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published