From 16672072dcf42a6f18c9e10efbd0c70f649c871c Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Fri, 3 Nov 2023 17:26:52 +0100 Subject: [PATCH] PLONK WIP --- std/recursion/plonk/verifier.go | 30 +++++++++++++++++----------- std/recursion/plonk/verifier_test.go | 17 ++++++++-------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/std/recursion/plonk/verifier.go b/std/recursion/plonk/verifier.go index d360868d05..8c5533f07b 100644 --- a/std/recursion/plonk/verifier.go +++ b/std/recursion/plonk/verifier.go @@ -2,6 +2,8 @@ package plonk import ( "fmt" + "math/big" + "strconv" fr_bls12377 "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" fr_bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" @@ -20,6 +22,7 @@ import ( "github.com/consensys/gnark/std/commitments/kzg" fiatshamir "github.com/consensys/gnark/std/fiat-shamir" "github.com/consensys/gnark/std/hash" + "github.com/consensys/gnark/std/math/bits" "github.com/consensys/gnark/std/math/emulated" "github.com/consensys/gnark/std/recursion" ) @@ -253,30 +256,34 @@ func PlaceholderWitness[FR emulated.FieldParams](ccs constraint.ConstraintSystem type Verifier[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT] struct { api frontend.API + scalars *emulated.Field[FR] curve algebra.Curve[FR, G1El] pairing algebra.Pairing[G1El, G2El, GtEl] kzgHash hash.FieldHasher - fsHash hash.FieldHasher htfHash hash.FieldHasher } -func NewVerifier[ - FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT]( +func NewVerifier[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT]( api frontend.API, curve algebra.Curve[FR, G1El], pairing algebra.Pairing[G1El, G2El, GtEl], - fsHash hash.FieldHasher) *Verifier[FR, G1El, G2El, GtEl] { +) (*Verifier[FR, G1El, G2El, GtEl], error) { + f, err := emulated.NewField[FR](api) + if err != nil { + return nil, fmt.Errorf("new scalars: %w", err) + } return &Verifier[FR, G1El, G2El, GtEl]{ api: api, + scalars: f, curve: curve, pairing: pairing, - fsHash: fsHash, - } + }, nil } func (v *Verifier[FR, G1El, G2El, GtEl]) AssertProof(vk VerifyingKey[FR, G1El, G2El], proof Proof[FR, G1El, G2El], witness Witness[FR]) error { + var fr FR if len(proof.Bsb22Commitments) != len(vk.Qcp) { return fmt.Errorf("BSB22 commitment number mismatch") } - fs, err := recursion.NewTranscript(v.api, nil, []string{"gamma", "beta", "alpha", "zeta"}) + fs, err := recursion.NewTranscript(v.api, fr.Modulus(), []string{"gamma", "beta", "alpha", "zeta"}) if err != nil { return fmt.Errorf("init new transcript: %w", err) } @@ -563,17 +570,16 @@ func (v *Verifier[FR, G1El, G2El, GtEl]) bindPublicData(fs *fiatshamir.Transcrip return nil } -func (v *Verifier[FR, G1El, G2El, GtEl]) deriveRandomness(fs *fiatshamir.Transcript, challenge string, points ...G1El) (emulated.Element[FR], error) { - var ret emulated.Element[FR] +func (v *Verifier[FR, G1El, G2El, GtEl]) deriveRandomness(fs *fiatshamir.Transcript, challenge string, points ...G1El) (*emulated.Element[FR], error) { for i := range points { if err := fs.Bind(challenge, v.curve.MarshalG1(points[i])); err != nil { - return ret, fmt.Errorf("bind challenge %d: %w", i, err) + return nil, fmt.Errorf("bind challenge %d: %w", i, err) } } b, err := fs.ComputeChallenge(challenge) if err != nil { - return ret, fmt.Errorf("compute challenge: %w", err) + return nil, fmt.Errorf("compute challenge: %w", err) } - _ = b + ret := v.scalars.FromBits(bits.ToBinary(v.api, b)) return ret, nil } diff --git a/std/recursion/plonk/verifier_test.go b/std/recursion/plonk/verifier_test.go index 4d394d0692..cc9c1452b9 100644 --- a/std/recursion/plonk/verifier_test.go +++ b/std/recursion/plonk/verifier_test.go @@ -63,12 +63,11 @@ type OuterCircuit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra Proof Proof[FR, G1El, G2El] VerifyingKey VerifyingKey[FR, G1El, G2El] InnerWitness Witness[FR] - - target *big.Int // TODO: remove later } -func (c *OuterCircuit[S, G1El, G2El, GtEl]) Define(api frontend.API) error { - curve, err := algebra.GetCurve[S, G1El](api) +func (c *OuterCircuit[FR, G1El, G2El, GtEl]) Define(api frontend.API) error { + var fr FR + curve, err := algebra.GetCurve[FR, G1El](api) if err != nil { return fmt.Errorf("new curve: %w", err) } @@ -76,12 +75,14 @@ func (c *OuterCircuit[S, G1El, G2El, GtEl]) Define(api frontend.API) error { if err != nil { return fmt.Errorf("get pairing: %w", err) } - // TODO: should do automatically but we need modulus. Hopefully Arithmetization returns it. - fsHhash, err := recursion.NewHash(api, c.target, true) + fsHhash, err := recursion.NewHash(api, fr.Modulus(), true) if err != nil { return fmt.Errorf("get hash: %w", err) } - verifier := NewVerifier(api, curve, pairing, fsHhash) + verifier, err := NewVerifier(api, curve, pairing, fsHhash) + if err != nil { + return fmt.Errorf("new verifier: %w", err) + } err = verifier.AssertProof(c.VerifyingKey, c.Proof, c.InnerWitness) return err } @@ -102,13 +103,11 @@ func TestBLS12InBW6(t *testing.T) { InnerWitness: PlaceholderWitness[sw_bls12377.ScalarField](innerCcs), Proof: PlaceholderProof[sw_bls12377.ScalarField, sw_bls12377.G1Affine, sw_bls12377.G2Affine](innerCcs), VerifyingKey: PlaceholderVerifyingKey[sw_bls12377.ScalarField, sw_bls12377.G1Affine, sw_bls12377.G2Affine](innerCcs), - target: ecc.BLS12_377.ScalarField(), } outerAssignment := &OuterCircuit[sw_bls12377.ScalarField, sw_bls12377.G1Affine, sw_bls12377.G2Affine, sw_bls12377.GT]{ InnerWitness: circuitWitness, Proof: circuitProof, VerifyingKey: circuitVk, - target: ecc.BLS12_377.ScalarField(), } assert.CheckCircuit(outerCircuit, test.WithValidAssignment(outerAssignment), test.WithCurves(ecc.BW6_761), test.NoFuzzing(), test.NoSerializationChecks(), test.NoSolidityChecks())