Experimental, unaudited cryptographic code. Use at your own risk.
Verify BLS signatures on the BN254 curve in a Solana program. The Shallue-van de Woestijne (SvdW) map defined in RFC 9380 is used to hash messages to curve points, in a manner compatible with drand evmnet and dcipher.
Due to Solana's computation limits, the onchain program must be provided pre-computed modular square roots for the SvdW map.
To prepare a fresh or existing signature for onchain verification, use the hash_to_g1_custom_with_hints function in the hash_to_curve crate, which returns the necessary hints for a given message and DST.
Note that the modular inverse operation only costs ~50k compute units (and is executed twice per signature) out of a maximum of 1.4M, hence it is computed onchain with no hints.
If desired, hints could be added back simply by changing to hints.inverse() in svdw.rs.
Note that since the total size of a Solana transaction is limited to 1232 bytes, this may not be a good tradeoff.
crates/solana-bls: a library that verifies BLS signatures on BN254 on Solana.
crates/hash_to_curve: a cryptographic library that implements SvdW with hints.
crates/hinting: a lower-level library that deals with computing and verifying hints.
crates/testcases: an internal library that generates test cases for solana-bls.
programs/demo_bls_verify: a demo Solana program that verifies arbitrary BLS signatures on BN254.
bins/submit_bls_sig: a CLI tool to interact with the demo program.
Dependencies: Rustup, Solana CLI, and Anchor. Authoritative installation instructions here. You do not need yarn or any JS/TS stuff.
If there is an error about needing a wallet, run this command to create one:
solana-keygen newanchor buildanchor test # for mollusk tests
cargo test # for other testsThis will fetch the latest round from evmnet and send it onchain for verification.
anchor localnet # in one terminal
bash demo.sh # in another terminal-
In the current setup, the deployer of the program retains the ability to upgrade it or delete it entirely.
-
It still takes up to 600k computation units to verify a signature, which is almost half of the transaction limit. Further optimizations may be possible.