### Perform zk-SNARK Backend Operations with gnark (Groth16 & PlonK) Source: https://docs.gnark.consensys.io/HowTo/prove This snippet demonstrates the three core zk-SNARK backend algorithms: `Setup`, `Prove`, and `Verify`. It shows examples for both `Groth16` and an experimental `PlonK` implementation within the `gnark` library. These operations are fundamental for generating and validating cryptographic proofs. ```Go // 1. One time setup pk, vk, err := groth16.Setup(cs) // 2. Proof creation proof, err := groth16.Prove(cs, pk, witness) // 3. Proof verification err := groth16.Verify(proof, vk, publicWitness) ``` ```Go // 1. One time setup publicData, _ := plonk.Setup(cs, ...) // WIP // 2. Proof creation proof, err := plonk.Prove(r1cs, publicData, witness) // 3. Proof verification err := plonk.Verify(proof, publicData, publicWitness) ``` -------------------------------- ### Install gnark Go module Source: https://docs.gnark.consensys.io/HowTo/get_started This command installs the `gnark` library as a standard Go module into your project. It fetches the latest version from the GitHub repository. Ensure your `go.mod` file uses `consensys` (lowercase) for the module path. ```Go go get github.com/consensys/gnark@latest ``` -------------------------------- ### Perform Groth16 Setup for zkSNARK Circuit in Go Source: https://docs.gnark.consensys.io/Tutorials/eddsa This Go snippet demonstrates running the Groth16 setup phase to generate the `ProvingKey` (pk) and `VerifyingKey` (vk) for the compiled R1CS circuit. These keys are crucial for generating and verifying zkSNARK proofs, enabling the prover to create a proof and the verifier to check its validity. ```Go // generating pk, vk pk, vk, err := groth16.Setup(r1cs) ``` -------------------------------- ### Example gnark Circuit Structure for Witness Variable Ordering Source: https://docs.gnark.consensys.io/HowTo/serialize Provides a Go struct definition for a gnark circuit, demonstrating how frontend.Variable types are declared and how the `gnark:",public"` tag designates a public input. This structure serves as an example for understanding the ordering of variables within a binary witness. ```Go type Circuit struct { X frontend.Variable Y frontend.Variable `gnark:",public"` Z frontend.Variable } ``` -------------------------------- ### Export Groth16 Verifying Key as Solidity Smart Contract Source: https://docs.gnark.consensys.io/HowTo/prove This snippet shows how to export a `groth16.VerifyingKey` as a Solidity smart contract, enabling on-chain proof verification on Ethereum. It covers the compilation, setup, and the final export step for `ecc.BN254` and `Groth16`. ```Go // 1. Compile (Groth16 + BN254) cs, err := frontend.Compile(ecc.BN254, r1cs.NewBuilder, &myCircuit) // 2. Setup pk, vk, err := groth16.Setup(cs) // 3. Write solidity smart contract into a file err = vk.ExportSolidity(f) ``` -------------------------------- ### Implement gnark Circuit Go Unit Tests Source: https://docs.gnark.consensys.io/HowTo/debug_test This Go unit test example shows how to use test.NewAssert to verify gnark circuits. It demonstrates ProverFailed and ProverSucceeded assertions, including specifying curve types for testing. ```Go // assert object wrapping testing.T assert := test.NewAssert(t) // declare the circuit var cubicCircuit Circuit assert.ProverFailed(&cubicCircuit, &Circuit{ PreImage: 42, Hash: 42, }) assert.ProverSucceeded(&cubicCircuit, &Circuit{ PreImage: 35, Hash: "16130099170765464552823636852555369511329944820189892919423002775646948828469", }, test.WithCurves(ecc.BN254)) ``` -------------------------------- ### Profile gnark Circuit Constraints with `gnark/profile` Source: https://docs.gnark.consensys.io/HowTo/profile This Go code demonstrates how to use the `gnark/profile` package to measure the number of constraints added in a `gnark` circuit. It shows how to start and stop a profile, compile a simple circuit, and then print the total number of constraints and the top constraint-contributing functions, generating a `pprof` compatible file for visualization. ```Go type Circuit struct { A frontend.Variable } func (circuit *Circuit) Define(api frontend.API) error { api.AssertIsEqual(api.Mul(circuit.A, circuit.A), circuit.A) return nil } func Example() { // default options generate gnark.pprof in current dir // use pprof as usual (go tool pprof -http=:8080 gnark.pprof) to read the profile file // overlapping profiles are allowed (define profiles inside Define or subfunction to profile // part of the circuit only) p := profile.Start() _, _ = frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &Circuit{}) p.Stop() fmt.Println(p.NbConstraints()) fmt.Println(p.Top()) // Output: // 2 // Showing nodes accounting for 2, 100% of 2 total // flat flat% sum% cum cum% // 1 50.00% 50.00% 2 100% profile_test.(*Circuit).Define profile/profile_test.go:17 // 1 50.00% 100% 1 50.00% r1cs.(*r1cs).AssertIsEqual frontend/cs/r1cs/api_assertions.go:37 } ``` -------------------------------- ### Using gnark hints for integer bit decomposition in Go Source: https://docs.gnark.consensys.io/HowTo/write/hints This Go code snippet demonstrates how to use `gnark` compiler hints, specifically `hint.IthBit`, to decompose an integer `a` into its binary representation. The bits are provided off-circuit via the hint, and the circuit then verifies that their weighted sum equals the original integer `a`. It uses `cs.NewHint` to get the hint value and `cs.AssertIsBoolean` and `cs.AssertIsEqual` for constraints. ```Go var b []frontend.Variable var Σbi frontend.Variable base := 1 for i := 0; i < nBits; i++ { b[i] = cs.NewHint(hint.IthBit, a, i) cs.AssertIsBoolean(b[i]) Σbi = api.Add(Σbi, api.Mul(b[i], base)) base = base << 1 } cs.AssertIsEqual(Σbi, a) ``` -------------------------------- ### Implement for loops in gnark circuit definition Source: https://docs.gnark.consensys.io/HowTo/write/instructions Demonstrates how to use standard `for` loops within a `gnark` circuit's `Define` method. The example shows repeated multiplication using `api.Mul` and a final assertion with `api.AssertIsEqual`, illustrating that loops are unrolled into the constraint system. ```Go func (circuit *Circuit) Define(api frontend.API) error { for i := 0; i < n; i++ { circuit.X = api.Mul(circuit.X, circuit.X) } api.AssertIsEqual(circuit.X, circuit.Y) return nil } ``` -------------------------------- ### Defining a cubic equation constraint in gnark Source: https://docs.gnark.consensys.io/HowTo/write/circuit_api Example demonstrating how to define a cubic equation constraint (x^3 + x + 5 = y) using `api.Mul` for multiplication and `api.Add` for addition within a gnark circuit. `circuit.X` and `circuit.Y` represent circuit variables. ```Go x3 := api.Mul(circuit.X, circuit.X, circuit.X) api.AssertIsEqual(circuit.Y, api.Add(x3, circuit.X, 5)) ``` -------------------------------- ### Hexadecimal Example of a Valid gnark Binary Witness Source: https://docs.gnark.consensys.io/HowTo/serialize Presents a concrete hexadecimal representation of a binary witness, corresponding to the example circuit with specific values for Y, X, and Z. This illustrates the byte-level encoding and ordering of elements as defined by the gnark binary witness protocol. ```APIDOC 000000010000000200000003000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002 ``` -------------------------------- ### Unit Test EdDSA Circuit with gnark/backend/groth16/assert in Go Source: https://docs.gnark.consensys.io/Tutorials/eddsa This Go snippet provides an example of how to write unit tests for a `gnark` circuit using the `groth16.NewAssert` utility within a `_test.go` file. It shows how to use methods like `ProverFailed` (or `ProverSucceeded`) to test the circuit's behavior and ensure its correctness with specific assignments. ```Go assert := groth16.NewAssert(t) var witness Circuit assert.ProverFailed(&circuit, &assignment) // .ProverSucceeded ``` -------------------------------- ### Declare gnark Circuit Struct with Inputs Source: https://docs.gnark.consensys.io/HowTo/write/circuit_structure This example shows how to define a gnark circuit struct, `MyCircuit`, which includes both a custom component and a `frontend.Variable`. It demonstrates how to mark inputs as public using the `gnark:",public"` struct tag, and outlines the basic structure of the `Define` method. ```Go type MyCircuit struct { C myComponent Y frontend.Variable `gnark:",public"` } type myComponent struct { X frontend.Variable } func (circuit *MyCircuit) Define(api frontend.API) error { // ... see Circuit API section } ``` -------------------------------- ### Generate EdDSA Signature for Circuit Testing in Go Source: https://docs.gnark.consensys.io/Tutorials/eddsa This Go `main` function demonstrates how to generate an EdDSA key pair, sign a message, and verify the signature using the `gnark-crypto/signature/eddsa` package. It utilizes the BN254 curve and a MiMC hash function, providing a concrete example of how to create the necessary inputs for circuit testing. ```Go func main() { // instantiate hash function hFunc := hash.MIMC_BN254.New() // create a eddsa key pair privateKey, err := eddsa.New(twistededwards.BN254, crand.Reader) publicKey := privateKey.Public() // note that the message is on 4 bytes msg := []byte{0xde, 0xad, 0xf0, 0x0d} // sign the message signature, err := privateKey.Sign(msg, hFunc) // verifies signature isValid, err := publicKey.Verify(signature, msg, hFunc) if !isValid { fmt.Println("1. invalid signature") } else { fmt.Println("1. valid signature") } } ``` -------------------------------- ### Construct a Witness for gnark Circuits in Go Source: https://docs.gnark.consensys.io/HowTo/prove This code illustrates how to construct a witness for a `gnark` circuit within a Go process. It defines a circuit structure, assigns values to its variables, and then creates a new witness object using `frontend.NewWitness`. This witness is essential for the `Prove` operation in zk-SNARK backends. ```Go type Circuit struct { X frontend.Variable Y frontend.Variable `gnark:",public"` } assignment := &Circuit { X: 3, Y: 35, } witness, _ := frontend.NewWitness(assignment, ecc.BN254) // use the witness directly in zk-SNARK backend APIs groth16.Prove(cs, pk, witness) // test file --> assert.ProverSucceeded(cs, &witness) ``` -------------------------------- ### Generate and Verify zk-SNARK Proof with gnark in Go Source: https://docs.gnark.consensys.io/overview This Go code illustrates the process of generating and verifying a zk-SNARK proof using `gnark`. It involves creating a witness from an assignment, setting up the prover and verifier keys with `groth16.Setup`, generating the proof with `groth16.Prove`, and finally verifying the proof against the public witness using `groth16.Verify`. ```Go // witness assignment := &Circuit{ Hash: "16130099170765464552823636852555369511329944820189892919423002775646948828469", PreImage: 35, } witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) publicWitness, _ := witness.Public() pk, vk, err := groth16.Setup(r1cs) proof, err := groth16.Prove(r1cs, pk, witness) err := groth16.Verify(proof, vk, publicWitness) ``` -------------------------------- ### gnark `frontend.API` Methods Reference Source: https://docs.gnark.consensys.io/HowTo/write/circuit_api Reference for key methods available on the `frontend.API` object, used within the `Define` method of a gnark circuit to build and assert constraints. These methods support variadic arguments for flexibility. ```APIDOC frontend.API: Methods: Mul(operands ...interface{}) frontend.Variable Purpose: Multiplies a variadic list of variables and constants. Parameters: operands: A variadic list of `frontend.Variable` or `interface{}` (constants). Returns: A `frontend.Variable` representing the product. Add(operands ...interface{}) frontend.Variable Purpose: Adds a variadic list of variables and constants. Parameters: operands: A variadic list of `frontend.Variable` or `interface{}` (constants). Returns: A `frontend.Variable` representing the sum. AssertIsEqual(a, b frontend.Variable) error Purpose: Asserts that two variables or expressions are equal. Parameters: a: The first `frontend.Variable` or expression. b: The second `frontend.Variable` or expression. Returns: An error if the assertion fails. ``` -------------------------------- ### Generate and Verify zkSNARK Proof for EdDSA Circuit in Go Source: https://docs.gnark.consensys.io/Tutorials/eddsa This Go snippet demonstrates the final steps of generating and verifying a zkSNARK proof using Groth16. It first creates a witness from the assigned values, then generates the proof using the proving key, and finally verifies the proof using the verifying key and the public witness, ensuring the computation was performed correctly. ```Go // witness witness, err := frontend.NewWitness(&assignment, ecc.BN254) publicWitness, err := witness.Public() // generate the proof proof, err := groth16.Prove(r1cs, pk, witness) // verify the proof err = groth16.Verify(proof, vk, publicWitness) if err != nil { // invalid proof } ``` -------------------------------- ### Debug gnark Circuit with api.Println Source: https://docs.gnark.consensys.io/HowTo/debug_test This Go snippet illustrates using api.Println() to debug gnark circuits by printing solved values, similar to fmt.Println, and provides stack traces for solving errors. ```Go api.Println("A.X", pubKey.A.X) ``` -------------------------------- ### gnark Hint Function API References Source: https://docs.gnark.consensys.io/HowTo/write/hints References to key `gnark` API elements related to compiler hints, including interfaces for hint functions and backend options. ```APIDOC hint.Function: Description: Interface that custom hint functions must satisfy. Reference: https://pkg.go.dev/github.com/consensys/gnark/backend/hint#Function backend.WithHints: Description: Option to provide custom hint functions to the gnark backend. Reference: https://pkg.go.dev/github.com/consensys/gnark/backend#WithHints hint.NewStaticHint: Description: Constructor for simple hint functions that take a constant number of inputs and return a constant number of outputs. Reference: https://pkg.go.dev/github.com/consensys/gnark/backend/hint#NewStaticHint api.NewHint(hint.Function, ...inputs): Description: Method used within a circuit to request a value from a hint function. Parameters: hint.Function: The hint function to use. ...inputs: Variables or constants to pass to the hint function. ``` -------------------------------- ### Verify Merkle Proof in gnark Circuit Source: https://docs.gnark.consensys.io/HowTo/write/standard_library This Go code snippet defines a circuit for verifying a Merkle proof. It takes the `RootHash`, `Path`, and `Helper` as public inputs. The `Define` method initializes a MiMC hash function and then uses `merkle.VerifyProof` to validate the proof against the root hash within the circuit. ```Go type merkleCircuit struct { RootHash frontend.Variable `gnark:",public"` Path, Helper []frontend.Variable } func (circuit *merkleCircuit) Define(api frontend.API) error { hFunc, _ := mimc.NewMiMC(api.Curve()) merkle.VerifyProof(cs, hFunc, circuit.RootHash, circuit.Path, circuit.Helper) return nil } ``` -------------------------------- ### Create Witness for EdDSA Circuit in Go Source: https://docs.gnark.consensys.io/Tutorials/eddsa This Go snippet illustrates how to declare and assign values to the `eddsaCircuit`'s witnesses, which represent the inputs to the circuit. It assigns the message, public key, and signature values to the corresponding fields of the `assignment` struct, preparing the data required for proof generation. ```Go // declare the witness var assignment eddsaCircuit // assign message value assignment.Message = msg // public key bytes _publicKey := publicKey.Bytes() // assign public key values assignment.PublicKey.Assign(ecc.BN254, _publicKey[:32]) // assign signature values assignment.Signature.Assign(ecc.BN254, signature) ``` -------------------------------- ### Serialize and Deserialize gnark ProvingKey with Point Compression in Go Source: https://docs.gnark.consensys.io/HowTo/serialize Shows how to serialize ProvingKey objects using WriteRawTo (without point compression) or WriteTo (with point compression). When deserializing with ReadFrom, the reader automatically detects if the points were compressed or not. This affects CPU cost versus storage size. ```Go provingKey.WriteRawTo(&buf) // alternatively, provingKey.WriteTo(&buf) ... pk := groth16.NewProvingKey(ecc.BN254) pk.ReadFrom(&buf) // reader will detect if points are compressed or not. ``` -------------------------------- ### Compile gnark circuit with frontend.Compile in Go Source: https://docs.gnark.consensys.io/HowTo/compile This Go snippet demonstrates how to compile a `gnark` circuit. It uses `frontend.Compile` with `ecc.BN254.ScalarField()` and `r1cs.NewBuilder` to convert a `Circuit` definition into an R1CS (Rank-1 Constraint System) representation. ```Go var myCircuit Circuit r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &myCircuit) ``` -------------------------------- ### Go gnark Witness Serialization and Deserialization Source: https://docs.gnark.consensys.io/HowTo/serialize This Go code snippet demonstrates the serialization and deserialization of `gnark` witnesses. It covers creating a witness, marshalling it into binary and JSON formats, and then unmarshalling it back. It also shows how to extract the public part of a witness, which is useful for scenarios where witness creation and proof creation occur in separate processes. ```Go // witness var assignment cubic.Circuit assignment.X = 3 assignment.Y = 35 witness, _ := frontend.NewWitness(&assignment, ecc.BN254) // Binary marshalling data, err := witness.MarshalBinary() // JSON marshalling json, err := witness.MarshalJSON() ... // recreate a witness witness, err := witness.New(ecc.BN254, ccs.GetSchema()) // note that schema is optional for binary encoding // Binary unmarshalling err := witness.UnmarshalBinary(data) // JSON unmarshalling err := witness.UnmarshalJSON(json) // extract the public part only publicWitness, _ := witness.Public() ``` -------------------------------- ### Using variadic arguments in gnark API calls Source: https://docs.gnark.consensys.io/HowTo/write/circuit_api Illustrates the flexibility of gnark APIs, which accept a variadic list of `frontend.Variable` and `interface{}`. This allows for concise expressions like `api.Mul(X, 2, api.Add(Y, Z, 42))`, where constants are automatically handled. ```Go api.Mul(X, 2, api.Add(Y, Z, 42)) ``` -------------------------------- ### Define gnark Circuit Interface Source: https://docs.gnark.consensys.io/HowTo/write/circuit_structure All gnark circuits must implement the `frontend/Circuit` interface. The `Define` method is where the circuit's constraints are declared, taking a `frontend.API` object as an argument to build the constraint system. ```Go type Circuit interface { // Define declares the circuit's Constraints Define(api frontend.API) error } ``` -------------------------------- ### Execute gnark Circuit Without Prover Source: https://docs.gnark.consensys.io/HowTo/debug_test This Go snippet demonstrates how to execute a gnark circuit using test.IsSolved for a faster development workflow, bypassing the zk-SNARK prover and constraint system generation. ```Go err := test.IsSolved(circuit, witness, field) ``` -------------------------------- ### Unit Test gnark Circuit with groth16 Assertions in Go Source: https://docs.gnark.consensys.io/overview This Go snippet shows how to unit test a `gnark` circuit using `groth16.NewAssert`. It demonstrates testing both a failing scenario (incorrect hash/pre-image) and a successful scenario (correct hash/pre-image) for the `mimcCircuit`. ```Go assert := groth16.NewAssert(t) var mimcCircuit Circuit { assert.ProverFailed(&mimcCircuit, &Circuit{ Hash: 42, PreImage: 42, }) } { assert.ProverSucceeded(&mimcCircuit, &Circuit{ Hash: "16130099170765464552823636852555369511329944820189892919423002775646948828469", PreImage: 35, }) } ``` -------------------------------- ### Verify Groth16 Proof within a gnark Circuit Source: https://docs.gnark.consensys.io/HowTo/write/standard_library This Go code defines a circuit that enables verifying a Groth16 proof (specifically a BLS12_377 proof) inside another gnark circuit (a BW6_761 circuit). It includes the `InnerProof`, `InnerVk` (verifying key), and a `Hash` as inputs. The `Define` method calls `groth16.Verify` to perform the on-chain verification. ```Go type verifierCircuit struct { InnerProof Proof InnerVk VerifyingKey Hash frontend.Variable } func (circuit *verifierCircuit) Define(api frontend.API) error { groth16.Verify(api, circuit.InnerVk, circuit.InnerProof, []frontend.Variable{circuit.Hash}) return nil } ``` -------------------------------- ### Serialize gnark Circuit Constraint System in Go Source: https://docs.gnark.consensys.io/HowTo/serialize Demonstrates how to compile a circuit and then serialize the resulting r1cs.ConstraintSystem object into a bytes.Buffer using its WriteTo method. This method is implemented by gnark objects that adhere to the io.WriterTo interface. ```Go // compile a circuit cs, err := frontend.Compile(ecc.BN254, r1cs.NewBuilder, &circuit) // cs implements io.WriterTo var buf bytes.Buffer cs.WriteTo(&buf) ``` -------------------------------- ### EdDSA Signature Generation (Outside Circuit) Source: https://docs.gnark.consensys.io/Tutorials/eddsa Demonstrates how to generate an EdDSA private key, public key, and sign a message using `eddsa.New` and `privateKey.Sign` outside of the zk-SNARK circuit. ```Go privateKey, publicKey := eddsa.New(..) signature := privateKey.Sign(message) ``` -------------------------------- ### Implement Circuit Define Function for EdDSA Verification in Go Source: https://docs.gnark.consensys.io/Tutorials/eddsa This Go function implements the `Define` method for the `eddsaCircuit`, which describes the mathematical statement to be verified within the zkSNARK. It initializes the elliptic curve and a MiMC hash function, then calls `eddsa.Verify` to perform the signature verification logic inside the circuit's constraint system. ```Go import ( "github.com/consensys/gnark/std/algebra/twistededwards" "github.com/consensys/gnark-crypto/ecc" ) func (circuit *eddsaCircuit) Define(api frontend.API) error { curve, err := twistededwards.NewEdCurve(api, circuit.curveID) if err != nil { return err } mimc, err := mimc.NewMiMC(api) if err != nil { return err } // verify the signature in the cs return eddsa.Verify(curve, circuit.Signature, circuit.Message, circuit.PublicKey, &mimc) return nil } ``` -------------------------------- ### Compile EdDSA Circuit in Go Source: https://docs.gnark.consensys.io/Tutorials/eddsa This Go snippet shows how to compile the `eddsaCircuit` using `frontend.Compile` from the `gnark` library. The compilation process converts the circuit's high-level Go definition into its arithmetized R1CS (Rank-1 Constraint System) form, which is a list of constraints that the prover must satisfy. ```Go var circuit eddsaCircuit r1cs, err := frontend.Compile(ecc.BN254, r1cs.NewBuilder, &circuit) ``` -------------------------------- ### Define Verify function signature Source: https://docs.gnark.consensys.io/Tutorials/eddsa Defines the initial signature of the `Verify` function, which takes a signature, message, public key, and a `frontend.API` object (representing the constraint system). This function will contain the core EdDSA verification logic. ```Go func Verify(api frontend.API, sig Signature, msg frontend.Variable, pubKey PublicKey) error { // ... } ``` -------------------------------- ### Implement MiMC Hash in gnark Circuit Source: https://docs.gnark.consensys.io/HowTo/write/standard_library This Go code snippet demonstrates how to define a circuit for computing the MiMC hash. It utilizes the `gnark/std/mimc` package to initialize a new MiMC hash function. The `Hash` method is then called to compute the hash of the `circuit.Data` within the circuit's `Define` method. ```Go func (circuit *mimcCircuit) Define(api frontend.API) error { // ... hFunc, _ := mimc.NewMiMC(api.Curve()) computedHash := hFunc.Hash(cs, circuit.Data) // ... } ``` -------------------------------- ### Compile gnark Circuit in Go Source: https://docs.gnark.consensys.io/overview This Go snippet demonstrates how to compile a `gnark` circuit. It uses `frontend.Compile` with the `ecc.BN254` curve and `r1cs.NewBuilder` to translate the defined `mimcCircuit` into an R1CS (Rank-1 Constraint System). ```Go var mimcCircuit Circuit r1cs, err := frontend.Compile(ecc.BN254, r1cs.NewBuilder, &mimcCircuit) ``` -------------------------------- ### gnark api.Select for conditional logic Source: https://docs.gnark.consensys.io/HowTo/write/instructions Documents the `gnark` `api.Select` method, which provides a declarative way to implement conditional statements in circuits. It takes a boolean variable `b` and two interface values `i1` and `i2`, returning `i1` if `b` is true, otherwise `i2`. ```APIDOC func (cs *ConstraintSystem) Select(b Variable, i1, i2 interface{}) Variable Description: Selects between i1 and i2 based on the boolean variable b. Parameters: b: Variable - A boolean variable. If true, i1 is selected; otherwise, i2 is selected. i1: interface{} - The value to be selected if b is true. i2: interface{} - The value to be selected if b is false. Returns: Variable - The selected value (either i1 or i2). ``` -------------------------------- ### Define gnark Circuit for Pre-image Knowledge Proof in Go Source: https://docs.gnark.consensys.io/overview This Go code defines a `Circuit` struct for a pre-image knowledge proof using `gnark`. It includes a `PreImage` (secret input) and a `Hash` (public input). The `Define` method specifies the circuit's constraints, asserting that the MiMC hash of the `PreImage` equals the `Hash`. ```Go // Circuit defines a pre-image knowledge proof // mimc(secret preImage) = public hash type Circuit struct { PreImage frontend.Variable Hash frontend.Variable `gnark:",public"` } // Define declares the circuit's constraints func (circuit *Circuit) Define(api frontend.API) error { // hash function mimc, err := mimc.NewMiMC(api.Curve()) // specify constraints // mimc(preImage) == hash api.AssertIsEqual(circuit.Hash, mimc.Hash(cs, circuit.PreImage)) return nil } ``` -------------------------------- ### Verify EdDSA Signature in gnark Circuit Source: https://docs.gnark.consensys.io/HowTo/write/standard_library This Go code defines a circuit for verifying an EdDSA signature. It includes public inputs for the `PublicKey`, `Signature`, and `Message`. The `Define` method initializes the EdDSA curve and then calls `eddsa.Verify` to check the signature against the message and public key within the circuit. ```Go type eddsaCircuit struct { PublicKey eddsa.PublicKey `gnark:",public"` Signature eddsa.Signature `gnark:",public"` Message frontend.Variable `gnark:",public"` } func (circuit *eddsaCircuit) Define(api frontend.API) error { edCurve, _ := twistededwards.NewEdCurve(api.Curve()) circuit.PublicKey.Curve = edCurve eddsa.Verify(cs, circuit.Signature, circuit.Message, circuit.PublicKey) return nil } ``` -------------------------------- ### Circuit `Define` method signature in gnark Source: https://docs.gnark.consensys.io/HowTo/write/circuit_api The `Define` method is implemented by a gnark circuit struct to define its constraints. It receives a `frontend.API` object, which serves as the root for manipulating and adding constraints. ```Go func Define(api frontend.API) error ``` -------------------------------- ### Debug values with api.Println Source: https://docs.gnark.consensys.io/Tutorials/eddsa Demonstrates how to print values for debugging purposes within the gnark circuit using `api.Println`. This function behaves similarly to `fmt.Println` but outputs the values at proving time, when they are solved by the prover. ```Go api.Println("A.X", pubKey.A.X) ``` -------------------------------- ### Compute H(R,A,M) using Mimc hash Source: https://docs.gnark.consensys.io/Tutorials/eddsa Computes the hash H(R,A,M) using the `mimc` hash function, which is a snark-friendly hash. This involves importing necessary gnark packages and preparing the input data (R, A, M components) for the hash function. ```Go import ( "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/std/algebra/twistededwards" "github.com/consensys/gnark/std/hash/mimc" ) func Verify(curve twistededwards.Curve, sig Signature, msg frontend.Variable, pubKey PublicKey, hash hash.Hash) error { // compute H(R, A, M) data := []frontend.Variable{ sig.R.A.X, sig.R.A.Y, pubKey.A.X, pubKey.A.Y, msg, } hramConstant := hash.Hash(cs, data...) return nil } ``` -------------------------------- ### Define EdDSA Circuit Structure in Go Source: https://docs.gnark.consensys.io/Tutorials/eddsa This Go struct defines the necessary public witnesses for an EdDSA signature verification within a zkSNARK circuit. It includes the public key, signature, and message, all marked as public variables for the `gnark` framework, ensuring they are exposed as public inputs to the circuit. ```Go import ( "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/std/signature/eddsa" ) type eddsaCircuit struct { PublicKey eddsa.PublicKey `gnark:",public"` Signature eddsa.Signature `gnark:",public"` Message frontend.Variable `gnark:",public"` } ``` -------------------------------- ### Deserialize gnark Circuit Constraint System in Go Source: https://docs.gnark.consensys.io/HowTo/serialize Illustrates how to deserialize a gnark object, specifically a curve-typed groth16.ConstraintSystem, from a bytes.Buffer using its ReadFrom method. It is crucial to instantiate a curve-typed object first, as per gnark API design choices. ```Go // instantiate a curve-typed object cs := groth16.NewCS(ecc.BN254) // cs implements io.ReaderFrom cs.ReadFrom(&buf) ``` -------------------------------- ### Go Struct for EdDSA Public Key in gnark Source: https://docs.gnark.consensys.io/Tutorials/eddsa Defines the `PublicKey` struct in the `eddsa` package for use within `gnark` circuits. It encapsulates a `twistededwards.Point` representing the public key, which is a tuple (x,y) of `frontend.Variable`. ```Go package eddsa import "github.com/consensys/gnark/std/algebra/twistededwards" type PublicKey struct { A twistededwards.Point } ``` -------------------------------- ### Go Struct for Twisted Edwards Curve Parameters Source: https://docs.gnark.consensys.io/Tutorials/eddsa Defines the `CurveParams` struct in Go, which holds the parameters for a twisted Edwards curve (ax^2 + y^2 = 1 + d*x^2*y^2), including coefficients A, D, Cofactor, Order, and Base point coordinates. This struct matches `gnark-crypto`'s curve-specific parameters. ```Go // CurveParams twisted edwards curve parameters ax^2 + y^2 = 1 + d*x^2*y^2 // Matches gnark-crypto curve specific params type CurveParams struct { A, D, Cofactor, Order *big.Int Base [2]*big.Int // base point coordinates } ``` -------------------------------- ### EdDSA Signature Verification (Inside zk-SNARK Circuit) Source: https://docs.gnark.consensys.io/Tutorials/eddsa Illustrates the assertion of EdDSA signature validity within a zk-SNARK circuit using an `isValid` function, which verifies the signature against the message and public key. ```Go assert(isValid(signature, message, publicKey)) ``` -------------------------------- ### Compute Left-Hand Side of EdDSA equality Source: https://docs.gnark.consensys.io/Tutorials/eddsa Calculates the left-hand side of the EdDSA verification equality, which is [2^c*S]G. This involves multiple scalar multiplications using `ScalarMulFixedBase` (for fixed base points) and `ScalarMulNonFixedBase` (for variable points), followed by point additions. ```Go // [2^basis*S1]G lhs.ScalarMulFixedBase(cs, pubKey.Curve.BaseX, pubKey.Curve.BaseY, sig.S1, pubKey.Curve). ScalarMulNonFixedBase(cs, &lhs, basis, pubKey.Curve) // [S2]G tmp := twistededwards.Point{} tmp.ScalarMulFixedBase(cs, pubKey.Curve.BaseX, pubKey.Curve.BaseY, sig.S2, pubKey.Curve) // [2^basis*S1 + S2]G lhs.AddGeneric(cs, &lhs, &tmp, pubKey.Curve) // [2^c*(2^basis*S1 + S2)]G lhs.ScalarMulNonFixedBase(cs, &lhs, cofactorConstant, pubKey.Curve) lhs.MustBeOnCurve(cs, pubKey.Curve) ``` -------------------------------- ### Binary Protocol Specification for gnark Witnesses Source: https://docs.gnark.consensys.io/HowTo/serialize Defines the binary encoding format for gnark full and public witnesses. It specifies the sequence of uint32 length fields for public, private, and total elements, followed by the actual variable data. Each field element is encoded as a big-endian byte array matching the modulus length. ```APIDOC // Full witness -> [uint32(nbPublicElements) | uint32(nbPrivateElements) | uint32(nbElements) | publicVariables | secretVariables] // Public witness -> [uint32(nbElements) | publicVariables ] ``` -------------------------------- ### Compute Right-Hand Side of EdDSA equality Source: https://docs.gnark.consensys.io/Tutorials/eddsa Calculates the right-hand side of the EdDSA verification equality: [2^c]R + [2^cH(R,A,M)]A. This step involves scalar multiplications of the public key (A) and signature component (R) with the hash output and cofactor, followed by point additions. ```Go //rhs = [2^c]R+[2^cH(R,A,M)]A // M: message // A: public key // R: from the signature (R,S) rhs := twistededwards.Point{} rhs.ScalarMulNonFixedBase(cs, &pubKey.A, hramConstant, pubKey.Curve). AddGeneric(cs, &rhs, &sig.R.A, pubKey.Curve). ScalarMulNonFixedBase(cs, &rhs, cofactorConstant, pubKey.Curve) rhs.MustBeOnCurve(cs, pubKey.Curve) ``` -------------------------------- ### Use gnark Struct Tag to Omit Variable Source: https://docs.gnark.consensys.io/HowTo/write/circuit_structure The `gnark:"-"` struct tag allows a `frontend.Variable` field to be omitted from the constraint system during compilation. This is useful when a variable is referenced multiple times but should only be instantiated once, preventing redundant variable declarations. ```Go // omits Y, frontend.Compile will not instantiate a new variable in the ConstraintSystem // this can be useful when a Variable is referenced in multiple places but we only wish to instantiate it once Y frontend.Variable `gnark:"-"` ``` -------------------------------- ### Common gnark Constraint Not Satisfied Error Source: https://docs.gnark.consensys.io/HowTo/debug_test This snippet shows a common error message encountered when the solver cannot satisfy a constraint with the provided witness, indicating an issue with the circuit logic or witness values. ```Text constraint is not satisfied: [(.. * ..) != (.. * ..) + (.. * ..) + (.. * ..)] ``` -------------------------------- ### Go Struct for EdDSA Signature in gnark Source: https://docs.gnark.consensys.io/Tutorials/eddsa Defines the `Signature` struct for use in `gnark` circuits. An EdDSA signature is represented as a tuple (R,S), where R is a `twistededwards.Point` on the twisted Edwards curve and S is a `frontend.Variable` scalar. The description also notes the properties of the subgroup `l` used in EdDSA to prevent overflow. ```Go import "github.com/consensys/gnark/frontend" // Signature stores a signature (to be used in gnark circuit) // An EdDSA signature is a tuple (R,S) where R is a point on the twisted Edwards curve // and S a scalar. Since the base field of the twisted Edwards is Fr, the number of points // N on the Edwards is < r+1+2sqrt(r)+2 (since the curve has 2 points of multiplicity 2). // The subgroup l used in eddsa is <1/2N, so the reduction // mod l ensures S < r, therefore there is no risk of overflow. type Signature struct { R twistededwards.Point S frontend.Variable } ``` -------------------------------- ### Assert equality of LHS and RHS using gnark API Source: https://docs.gnark.consensys.io/Tutorials/eddsa Asserts that the computed left-hand side (lhs) and right-hand side (rhs) of the EdDSA equality are equal. Since `AssertIsEqual` does not work on arbitrary structures, equality is enforced by comparing the X and Y coordinates of the points individually. ```Go // ensures that lhs==rhs api.AssertIsEqual(lhs.X, rhs.X) api.AssertIsEqual(lhs.Y, rhs.Y) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.