Groth16 Verifier in Fe-lang
Tags: ethereum, circom, smartcontract, felang
Published: 2023-11-28 09:44:23

[Fe-lang](https://fe-lang.org/) is a next generation smart contract language for Ethereum. 

Writing smart contracts in Fe is easy to learn, which is inspired by Python and Rust (but, there won't be a learning curve as Rust). In other words, writing in Fe looks like writing in Rust, but it is easy to write as Python. 

It uses the same intermediate language as Solidity (YUL), which makes a very good choice not only for Ethereum mainnet, but also for the Layer2 solutions.

By leveraging the EVM compatibility, I have implemented Groth16 Verifier contract in Fe (https://github.com/fe-lang/fe-crypto). It uses BN254 EVM precompiles in Fe as similar in Solidity.

Groth16 verifier in fe-lang allows you to verify circom circuits using [snarkjs](https://github.com/iden3/snarkjs). Using groth16.fe, you will be able to leverage zero-knowledge proofs with Fe.

As an example, I write a Circom circuit that you can prove that you know 2 factors of an integer without revealing what the factors are. Here is the simple circuit.

```
pragma circom 2.0.0;

/*This circuit template checks that c is the multiplication of a and b.*/  

template Multiplier2 () {  

   // Declaration of signals.  
   signal input a;  
   signal input b;  
   signal output c;  

   // Constraints.  
   c <== a * b;  
}
```

To be able to use the verifier to this circuit, you can follow the steps that is documented [here](https://github.com/fe-lang/fe-crypto/tree/main/verifiers)

Using the specified steps in the above link, you will be able to generate a Verifier.fe file.

Then, the only thing you need to do is use the `verifyProof()` functions in your Fe contract.

Here is the simple contract that verifies that I know 2 factors of an integer without revealing the factors in [main.fe](https://github.com/fe-lang/fe-crypto/blob/main/verifiers/src/main.fe)

```
#test
fn test_verify_proof() {
    let verification: bool = verifyProof(
        a: [0x28930e0aeb50e7e3b5f9a54a6abdce99978e00701914dfd4d87f8dc5ea9e1d02, 0x02c1e99774e679c144aceac4e9fdbc67dc858533d9f49c5933939c89010131b7],
        b: [[0x0684d8357689fb95e886a8251db0e142ffdda8032e314750455b9f5ff13159ca, 0x26189ebc171412019704e808c432062721db66c4a22635f20ed422a2147ad5bf], [0x005d309291fd34bef6248c17779114907b6d912a5a02ddae46d902dbd05e2e1c, 0x01673b4a2e94569e28e23a9ae808b9f92b4d21beca07522f79d16ec419a6e85c]],
        c: [0x25170145c09315e2df3c93d155b39df35434469607b0121a16125224190a596a, 0x05467081343913d54408694735a8d149578e7cbb3168f2b4283a7fe2861a7a42],
        input: [0x0000000000000000000000000000000000000000000000000000000000000021]
    )

    assert verification == true
}
```

That's all! The verification is correct in Fe.

I also created [bn254.fe library](https://github.com/fe-lang/fe-crypto/blob/main/crypto/src/curve/bn254.fe) that you can use the precompiles more easily.

Fe is currently a developing language to write smart contracts. It is designed to be safe, and helps you to write clean code without getting rid of compile-time guarantees. Further, you can see the links below to discover Fe yourself.

Explore some advanced contracts written in Fe: https://github.com/ethereum/fe/tree/master/crates/test-files/fixtures/demos
Fe-lang: https://fe-lang.org/