Title
Mina Schnorr Signature verification in EVMs
Project Background
We’re working on bringing Mina’s signature verification methods to EVMs, inspired by mina-signer. The goal is simple but powerful - allow developers to verify signatures native to Mina Protocol right on EVM chains through Solidity smart contracts. For this project it means verifying both Field signatures, Message signatures and also validating Mina’s native Public Keys (Pallas Points).
The groundwork is already underway, and we’re excited to take this to the next level.
Proposal Overview
Problem
Right now, developers looking to work with Mina Schnorr Signatures on EVM chains are stuck - there’s no ready-to-use smart contract template for verifying signatures over the Pallas Pasta curve. This gap is holding back cross-chain innovation.
Solution
We’re creating a clone of the current verification methods, starting with the most crucial ones - verifyMessage and verifyFields. Based on community feedback, we’ll expand to cover other methods that developers find valuable.
Impact
This project opens up some exciting possibilities:
Cross-Chain Identity/Authentication:
- Your Mina account becomes readable by Ethereum contracts
- One identity works across both chains (imagine having a matched Public Key pair on EVM/Mina)
- Sign once, use anywhere - your signature works on both chains
- Complements the existing ECDSA verification
Cross-Chain Logic Execution:
- Smart contracts that react to verified Mina signatures
- Build trustless bridges without extra dependencies
- Simple plug-and-play verification for any developer
The best part? This lays the foundation for trustless bridges without relying on complex solutions. Developers can simply call our contracts and validate Mina native signatures.
Audience
We’re building this for:
- Potential bridge developers
- Solo developers wanting to build cross-chain zkApps
- Anyone looking for an entry point to connect Mina and EVM chains
Budget & Milestones
Deliverables: Production-ready EVM contracts that can verify both Mina Public Keys and Signatures (supporting fields and messages)
Mid-Point: Working verification on local Hardhat environment with basic test coverage
Timeline: 1 month
Budget: 10,000 MINA, broken down as:
- Developer Costs: 8000 MINA (core development)
- Deployment: 2000 MINA total
- Initial deployments across chains
- Comprehensive testing with edge cases
- Buffer for potential hotfixes to meet deadlines
Team Info
Github: br0wnD3v (Brown Dev) · GitHub
Experience: I’ve contributed to projects around Raffles, Perpetuals, RWAs and NFTs on Ethereum, and I’m deeply involved in Mina’s zkApp ecosystem as well as the community.
Team: Just me - Anuj Tanwar (br0wnD3v on Mina’s Discord), handling all development.
Achievements:
- Mina: Built Doot (Oracle, in production) and BMM (Memecoin Launchpad, near beta)
- Ethereum: Delivered whitelabel solutions for POP, QuantumFair, and Perped
Risks & Mitigations
Let’s be honest - the main challenge is gas fees. Verification is computationally heavy, and right now, we can’t do it in a single contract call. This creates two issues:
- Higher than ideal gas costs
- Slightly complex developer experience
But we’ve got solutions:
- Deploy on gas-efficient L1s like Base
- Integrate MakerDAO’s multicall for better UX
- Provide copy-paste examples to make integration dead simple
Sneak Peek
The following section is dedicated to displaying where we are at in the grand scheme of cloning the verification :
Public Key Verification
We have already implemented a function call that can validate a Public Key (Pallas Point) in solidity, it can be found here. The relevant struct to represent a Public Key can be found here. The hardhat test can be found here.
Verification methods.
Taking verifyFields()
from mina-signer.ts. It internally calls verify()
which I have started working on in the CORE file as can be seen here.
What I have in mind at the moment is as follows :
step1_prepareMessage + step2_prepareHashInput + step3_computeHash → hashMessage()
step4_computeHP + step5_negatePoint → scale(pk, e) and negate
step6_computeSG → scale(G, s)
step7_finalAddition → add points
step8_verify → check x coordinate and y parity
At the time of writing this proposal we have the step_1 ready and the Public Key verification completed.
What the next weeks would look like?
After completing the verifyFields()
implementation, I will start working on the steps related with verifyMessage()
from mina-signer.ts. The function in the source code internally calls verifyStringSignature()
which in turn calls verifyLegacy()
.
The verifyLegacy()
is same as verify()
, but using the “legacy” style of hash input packing. Considering that the source code explicitly mentions that the only difference is in the way of hash input packing, the majority of the main logic would remain same with some fine tuning here and there to the already existing methods implemented earlier in the verify()
solidity implementation.
What the DX would look like?
Our architecture follows a cascading pattern such that the only requirement would be to call the steps sequentially with a verificationId
that is generated at the very first step (step_1). A dedicated struct exists on The CORE file that keeps track of the steps and output of each step as can be seen here Example -
step_5(id) -> step_5_output
step_6(id) -> step_6_output
Again, a lot of the functions on the smart contract repository shared are not finalized and will be edited aggresively so please take everything mentioned above with a grain of salt. For example - A lot of functions on the smart contract expects one more param other than the verificationId
which won’t be there in the final state of the project.
What I am certain about however is that the final result would be a smart contract deployment that is a dot to dot clone of verifyMessage()
and verifyFields()
method from mina-signer under o1js.
The developer will only supply Message/Fields, Signature, PublicKey and the rest would be carry forwarded with each step (to be called sequentially by the user i.e (step_1 -> step_2
)). Ultimately returning True
if the message/fields signed did originate from the claimed Public Key or False
if not.
The Smart Contract Interface would be along the following lines :
// verifyFields()
function step_1VF() external returns(uint256 verificationId) {}
function step_2VF(uint256 verificationId) external {}
function step_3VF(uint256 verificationId) external {}
...
// verifyMessage()
function step_1VM() external returns(uint256 verificationId) {}
function step_2VM(uint256 verificationId) external {}
function step_3VM(uint256 verificationId) external {}
...
Bonus Note
This project is actually laying groundwork for something bigger - a feature called ‘Barter Swap’ (will be introduced under Doot) that’ll make ETH/MINA cross-chain swaps possible.
Getting this funded helps push that vision forward too. Have a good day .