Code Monkey home page Code Monkey logo

ak-381's Introduction

AK-381: A SNARK verification library using bls12-381

This Aiken library implements utilities to verificate Zero-Knowledge proof following the Groth16 protocol. The main feature is a zk-SNARK verification function, along with utilities to create proofs and interoperate with the Plutus VM. The library is tailored to use with the Circom language and the SnarkJs module.

The statement...

I can prove to you "x" without to reveal "x".

Is now possible in its endless variations in this next PlutusV3 hardfork.

About zk-SNARKs

In short, a zk-SNARK follows a three step process:

  1. Setup: A preprocessing of the circuit (representation of the statement or algorith that you want to prove) that results in the proverk-ey and verification-key
  2. Proof: The creation of a proof of the statement.
  3. Verification: The verification of the statement given the proof (and not the data itself).

The 3 prime factorization example

In order to make this library ilustrative, we use a circuit that proofs that we know the multiplication of three big prime numbers to a verifier. Although in this example we use small prime numbers, to deduce the prime factors from the result is usually an hard and challenging computation problem. In this case for a given number we show just one factor and we proof that we know the other two without revealing them.

Requisites

In order to use this library you must have circom and Snarkjs. You can get both installed following this part of the circom documentation

Structure folder

  • Circuits: The folder where you put your circom circuits.
  • 3_fac: The output of the circuit that we use as example.
  • conversion: The javascript module where you can convert the proof and verification-key given by circom into the serialization that Plutus need.

Import the module into your Aiken project

To import the module you must execute the following command with the corresponding version. At the momment the version is v0.1.

aiken packages add modulo-p/ak-381 --version v0.1

The Groth16 process.

Groth16 is a zk-SNARK protocol that is characterized by its lighter proof and efficient verification. This library includes a bash script .groth16 that conduct you to the full process of setup, proving and verification. Regarding the setup that in the case of Groth16 requires a multi-party computation so it will ask you various randoms contributions to securely create the prover-key and verificatio-key. Make sure to take a look in the script to know more.

Before executing the script you have to set some things:

  • Set your circuit in the /circuitsfolder.
  • Set the input.json file (see below creating the witness).
  • Set the public.jsonfile (see below creating the witness).

Once you circuits and other files are ready, you can start the Groth16 protocol from setup, to proof and verification using:

./groth16

The script it's going to ask you about the circuit that you want to use. It is going to create you a folder with the name of the circuit which will storage all the outputs of the process.

Use with SnarkJs

Once you have completed the setup and created the <circuit>_final.zkeyyou can create new proofs and verify them.

Creating the witness

We create set the inputs of our proof in the input.json file. In this case we define the 3 factors (x1,x2 and x3) with these:

{ "x1": 3, "x2": 11, "x3": 17 }

And then change the public.json with the product of the factors and x1:

[
  "561",
  "3"
]

Then we take the wasm compilation of the circuit and theinput.json file and output the result in witness.wtns

snarkjs wc 3_fac_js/3_fac.wasm input.json witness.wtns

Creating the proof

With the witness ready we can compute the proof.

narkjs g16p 3_fac_final.zkey witness.wtns proof.json public.json

Verifying the proof

snarkjs g16v verification_key.json public3.json proof3.json

And should output the following:

[INFO]  snarkJS: OK!

Serialization of circom files.

In order to make the circom files interoperable with the Plutus VM, it is necessary to serialize the proof and verification key generated by circom. To serialize the circom files you can run the following:

#It will take as arg the folder of circom files, in our case is 3_fac.
$ ./convert.sh 3_fac

This will output the serialized proof and vk in its uncompressed form. It is important to point that the Plutus VM can operate uncompressed values, but will not let you store the uncompressed values as PlutusData. To store them as PlutusData you must do it in its compressed form, though the Aiken compiler can do the transformation under the hood for you.

Capabilities to convert values in its compressed form will be incorporated in the future.

ak-381's People

Contributors

agustinbadi avatar jmagan avatar ajuggler avatar ktorz avatar

ak-381's Issues

G1 & G2 Element definitions and interface

Context

In order to test the verification function we have to use the values of vk.json and proof.json by circom. To test this I will append our three factorial circuit example into the repo.

Problem

The problem now is how translate the values given by these .json files as G1 and G2 elements. Here is some clues that I have found:

  1. Both G1 and G2 defined in Cardano follows Z-Cash encoding where they have a compress and uncompress form.

Serialization Format

From the ZCash BLS12-381 specification

  • Fq elements are encoded in big-endian form. They occupy 48 bytes in this form.
  • Fq2 elements are encoded in big-endian form, meaning that the Fq2 element c0 + c1 * u is represented by the Fq element c1 followed by the Fq element c0. This means Fq2 elements occupy 96 bytes in this form.
  • The group G1 uses Fq elements for coordinates. The group G2 uses Fq2 elements for coordinates.
  • G1 and G2 elements can be encoded in uncompressed form (the x-coordinate followed by the y-coordinate) or in compressed form (just the x-coordinate). G1 elements occupy 96 bytes in uncompressed form, and 48 bytes in compressed form. G2 elements occupy 192 bytes in uncompressed form, and 96 bytes in compressed form.
    The most-significant three bits of a G1 or G2 encoding should be masked away before the coordinate(s) are interpreted. These bits are used to unambiguously represent the underlying element:

The most-significant three bits of a G1 or G2 encoding should be masked away before the coordinate(s) are interpreted. These bits are used to unambiguously represent the underlying element:

  • The most significant bit, when set, indicates that the point is in compressed form. Otherwise, the point is in uncompressed form.
  • The second-most significant bit indicates that the point is at infinity. If this bit is set, the remaining bits of the group element's encoding should be set to zero.
  • The third-most significant bit is set if (and only if) this point is in compressed form and it is not the point at infinity and its y-coordinate is the lexicographically largest of the two associated with the encoded x-coordinate.

Reference-1: https://github.com/supranational/blst#serialization-format
Reference-2: https://ci.iog.io/build/1230997/download/1/plutus-core-specification.pdf

  1. BLS12-381 Syntax

In aiken the definition of the uncompress G1 & G2 elements goes like this:

// Uncompressed G1Element
#<Bls12_381, G1>"97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"
// Compressed G1Element
#"97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"

// Uncompressed G2Element
#<Bls12_381, G2>"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8"
// Compressed G2Element
#"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8"

One can see more info about it in this in this PR: https://github.com/aiken-lang/stdlib/pull/79/files

[On-chain] Implementar verificador Groth16 con builtins v3

The idea is to create a library that one can later import in the game-logic aiken project.

The following resources will be useful:

  1. Aiken is updated with the next v3 builtins that allow pairings using bls12-381 curve, see:

https://aiken-lang.github.io/prelude/aiken/builtin.html

  1. The plutus specification gives some guidelines to implement pairings on page 38:

https://ci.iog.io/build/1230997/download/1/plutus-core-specification.pdf

  1. It would be good make the function abstractions similar to what we already implemented in the Plutus Groth repo:

https://github.com/Modulo-P/plutus-groth/blob/main/src/Groth16.hs

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.