### Run Groth16 Setup (Go) Source: https://docs.gnark.consensys.net/Tutorials/eddsa Performs the Groth16 setup process, generating the proving key (pk) and verifying key (vk) based on the compiled R1CS of the EdDSA circuit. These keys are essential for proof generation and verification. ```go import ( "github.com/consensys/gnark/backend/groth16" ) // Assuming 'r1cs' is the compiled R1CS pk, vk, err := groth16.Setup(r1cs) ``` -------------------------------- ### Construct and Marshall Witnesses Source: https://docs.gnark.consensys.net/HowTo/serialize Provides an example of creating a witness from a circuit assignment and performing binary or JSON serialization for cross-process communication. ```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()) // Binary unmarshalling err := witness.UnmarshalBinary(data) // JSON unmarshalling err := witness.UnmarshalJSON(json) // extract the public part only publicWitness, _ := witness.Public() ``` -------------------------------- ### Perform zk-SNARK Proof Lifecycle with Groth16 and PlonK Source: https://docs.gnark.consensys.net/HowTo/prove Demonstrates the three-step process of Setup, Prove, and Verify using gnark's backend implementations. Groth16 is the standard implementation, while PlonK is currently experimental. ```go // Groth16 implementation pk, vk, err := groth16.Setup(cs) proof, err := groth16.Prove(cs, pk, witness) err := groth16.Verify(proof, vk, publicWitness) ``` ```go // PlonK implementation (WIP) publicData, _ := plonk.Setup(cs, ...) proof, err := plonk.Prove(r1cs, publicData, witness) err := plonk.Verify(proof, publicData, publicWitness) ``` -------------------------------- ### Implement Gnark Circuit Tests with Go Unit Tests Source: https://docs.gnark.consensys.net/HowTo/debug_test Provides an example of how to write Go unit tests for Gnark circuits. It utilizes the `test.NewAssert` helper to create an assertion object and demonstrates testing for prover success and failure scenarios. ```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)) ``` -------------------------------- ### Unit Test EdDSA Circuit Proof Assertion (Go) Source: https://docs.gnark.consensys.net/Tutorials/eddsa Provides an example of how to use Gnark's assertion helpers for unit testing EdDSA circuits. The `assert.ProverFailed` and `assert.ProverSucceeded` functions can be used to check if proof generation succeeds or fails as expected. ```go import ( "testing" "github.com/consensys/gnark/backend/groth16" ) // Assuming 't' is a *testing.T, 'circuit' is the circuit struct, and 'assignment' is the witness assignment assert := groth16.NewAssert(t) var circuit Circuit // Replace 'Circuit' with your actual circuit type // assert.ProverFailed(&circuit, &assignment) // Use this to assert that proving should fail // assert.ProverSucceeded(&circuit, &assignment) // Use this to assert that proving should succeed ``` -------------------------------- ### Construct a Circuit Witness Source: https://docs.gnark.consensys.net/HowTo/prove Shows how to define a circuit structure and assign values to variables to create a witness. The witness is then used as input for the prover. ```go type Circuit struct { X frontend.Variable Y frontend.Variable `gnark:",public"` } assignment := &Circuit { X: 3, Y: 35, } witness, _ := frontend.NewWitness(assignment, ecc.BN254) groth16.Prove(cs, pk, witness) ``` -------------------------------- ### Generate and Verify Proof Source: https://docs.gnark.consensys.net/overview Creates a witness from inputs, sets up the proving/verifying keys, generates a proof, and verifies it against the public witness. ```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) ``` -------------------------------- ### Handle Elliptic Curve Point Compression Source: https://docs.gnark.consensys.net/HowTo/serialize Shows how to toggle between raw serialization and compressed serialization for cryptographic objects like ProvingKeys, balancing CPU usage against 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. ``` -------------------------------- ### Decompose integer into bits using gnark hints Source: https://docs.gnark.consensys.net/HowTo/write/hints Demonstrates how to use a hint function to extract bits of an integer within a circuit. The code uses cs.NewHint to retrieve bits, constrains them as boolean, and verifies their weighted sum equals the original input. ```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) ``` -------------------------------- ### Profile gnark circuit constraints Source: https://docs.gnark.consensys.net/HowTo/profile This snippet demonstrates how to instrument a gnark circuit definition to generate a pprof profile. It uses profile.Start() and profile.Stop() to wrap the compilation process, allowing for the extraction of constraint counts and performance metrics. ```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() { p := profile.Start() _, _ = frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &Circuit{}) p.Stop() fmt.Println(p.NbConstraints()) fmt.Println(p.Top()) } ``` -------------------------------- ### Serialize and Deserialize gnark Objects Source: https://docs.gnark.consensys.net/HowTo/serialize Demonstrates how to serialize a compiled constraint system to a buffer and deserialize it back into a curve-typed object using the io.WriterTo and io.ReaderFrom interfaces. ```go // compile a circuit cs, err := frontend.Compile(ecc.BN254, r1cs.NewBuilder, &circuit) // cs implements io.WriterTo var buf bytes.Buffer cs.WriteTo(&buf) // instantiate a curve-typed object cs := groth16.NewCS(ecc.BN254) // cs implements io.ReaderFrom cs.ReadFrom(&buf) ``` -------------------------------- ### Perform Arithmetic Constraints Source: https://docs.gnark.consensys.net/HowTo/write/circuit_api Demonstrates how to perform arithmetic operations like multiplication and addition to define constraints such as cubic equations. The API supports variadic inputs for flexible constraint definition. ```go x3 := api.Mul(circuit.X, circuit.X, circuit.X) api.AssertIsEqual(circuit.Y, api.Add(x3, circuit.X, 5)) ``` ```go api.Mul(X, 2, api.Add(Y, Z, 42)) ``` -------------------------------- ### Verify Merkle Proofs in gnark Circuit Source: https://docs.gnark.consensys.net/HowTo/write/standard_library Illustrates the implementation of a Merkle proof verification circuit. It utilizes a hash function and the merkle.VerifyProof helper to validate data against a root hash. ```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 EdDSA Circuit Witness (Go) Source: https://docs.gnark.consensys.net/Tutorials/eddsa Creates a witness assignment for the EdDSA circuit using the previously generated EdDSA signature and public key. This involves assigning the public key bytes, signature, and message to the corresponding fields in the circuit assignment structure. ```go import ( "github.com/consensys/gnark-crypto/ecc" ) // Assuming 'publicKey' and 'signature' are previously generated EdDSA objects // Assuming 'msg' is the message that was signed // 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]) // Assuming PublicKey is 32 bytes for BN254 // assign signature values assignment.Signature.Assign(ecc.BN254, signature) ``` -------------------------------- ### Generate and Verify EdDSA Signature (Go) Source: https://docs.gnark.consensys.net/Tutorials/eddsa Demonstrates how to generate an EdDSA key pair, sign a message, and verify the signature using the `gnark-crypto` package. This is a prerequisite for creating the circuit's witness. ```go import ( "crypto/rand" "fmt" "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/hash" "github.com/consensys/gnark-crypto/signature/eddsa" "github.com/consensys/gnark/std/algebra/twistededwards" ) func main() { // instantiate hash function hFunc := hash.MIMC_BN254.New() // create a eddsa key pair privateKey, err := eddsa.New(twistededwards.BN254, rand.Reader) if err != nil { // handle error } 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) if err != nil { // handle error } // verifies signature isValid, err := publicKey.Verify(signature, msg, hFunc) if !isValid { fmt.Println("1. invalid signature") } else { fmt.Println("1. valid signature") } } ``` -------------------------------- ### Define Circuit Constraints Source: https://docs.gnark.consensys.net/HowTo/write/circuit_api The Define method is the entry point for circuit logic where the frontend.API is used to declare constraints. It takes an api object as an argument and returns an error. ```go func Define(api frontend.API) error ``` -------------------------------- ### Export Verifying Key to Solidity Source: https://docs.gnark.consensys.net/HowTo/prove Exports a Groth16 verifying key for the BN254 curve into a Solidity smart contract for on-chain verification on Ethereum. ```go cs, err := frontend.Compile(ecc.BN254, r1cs.NewBuilder, &myCircuit) pk, vk, err := groth16.Setup(cs) err = vk.ExportSolidity(f) ``` -------------------------------- ### Generate and Verify Groth16 Proof (Go) Source: https://docs.gnark.consensys.net/Tutorials/eddsa Generates a Groth16 proof for the EdDSA circuit using the compiled R1CS, proving key, and witness. It then verifies the generated proof using the verifying key and the public part of the witness. ```go import ( "github.com/consensys/gnark/frontend" "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark/backend/groth16" ) // Assuming 'r1cs', 'pk', 'vk', 'assignment' are previously defined and generated // 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 } ``` -------------------------------- ### Implement MiMC Hash in gnark Circuit Source: https://docs.gnark.consensys.net/HowTo/write/standard_library Demonstrates how to integrate the MiMC hash function within a gnark circuit. It uses the frontend.API to compute hashes over circuit variables. ```go func (circuit *mimcCircuit) Define(api frontend.API) error { // ... hFunc, _ := mimc.NewMiMC(api.Curve()) computedHash := hFunc.Hash(cs, circuit.Data) // ... } ``` -------------------------------- ### Compile a gnark circuit to R1CS Source: https://docs.gnark.consensys.net/HowTo/compile Uses frontend.Compile to translate a circuit struct into an arithmetic representation. It requires the target scalar field and a builder function to generate the constraint system. ```go var myCircuit Circuit r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &myCircuit) ``` -------------------------------- ### Unit Test Circuits Source: https://docs.gnark.consensys.net/overview Uses the gnark testing utility to verify that a circuit correctly fails or succeeds based on provided witness assignments. ```Go assert := groth16.NewAssert(t) var mimcCircuit Circuit { assert.ProverFailed(&mimcCircuit, &Circuit{ Hash: 42, PreImage: 42, }) } { assert.ProverSucceeded(&mimcCircuit, &Circuit{ Hash: "16130099170765464552823636852555369511329944820189892919423002775646948828469", PreImage: 35, }) } ``` -------------------------------- ### Implement EdDSA Circuit Verification Logic (Go) Source: https://docs.gnark.consensys.net/Tutorials/eddsa Implements the `Define` function for the EdDSA circuit, which orchestrates the verification of an EdDSA signature. It initializes the curve and hash function, then calls the `eddsa.Verify` function to check the signature against the public key and message. ```go import ( "github.com/consensys/gnark/std/algebra/twistededwards" "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark/std/hash/mimc" ) func (circuit *eddsaCircuit) Define(api frontend.API) error { curve, err := twistededwards.NewEdCurve(api, circuit.curveID) // Assuming curveID is a field in eddsaCircuit 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) } ``` -------------------------------- ### Define Witness Binary Protocol Structure Source: https://docs.gnark.consensys.net/HowTo/serialize Outlines the binary layout for full and public witnesses, including the sequence of public and secret elements encoded as big-endian byte arrays. ```text // Full witness -> [uint32(nbPublicElements) | uint32(nbPrivateElements) | uint32(nbElements) | publicVariables | secretVariables] // Public witness -> [uint32(nbElements) | publicVariables ] ``` -------------------------------- ### Compile EdDSA Circuit (Go) Source: https://docs.gnark.consensys.net/Tutorials/eddsa Compiles the EdDSA circuit into its R1CS (Rank-1 Constraint System) representation using Gnark's `frontend.Compile` function. The R1CS is an arithmetized version of the circuit, defining the constraints that the prover must satisfy. ```go import ( "github.com/consensys/gnark/backend/r1cs" "github.com/consensys/gnark/frontend" "github.com/consensys/gnark-crypto/ecc" ) // Assuming 'circuit' is an instance of eddsaCircuit var circuit eddsaCircuit r1cs, err := frontend.Compile(ecc.BN254, r1cs.NewBuilder, &circuit) ``` -------------------------------- ### Compile gnark Circuit Source: https://docs.gnark.consensys.net/overview Compiles the defined circuit structure into a Rank-1 Constraint System (R1CS) using the specified elliptic curve and builder. ```Go var mimcCircuit Circuit r1cs, err := frontend.Compile(ecc.BN254, r1cs.NewBuilder, &mimcCircuit) ``` -------------------------------- ### Execute Circuits Without Prover in Gnark Source: https://docs.gnark.consensys.net/HowTo/debug_test Demonstrates how to use the `test.IsSolved` function to execute a circuit in plain Go without engaging the zk-SNARK prover. This is recommended for a faster development workflow. ```go err := test.IsSolved(circuit, witness, field) ``` -------------------------------- ### Verify EdDSA Signatures in gnark Circuit Source: https://docs.gnark.consensys.net/HowTo/write/standard_library Shows the structure of an EdDSA circuit and the usage of eddsa.Verify to validate signatures. It requires defining public keys, signatures, and messages as circuit variables. ```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 } ``` -------------------------------- ### Implement conditional logic using api.Select Source: https://docs.gnark.consensys.net/HowTo/write/instructions Since gnark uses a declarative API, standard if/else statements are not supported. Instead, use api.Select to choose between two values based on a boolean variable. ```go // Select if b is true, yields i1 else yields i2 func (cs *ConstraintSystem) Select(b Variable, i1, i2 interface{}) Variable { ``` -------------------------------- ### Verify Groth16 Proofs in gnark Circuit Source: https://docs.gnark.consensys.net/HowTo/write/standard_library Enables recursive verification of a BLS12-377 Groth16 proof within a BW6-761 circuit. It uses the groth16.Verify function to perform the verification inside the circuit definition. ```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 } ``` -------------------------------- ### EdDSA Signing Outside zk-SNARK Source: https://docs.gnark.consensys.net/Tutorials/eddsa Demonstrates the process of signing a message using an EdDSA private key, which occurs outside the zk-SNARK circuit. This step generates the signature that will later be verified within the circuit. ```go privateKey, publicKey := eddsa.New(..) signature := privateKey.Sign(message) ``` -------------------------------- ### Define EdDSA Circuit Structure (Go) Source: https://docs.gnark.consensys.net/Tutorials/eddsa Defines the structure for an EdDSA circuit, specifying public inputs for the public key, signature, and message. This structure is essential for representing the mathematical statement to be verified within the zk-SNARK. ```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"` } ``` -------------------------------- ### Print Circuit Values During Debugging in Gnark Source: https://docs.gnark.consensys.net/HowTo/debug_test Shows how to use `api.Println()` for debugging circuits in Gnark. This function behaves similarly to `fmt.Println` but outputs values only when they are solved, aiding in identifying issues. ```go api.Println("A.X", pubKey.A.X) ``` -------------------------------- ### Handle Constraint Satisfaction Errors in Gnark Source: https://docs.gnark.consensys.net/HowTo/debug_test This snippet illustrates a common error encountered when the Gnark solver cannot satisfy a constraint with the provided witness. It highlights the format of the error message and suggests enabling debug tags for more verbose output. ```text constraint is not satisfied: [(.. * ..) != (.. * ..) + (.. * ..) + (.. * ..)] ``` -------------------------------- ### Implement loops in gnark circuits Source: https://docs.gnark.consensys.net/HowTo/write/instructions Standard Go for-loops can be used within the Define method to unroll constraints. Note that the loop's impact on the constraint system is equivalent to manually unrolling the operations. ```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 } ``` -------------------------------- ### EdDSA Signature Verification Inside zk-SNARK Source: https://docs.gnark.consensys.net/Tutorials/eddsa Illustrates the assertion of a valid EdDSA signature within a zk-SNARK circuit. This is the core verification step that ensures the signature corresponds to the message and public key. ```go assert(isValid(signature, message, publicKey)) ``` -------------------------------- ### Compute H(R, A, M) using MiMC Hash in Gnark Source: https://docs.gnark.consensys.net/Tutorials/eddsa Implements the computation of H(R, A, M), a crucial part of the EdDSA verification equation, using the MiMC hash function. It takes the curve, signature, message, public key, and hash function as input, and returns an error if any issues arise during computation. ```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 zk-SNARK Circuit in Go Source: https://docs.gnark.consensys.net/overview Defines a circuit structure and its constraints using the gnark frontend API. The Define method specifies the mathematical relationships between secret inputs and public outputs. ```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 } ``` -------------------------------- ### Gnark Circuit Input Declaration Source: https://docs.gnark.consensys.net/HowTo/write/circuit_structure Illustrates how to declare public and secret inputs for a gnark circuit using `frontend.Variable`. Public inputs are marked with `gnark:",public"`. ```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 } ``` -------------------------------- ### Gnark Circuit Interface Definition Source: https://docs.gnark.consensys.net/HowTo/write/circuit_structure Defines the `Circuit` interface in gnark, which requires implementing the `Define` method to declare the circuit's constraints using the provided API. ```go type Circuit interface { // Define declares the circuit's Constraints Define(api frontend.API) error } ``` -------------------------------- ### Twisted Edwards Curve Parameters Structure Source: https://docs.gnark.consensys.net/Tutorials/eddsa Defines the `CurveParams` struct to hold parameters for twisted Edwards curves, such as A, D, Cofactor, Order, and Base point coordinates. This structure is crucial for defining curves compatible with `gnark-crypto`. ```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 } ``` -------------------------------- ### Gnark Struct Tag for Omitting Variables Source: https://docs.gnark.consensys.net/HowTo/write/circuit_structure Demonstrates the use of the `gnark:"-"` struct tag in gnark. This tag prevents `frontend.Compile` from instantiating a variable in the ConstraintSystem, useful for variables referenced multiple times. ```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:"-"` ``` -------------------------------- ### Assert Equality of LHS and RHS in Gnark Circuit Source: https://docs.gnark.consensys.net/Tutorials/eddsa Enforces the equality between the left-hand side (LHS) and right-hand side (RHS) of the EdDSA verification equation within the Gnark circuit. It uses `api.AssertIsEqual` on the X and Y coordinates individually, as direct structure comparison is not supported. ```go // ensures that lhs==rhs api.AssertIsEqual(lhs.X, rhs.X) api.AssertIsEqual(lhs.Y, rhs.Y) ``` -------------------------------- ### EdDSA PublicKey Structure for gnark Circuit Source: https://docs.gnark.consensys.net/Tutorials/eddsa Defines the `PublicKey` struct for use within a `gnark` circuit. It includes the public key point on the twisted Edwards curve, represented by `twistededwards.Point`. ```go package eddsa import "github.com/consensys/gnark/std/algebra/twistededwards" type PublicKey struct { A twistededwards.Point } ``` -------------------------------- ### Compute Left-Hand Side of EdDSA Verification Equation Source: https://docs.gnark.consensys.net/Tutorials/eddsa Calculates the left-hand side (LHS) of the EdDSA verification equation: [2c*S]G. This involves scalar multiplications and point additions on the twisted Edwards curve. It utilizes `ScalarMulFixedBase` for constant coordinates and `ScalarMulNonFixedBase` for variable coordinates, optimizing constraint usage. ```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) ``` -------------------------------- ### Define EdDSA Signature Verification Function Signature Source: https://docs.gnark.consensys.net/Tutorials/eddsa Defines the function signature for EdDSA signature verification, specifying the required inputs: an API object, the signature, the message, and the public key. This sets up the structure for implementing the verification logic. ```go func Verify(api frontend.API, sig Signature, msg frontend.Variable, pubKey PublicKey) error { // ... } ``` -------------------------------- ### EdDSA Signature Structure for gnark Circuit Source: https://docs.gnark.consensys.net/Tutorials/eddsa Defines the `Signature` struct for representing an EdDSA signature within a `gnark` circuit. It comprises a point `R` on the twisted Edwards curve and a scalar `S`. ```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 } ``` -------------------------------- ### Compute Right-Hand Side of EdDSA Verification Equation Source: https://docs.gnark.consensys.net/Tutorials/eddsa Computes the right-hand side (RHS) of the EdDSA verification equation: [2c]R + [2cH(R,A,M)]A. This involves scalar multiplications and point additions, similar to the LHS computation. The function uses the previously computed hash value `hramConstant`. ```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) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.