From 25f044c08cff09570730e264e5f1a7cbaa57b9c8 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 01:38:15 +0100 Subject: [PATCH 01/19] feat: use options for fiat-shamir --- fiat-shamir/options.go | 35 +++++++++++++++++++++ fiat-shamir/transcript.go | 66 ++++++++++++++++++++++++++------------- 2 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 fiat-shamir/options.go diff --git a/fiat-shamir/options.go b/fiat-shamir/options.go new file mode 100644 index 000000000..3e9832ae1 --- /dev/null +++ b/fiat-shamir/options.go @@ -0,0 +1,35 @@ +package fiatshamir + +type transcriptConfig struct { + withDomainSeparation bool + fixedChallenges []string +} + +// TranscriptOption allows modifying the [Transcript] operation. +type TranscriptOption func(tc *transcriptConfig) error + +// WithDomainSeparation adds domain separation string `string:` when hashing +// challenge name as defined in RCF 9380. +func WithDomainSeparation() TranscriptOption { + return func(tc *transcriptConfig) error { + tc.withDomainSeparation = true + return nil + } +} + +// WithStaticChallenges fixes the allowed challenges. Otherwise challenges are +// appended when bound. +func WithStaticChallenges(challenges ...string) TranscriptOption { + return func(tc *transcriptConfig) error { + tc.fixedChallenges = challenges + return nil + } +} + +func newConfig(opts ...TranscriptOption) *transcriptConfig { + tc := &transcriptConfig{} + for _, opt := range opts { + opt(tc) + } + return tc +} diff --git a/fiat-shamir/transcript.go b/fiat-shamir/transcript.go index 110d8aed5..e43c44e26 100644 --- a/fiat-shamir/transcript.go +++ b/fiat-shamir/transcript.go @@ -16,6 +16,7 @@ package fiatshamir import ( "errors" + "fmt" "hash" ) @@ -33,6 +34,8 @@ type Transcript struct { challenges map[string]challenge previous *challenge + + config *transcriptConfig } type challenge struct { @@ -45,17 +48,19 @@ type challenge struct { // NewTranscript returns a new transcript. // h is the hash function that is used to compute the challenges. // challenges are the name of the challenges. The order of the challenges IDs matters. -func NewTranscript(h hash.Hash, challengesID ...string) Transcript { - n := len(challengesID) - t := Transcript{ - challenges: make(map[string]challenge, n), - h: h, +func NewTranscript(h hash.Hash, opts ...TranscriptOption) *Transcript { + cfg := newConfig(opts...) + challenges := make(map[string]challenge) + if cfg.fixedChallenges != nil { + for i := range cfg.fixedChallenges { + challenges[cfg.fixedChallenges[i]] = challenge{position: i} + } } - - for i := 0; i < n; i++ { - t.challenges[challengesID[i]] = challenge{position: i} + t := &Transcript{ + challenges: challenges, + h: h, + config: cfg, } - return t } @@ -65,19 +70,24 @@ func NewTranscript(h hash.Hash, challengesID ...string) Transcript { // binded to other values. func (t *Transcript) Bind(challengeID string, bValue []byte) error { - challenge, ok := t.challenges[challengeID] + currentChallenge, ok := t.challenges[challengeID] if !ok { - return errChallengeNotFound + if t.config.fixedChallenges != nil { + return errChallengeNotFound + } else { + t.challenges[challengeID] = challenge{position: len(t.challenges)} + currentChallenge = t.challenges[challengeID] + } } - if challenge.isComputed { + if currentChallenge.isComputed { return errChallengeAlreadyComputed } bCopy := make([]byte, len(bValue)) copy(bCopy, bValue) - challenge.bindings = append(challenge.bindings, bCopy) - t.challenges[challengeID] = challenge + currentChallenge.bindings = append(currentChallenge.bindings, bCopy) + t.challenges[challengeID] = currentChallenge return nil @@ -103,15 +113,27 @@ func (t *Transcript) ComputeChallenge(challengeID string) ([]byte, error) { t.h.Reset() defer t.h.Reset() - // write the challenge name, the purpose is to have a domain separator - if hashToField, ok := t.h.(interface { - WriteString(rawBytes []byte) - }); ok { - hashToField.WriteString([]byte(challengeID)) // TODO: Replace with a function returning field identifier, whence we can find the correct hash to field function. Better than confusingly embedding hash to field into another hash - } else { - if _, err := t.h.Write([]byte(challengeID)); err != nil { - return nil, err + htf, ok := t.h.(interface{ WriteString(rawBytes []byte) error }) + switch { + case t.config.withDomainSeparation && ok: + // requested domain separation and the hash function has the method + if err := htf.WriteString([]byte(challengeID)); err != nil { + return nil, fmt.Errorf("write string: %w", err) + } + case t.config.withDomainSeparation && !ok: + // problem - we requested domain separation buth the hash function + // doesn't provide WriteString method (which does hash to field + // internally). + return nil, fmt.Errorf("hash function doesn't provide challenge domain separation") + case len(challengeID) > t.h.BlockSize(): + return nil, fmt.Errorf("challenge name exceeds domain size") + default: + tmp := make([]byte, t.h.BlockSize()) + copy(tmp[t.h.BlockSize()-len(challengeID):], []byte(challengeID)) + if _, err := t.h.Write(tmp[:]); err != nil { + return nil, fmt.Errorf("write: %w", err) } + } // write the previous challenge if it's not the first challenge From 4139807b16bd62865c38bd02c448d57745716278 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 01:38:36 +0100 Subject: [PATCH 02/19] test: implement FS test with options --- fiat-shamir/transcript_test.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fiat-shamir/transcript_test.go b/fiat-shamir/transcript_test.go index 8b929f57d..f2ca5b9bb 100644 --- a/fiat-shamir/transcript_test.go +++ b/fiat-shamir/transcript_test.go @@ -20,9 +20,9 @@ import ( "testing" ) -func initTranscript() Transcript { +func initTranscript() *Transcript { - fs := NewTranscript(sha256.New(), "alpha", "beta", "gamma") + fs := NewTranscript(sha256.New(), WithStaticChallenges("alpha", "beta", "gamma")) values := [][]byte{[]byte("v1"), []byte("v2"), []byte("v3"), []byte("v4"), []byte("v5"), []byte("v6")} if err := fs.Bind("alpha", values[0]); err != nil { @@ -139,3 +139,10 @@ func TestBindToComputedChallenge(t *testing.T) { } } + +func TestDynamicChallenges(t *testing.T) { + ts := NewTranscript(sha256.New()) + if err := ts.Bind("alpha", []byte("test")); err != nil { + t.Fatal(err) + } +} From 7d4c4acd663ad0f5a7ec99fe8e222b87498ddd04 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 01:39:20 +0100 Subject: [PATCH 03/19] chore: return error for writeString instead of panic --- internal/generator/crypto/hash/mimc/template/mimc.go.tmpl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/generator/crypto/hash/mimc/template/mimc.go.tmpl b/internal/generator/crypto/hash/mimc/template/mimc.go.tmpl index f396c8644..6e1b2a8d8 100644 --- a/internal/generator/crypto/hash/mimc/template/mimc.go.tmpl +++ b/internal/generator/crypto/hash/mimc/template/mimc.go.tmpl @@ -227,10 +227,11 @@ func initConstants() { } // WriteString writes a string that doesn't necessarily consist of field elements -func (d *digest) WriteString(rawBytes []byte) { +func (d *digest) WriteString(rawBytes []byte) error { if elems, err := fr.Hash(rawBytes, []byte("string:"), 1); err != nil { - panic(err) + return err } else { d.data = append(d.data, elems[0]) } + return nil } From 3920d8e79fc8be5ef8472dafec1051e5fb7d529d Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 01:39:45 +0100 Subject: [PATCH 04/19] chore: use options in templates --- internal/generator/fri/template/fri.go.tmpl | 4 ++-- internal/generator/gkr/template/gkr.go.tmpl | 4 +--- internal/generator/kzg/template/kzg.go.tmpl | 2 +- .../pedersen/template/pedersen.go.tmpl | 2 +- .../permutation/template/permutation.go.tmpl | 16 +++++++-------- .../generator/plookup/template/table.go.tmpl | 8 ++++---- .../generator/plookup/template/vector.go.tmpl | 20 +++++++++---------- .../sumcheck/template/sumcheck.go.tmpl | 3 +-- .../small_rational/gkr/gkr.go | 4 +--- .../small_rational/sumcheck/sumcheck.go | 3 +-- 10 files changed, 30 insertions(+), 36 deletions(-) diff --git a/internal/generator/fri/template/fri.go.tmpl b/internal/generator/fri/template/fri.go.tmpl index f226f87a4..ecee08ed5 100644 --- a/internal/generator/fri/template/fri.go.tmpl +++ b/internal/generator/fri/template/fri.go.tmpl @@ -381,7 +381,7 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -535,7 +535,7 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/internal/generator/gkr/template/gkr.go.tmpl b/internal/generator/gkr/template/gkr.go.tmpl index 6a09ac332..9a00516cd 100644 --- a/internal/generator/gkr/template/gkr.go.tmpl +++ b/internal/generator/gkr/template/gkr.go.tmpl @@ -475,9 +475,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/internal/generator/kzg/template/kzg.go.tmpl b/internal/generator/kzg/template/kzg.go.tmpl index 632c47c2b..fa83fbe8e 100644 --- a/internal/generator/kzg/template/kzg.go.tmpl +++ b/internal/generator/kzg/template/kzg.go.tmpl @@ -538,7 +538,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, "gamma") + fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/internal/generator/pedersen/template/pedersen.go.tmpl b/internal/generator/pedersen/template/pedersen.go.tmpl index c84d17559..bcbf6951c 100644 --- a/internal/generator/pedersen/template/pedersen.go.tmpl +++ b/internal/generator/pedersen/template/pedersen.go.tmpl @@ -207,7 +207,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), "r") + t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/internal/generator/permutation/template/permutation.go.tmpl b/internal/generator/permutation/template/permutation.go.tmpl index 9ef791a63..6dd466c1c 100644 --- a/internal/generator/permutation/template/permutation.go.tmpl +++ b/internal/generator/permutation/template/permutation.go.tmpl @@ -138,7 +138,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // commit t1, t2 ct1 := make([]fr.Element, s) @@ -159,7 +159,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive challenge for z - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return proof, err } @@ -188,7 +188,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { lsNum := evaluateSecondPartNumReverse(lz, d) // derive challenge used for the folding - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return proof, err } @@ -211,7 +211,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive the evaluation challenge - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return proof, err } @@ -261,20 +261,20 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // derive the challenges - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return err } - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return err } - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return err } diff --git a/internal/generator/plookup/template/table.go.tmpl b/internal/generator/plookup/template/table.go.tmpl index 29f0339bf..3d4459c66 100644 --- a/internal/generator/plookup/template/table.go.tmpl +++ b/internal/generator/plookup/template/table.go.tmpl @@ -52,7 +52,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check the sizes if len(f) != len(t) { @@ -127,7 +127,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, comms[nbRows+i] = new(kzg.Digest) comms[nbRows+i].Set(&proof.ts[i]) } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return proof, err } @@ -165,7 +165,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { @@ -179,7 +179,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { comms[i] = &proof.fs[i] comms[i+nbRows] = &proof.ts[i] } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return err } diff --git a/internal/generator/plookup/template/vector.go.tmpl b/internal/generator/plookup/template/vector.go.tmpl index 1970b864f..4c596a51e 100644 --- a/internal/generator/plookup/template/vector.go.tmpl +++ b/internal/generator/plookup/template/vector.go.tmpl @@ -346,7 +346,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // create domains var domainSmall *fft.Domain @@ -424,11 +424,11 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // derive beta, gamma - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return proof, err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return proof, err } @@ -478,7 +478,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er lh1h2 := evaluateOverlapH1h2BitReversed(_lh1, _lh2, domainBig) // compute the quotient - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return proof, err } @@ -489,7 +489,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // build the opening proofs - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return proof, err } @@ -550,25 +550,25 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // derive the various challenges - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return err } - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return err } - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return err } diff --git a/internal/generator/sumcheck/template/sumcheck.go.tmpl b/internal/generator/sumcheck/template/sumcheck.go.tmpl index 80881bdcc..90a60cb02 100644 --- a/internal/generator/sumcheck/template/sumcheck.go.tmpl +++ b/internal/generator/sumcheck/template/sumcheck.go.tmpl @@ -48,8 +48,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) } for i := range settings.BaseChallenges { diff --git a/internal/generator/test_vector_utils/small_rational/gkr/gkr.go b/internal/generator/test_vector_utils/small_rational/gkr/gkr.go index ae7261e52..839abf2e7 100644 --- a/internal/generator/test_vector_utils/small_rational/gkr/gkr.go +++ b/internal/generator/test_vector_utils/small_rational/gkr/gkr.go @@ -490,9 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/internal/generator/test_vector_utils/small_rational/sumcheck/sumcheck.go b/internal/generator/test_vector_utils/small_rational/sumcheck/sumcheck.go index 4f33c8017..236d7fbd6 100644 --- a/internal/generator/test_vector_utils/small_rational/sumcheck/sumcheck.go +++ b/internal/generator/test_vector_utils/small_rational/sumcheck/sumcheck.go @@ -66,8 +66,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) } for i := range settings.BaseChallenges { From 8bfdb2f31280eb34e2c316b89a10d62fec334990 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 01:41:03 +0100 Subject: [PATCH 05/19] test: implement FS test with options --- ecc/bn254/fr/mimc/mimc_test.go | 5 +++-- ecc/bn254/fr/test_vector_utils/test_vector_utils_test.go | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ecc/bn254/fr/mimc/mimc_test.go b/ecc/bn254/fr/mimc/mimc_test.go index 11c693852..5df2c442a 100644 --- a/ecc/bn254/fr/mimc/mimc_test.go +++ b/ecc/bn254/fr/mimc/mimc_test.go @@ -1,14 +1,15 @@ package mimc_test import ( + "testing" + "github.com/consensys/gnark-crypto/ecc/bn254/fr/mimc" fiatshamir "github.com/consensys/gnark-crypto/fiat-shamir" "github.com/stretchr/testify/assert" - "testing" ) func TestMiMCFiatShamir(t *testing.T) { - fs := fiatshamir.NewTranscript(mimc.NewMiMC(), "c0") + fs := fiatshamir.NewTranscript(mimc.NewMiMC(), fiatshamir.WithStaticChallenges("c0")) zero := make([]byte, mimc.BlockSize) err := fs.Bind("c0", zero) assert.NoError(t, err) diff --git a/ecc/bn254/fr/test_vector_utils/test_vector_utils_test.go b/ecc/bn254/fr/test_vector_utils/test_vector_utils_test.go index dc14edf51..15c01a7e5 100644 --- a/ecc/bn254/fr/test_vector_utils/test_vector_utils_test.go +++ b/ecc/bn254/fr/test_vector_utils/test_vector_utils_test.go @@ -1,16 +1,17 @@ package test_vector_utils import ( + "testing" + fiatshamir "github.com/consensys/gnark-crypto/fiat-shamir" "github.com/consensys/gnark-crypto/internal/generator/test_vector_utils/small_rational/test_vector_utils" "github.com/stretchr/testify/assert" - "testing" ) func TestCounterTranscriptInequality(t *testing.T) { const challengeName = "fC.0" - t1 := fiatshamir.NewTranscript(test_vector_utils.NewMessageCounter(1, 1), challengeName) - t2 := fiatshamir.NewTranscript(test_vector_utils.NewMessageCounter(0, 1), challengeName) + t1 := fiatshamir.NewTranscript(test_vector_utils.NewMessageCounter(1, 1), fiatshamir.WithStaticChallenges(challengeName)) + t2 := fiatshamir.NewTranscript(test_vector_utils.NewMessageCounter(0, 1), fiatshamir.WithStaticChallenges(challengeName)) var c1, c2 []byte var err error c1, err = t1.ComputeChallenge(challengeName) From 819aeb41bc5183f4182b5668354a3e5536d3f390 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 01:42:25 +0100 Subject: [PATCH 06/19] chore: go generate --- ecc/bls12-377/fr/fri/fri.go | 4 ++-- ecc/bls12-377/fr/gkr/gkr.go | 4 +--- ecc/bls12-377/fr/mimc/mimc.go | 5 +++-- ecc/bls12-377/fr/pedersen/pedersen.go | 2 +- ecc/bls12-377/fr/permutation/permutation.go | 16 ++++++++-------- ecc/bls12-377/fr/plookup/table.go | 8 ++++---- ecc/bls12-377/fr/plookup/vector.go | 20 ++++++++++---------- ecc/bls12-377/fr/sumcheck/sumcheck.go | 3 +-- ecc/bls12-377/kzg/kzg.go | 2 +- ecc/bls12-378/fr/fri/fri.go | 4 ++-- ecc/bls12-378/fr/gkr/gkr.go | 4 +--- ecc/bls12-378/fr/mimc/mimc.go | 5 +++-- ecc/bls12-378/fr/pedersen/pedersen.go | 2 +- ecc/bls12-378/fr/permutation/permutation.go | 16 ++++++++-------- ecc/bls12-378/fr/plookup/table.go | 8 ++++---- ecc/bls12-378/fr/plookup/vector.go | 20 ++++++++++---------- ecc/bls12-378/fr/sumcheck/sumcheck.go | 3 +-- ecc/bls12-378/kzg/kzg.go | 2 +- ecc/bls12-381/fr/fri/fri.go | 4 ++-- ecc/bls12-381/fr/gkr/gkr.go | 4 +--- ecc/bls12-381/fr/mimc/mimc.go | 5 +++-- ecc/bls12-381/fr/pedersen/pedersen.go | 2 +- ecc/bls12-381/fr/permutation/permutation.go | 16 ++++++++-------- ecc/bls12-381/fr/plookup/table.go | 8 ++++---- ecc/bls12-381/fr/plookup/vector.go | 20 ++++++++++---------- ecc/bls12-381/fr/sumcheck/sumcheck.go | 3 +-- ecc/bls12-381/kzg/kzg.go | 2 +- ecc/bls24-315/fr/fri/fri.go | 4 ++-- ecc/bls24-315/fr/gkr/gkr.go | 4 +--- ecc/bls24-315/fr/mimc/mimc.go | 5 +++-- ecc/bls24-315/fr/pedersen/pedersen.go | 2 +- ecc/bls24-315/fr/permutation/permutation.go | 16 ++++++++-------- ecc/bls24-315/fr/plookup/table.go | 8 ++++---- ecc/bls24-315/fr/plookup/vector.go | 20 ++++++++++---------- ecc/bls24-315/fr/sumcheck/sumcheck.go | 3 +-- ecc/bls24-315/kzg/kzg.go | 2 +- ecc/bls24-317/fr/fri/fri.go | 4 ++-- ecc/bls24-317/fr/gkr/gkr.go | 4 +--- ecc/bls24-317/fr/mimc/mimc.go | 5 +++-- ecc/bls24-317/fr/pedersen/pedersen.go | 2 +- ecc/bls24-317/fr/permutation/permutation.go | 16 ++++++++-------- ecc/bls24-317/fr/plookup/table.go | 8 ++++---- ecc/bls24-317/fr/plookup/vector.go | 20 ++++++++++---------- ecc/bls24-317/fr/sumcheck/sumcheck.go | 3 +-- ecc/bls24-317/kzg/kzg.go | 2 +- ecc/bn254/fr/fri/fri.go | 4 ++-- ecc/bn254/fr/gkr/gkr.go | 4 +--- ecc/bn254/fr/mimc/mimc.go | 5 +++-- ecc/bn254/fr/pedersen/pedersen.go | 2 +- ecc/bn254/fr/permutation/permutation.go | 16 ++++++++-------- ecc/bn254/fr/plookup/table.go | 8 ++++---- ecc/bn254/fr/plookup/vector.go | 20 ++++++++++---------- ecc/bn254/fr/sumcheck/sumcheck.go | 3 +-- ecc/bn254/kzg/kzg.go | 2 +- ecc/bw6-633/fr/fri/fri.go | 4 ++-- ecc/bw6-633/fr/gkr/gkr.go | 4 +--- ecc/bw6-633/fr/mimc/mimc.go | 5 +++-- ecc/bw6-633/fr/pedersen/pedersen.go | 2 +- ecc/bw6-633/fr/permutation/permutation.go | 16 ++++++++-------- ecc/bw6-633/fr/plookup/table.go | 8 ++++---- ecc/bw6-633/fr/plookup/vector.go | 20 ++++++++++---------- ecc/bw6-633/fr/sumcheck/sumcheck.go | 3 +-- ecc/bw6-633/kzg/kzg.go | 2 +- ecc/bw6-756/fr/fri/fri.go | 4 ++-- ecc/bw6-756/fr/gkr/gkr.go | 4 +--- ecc/bw6-756/fr/mimc/mimc.go | 5 +++-- ecc/bw6-756/fr/pedersen/pedersen.go | 2 +- ecc/bw6-756/fr/permutation/permutation.go | 16 ++++++++-------- ecc/bw6-756/fr/plookup/table.go | 8 ++++---- ecc/bw6-756/fr/plookup/vector.go | 20 ++++++++++---------- ecc/bw6-756/fr/sumcheck/sumcheck.go | 3 +-- ecc/bw6-756/kzg/kzg.go | 2 +- ecc/bw6-761/fr/fri/fri.go | 4 ++-- ecc/bw6-761/fr/gkr/gkr.go | 4 +--- ecc/bw6-761/fr/mimc/mimc.go | 5 +++-- ecc/bw6-761/fr/pedersen/pedersen.go | 2 +- ecc/bw6-761/fr/permutation/permutation.go | 16 ++++++++-------- ecc/bw6-761/fr/plookup/table.go | 8 ++++---- ecc/bw6-761/fr/plookup/vector.go | 20 ++++++++++---------- ecc/bw6-761/fr/sumcheck/sumcheck.go | 3 +-- ecc/bw6-761/kzg/kzg.go | 2 +- 81 files changed, 279 insertions(+), 297 deletions(-) diff --git a/ecc/bls12-377/fr/fri/fri.go b/ecc/bls12-377/fr/fri/fri.go index 91cc031ee..14f897270 100644 --- a/ecc/bls12-377/fr/fri/fri.go +++ b/ecc/bls12-377/fr/fri/fri.go @@ -398,7 +398,7 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -552,7 +552,7 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls12-377/fr/gkr/gkr.go b/ecc/bls12-377/fr/gkr/gkr.go index 2d579924a..d92c6e559 100644 --- a/ecc/bls12-377/fr/gkr/gkr.go +++ b/ecc/bls12-377/fr/gkr/gkr.go @@ -490,9 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bls12-377/fr/mimc/mimc.go b/ecc/bls12-377/fr/mimc/mimc.go index 58ed4f649..d73781c79 100644 --- a/ecc/bls12-377/fr/mimc/mimc.go +++ b/ecc/bls12-377/fr/mimc/mimc.go @@ -185,10 +185,11 @@ func initConstants() { } // WriteString writes a string that doesn't necessarily consist of field elements -func (d *digest) WriteString(rawBytes []byte) { +func (d *digest) WriteString(rawBytes []byte) error { if elems, err := fr.Hash(rawBytes, []byte("string:"), 1); err != nil { - panic(err) + return err } else { d.data = append(d.data, elems[0]) } + return nil } diff --git a/ecc/bls12-377/fr/pedersen/pedersen.go b/ecc/bls12-377/fr/pedersen/pedersen.go index 31130283a..3645909a5 100644 --- a/ecc/bls12-377/fr/pedersen/pedersen.go +++ b/ecc/bls12-377/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), "r") + t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bls12-377/fr/permutation/permutation.go b/ecc/bls12-377/fr/permutation/permutation.go index 3cf4c56a9..9e8302018 100644 --- a/ecc/bls12-377/fr/permutation/permutation.go +++ b/ecc/bls12-377/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // commit t1, t2 ct1 := make([]fr.Element, s) @@ -177,7 +177,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive challenge for z - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return proof, err } @@ -206,7 +206,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { lsNum := evaluateSecondPartNumReverse(lz, d) // derive challenge used for the folding - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return proof, err } @@ -229,7 +229,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive the evaluation challenge - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return proof, err } @@ -279,20 +279,20 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // derive the challenges - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return err } - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return err } - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return err } diff --git a/ecc/bls12-377/fr/plookup/table.go b/ecc/bls12-377/fr/plookup/table.go index 650e73be2..72e68891e 100644 --- a/ecc/bls12-377/fr/plookup/table.go +++ b/ecc/bls12-377/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check the sizes if len(f) != len(t) { @@ -145,7 +145,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, comms[nbRows+i] = new(kzg.Digest) comms[nbRows+i].Set(&proof.ts[i]) } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return proof, err } @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { @@ -197,7 +197,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { comms[i] = &proof.fs[i] comms[i+nbRows] = &proof.ts[i] } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return err } diff --git a/ecc/bls12-377/fr/plookup/vector.go b/ecc/bls12-377/fr/plookup/vector.go index dd91fb108..0998753fe 100644 --- a/ecc/bls12-377/fr/plookup/vector.go +++ b/ecc/bls12-377/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // create domains var domainSmall *fft.Domain @@ -441,11 +441,11 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // derive beta, gamma - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return proof, err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return proof, err } @@ -495,7 +495,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er lh1h2 := evaluateOverlapH1h2BitReversed(_lh1, _lh2, domainBig) // compute the quotient - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return proof, err } @@ -506,7 +506,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // build the opening proofs - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return proof, err } @@ -567,25 +567,25 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // derive the various challenges - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return err } - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return err } - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return err } diff --git a/ecc/bls12-377/fr/sumcheck/sumcheck.go b/ecc/bls12-377/fr/sumcheck/sumcheck.go index 09640b7bc..228faa75b 100644 --- a/ecc/bls12-377/fr/sumcheck/sumcheck.go +++ b/ecc/bls12-377/fr/sumcheck/sumcheck.go @@ -66,8 +66,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) } for i := range settings.BaseChallenges { diff --git a/ecc/bls12-377/kzg/kzg.go b/ecc/bls12-377/kzg/kzg.go index 3458d655e..dc8451d8a 100644 --- a/ecc/bls12-377/kzg/kzg.go +++ b/ecc/bls12-377/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, "gamma") + fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bls12-378/fr/fri/fri.go b/ecc/bls12-378/fr/fri/fri.go index 145e2defd..78672890d 100644 --- a/ecc/bls12-378/fr/fri/fri.go +++ b/ecc/bls12-378/fr/fri/fri.go @@ -398,7 +398,7 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -552,7 +552,7 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls12-378/fr/gkr/gkr.go b/ecc/bls12-378/fr/gkr/gkr.go index 1c6c96774..5b513de8f 100644 --- a/ecc/bls12-378/fr/gkr/gkr.go +++ b/ecc/bls12-378/fr/gkr/gkr.go @@ -490,9 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bls12-378/fr/mimc/mimc.go b/ecc/bls12-378/fr/mimc/mimc.go index e28d965a4..632cacd83 100644 --- a/ecc/bls12-378/fr/mimc/mimc.go +++ b/ecc/bls12-378/fr/mimc/mimc.go @@ -183,10 +183,11 @@ func initConstants() { } // WriteString writes a string that doesn't necessarily consist of field elements -func (d *digest) WriteString(rawBytes []byte) { +func (d *digest) WriteString(rawBytes []byte) error { if elems, err := fr.Hash(rawBytes, []byte("string:"), 1); err != nil { - panic(err) + return err } else { d.data = append(d.data, elems[0]) } + return nil } diff --git a/ecc/bls12-378/fr/pedersen/pedersen.go b/ecc/bls12-378/fr/pedersen/pedersen.go index 96c963e3a..cb7585a85 100644 --- a/ecc/bls12-378/fr/pedersen/pedersen.go +++ b/ecc/bls12-378/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), "r") + t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bls12-378/fr/permutation/permutation.go b/ecc/bls12-378/fr/permutation/permutation.go index 7e21ef345..609de2c71 100644 --- a/ecc/bls12-378/fr/permutation/permutation.go +++ b/ecc/bls12-378/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // commit t1, t2 ct1 := make([]fr.Element, s) @@ -177,7 +177,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive challenge for z - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return proof, err } @@ -206,7 +206,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { lsNum := evaluateSecondPartNumReverse(lz, d) // derive challenge used for the folding - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return proof, err } @@ -229,7 +229,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive the evaluation challenge - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return proof, err } @@ -279,20 +279,20 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // derive the challenges - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return err } - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return err } - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return err } diff --git a/ecc/bls12-378/fr/plookup/table.go b/ecc/bls12-378/fr/plookup/table.go index e4a9ea604..1dbcdc447 100644 --- a/ecc/bls12-378/fr/plookup/table.go +++ b/ecc/bls12-378/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check the sizes if len(f) != len(t) { @@ -145,7 +145,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, comms[nbRows+i] = new(kzg.Digest) comms[nbRows+i].Set(&proof.ts[i]) } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return proof, err } @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { @@ -197,7 +197,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { comms[i] = &proof.fs[i] comms[i+nbRows] = &proof.ts[i] } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return err } diff --git a/ecc/bls12-378/fr/plookup/vector.go b/ecc/bls12-378/fr/plookup/vector.go index 6415607e4..e27e3aa33 100644 --- a/ecc/bls12-378/fr/plookup/vector.go +++ b/ecc/bls12-378/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // create domains var domainSmall *fft.Domain @@ -441,11 +441,11 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // derive beta, gamma - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return proof, err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return proof, err } @@ -495,7 +495,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er lh1h2 := evaluateOverlapH1h2BitReversed(_lh1, _lh2, domainBig) // compute the quotient - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return proof, err } @@ -506,7 +506,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // build the opening proofs - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return proof, err } @@ -567,25 +567,25 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // derive the various challenges - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return err } - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return err } - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return err } diff --git a/ecc/bls12-378/fr/sumcheck/sumcheck.go b/ecc/bls12-378/fr/sumcheck/sumcheck.go index 2ae2f56aa..c843b0873 100644 --- a/ecc/bls12-378/fr/sumcheck/sumcheck.go +++ b/ecc/bls12-378/fr/sumcheck/sumcheck.go @@ -66,8 +66,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) } for i := range settings.BaseChallenges { diff --git a/ecc/bls12-378/kzg/kzg.go b/ecc/bls12-378/kzg/kzg.go index 3624d41e0..66c64f185 100644 --- a/ecc/bls12-378/kzg/kzg.go +++ b/ecc/bls12-378/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, "gamma") + fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bls12-381/fr/fri/fri.go b/ecc/bls12-381/fr/fri/fri.go index 52bf2091e..e6799db6f 100644 --- a/ecc/bls12-381/fr/fri/fri.go +++ b/ecc/bls12-381/fr/fri/fri.go @@ -398,7 +398,7 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -552,7 +552,7 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls12-381/fr/gkr/gkr.go b/ecc/bls12-381/fr/gkr/gkr.go index 7de6aa7df..c9a2a4044 100644 --- a/ecc/bls12-381/fr/gkr/gkr.go +++ b/ecc/bls12-381/fr/gkr/gkr.go @@ -490,9 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bls12-381/fr/mimc/mimc.go b/ecc/bls12-381/fr/mimc/mimc.go index 577768363..6db7f47c2 100644 --- a/ecc/bls12-381/fr/mimc/mimc.go +++ b/ecc/bls12-381/fr/mimc/mimc.go @@ -183,10 +183,11 @@ func initConstants() { } // WriteString writes a string that doesn't necessarily consist of field elements -func (d *digest) WriteString(rawBytes []byte) { +func (d *digest) WriteString(rawBytes []byte) error { if elems, err := fr.Hash(rawBytes, []byte("string:"), 1); err != nil { - panic(err) + return err } else { d.data = append(d.data, elems[0]) } + return nil } diff --git a/ecc/bls12-381/fr/pedersen/pedersen.go b/ecc/bls12-381/fr/pedersen/pedersen.go index 204c6f13b..fe5dca8a2 100644 --- a/ecc/bls12-381/fr/pedersen/pedersen.go +++ b/ecc/bls12-381/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), "r") + t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bls12-381/fr/permutation/permutation.go b/ecc/bls12-381/fr/permutation/permutation.go index 778f4ea48..892a370d4 100644 --- a/ecc/bls12-381/fr/permutation/permutation.go +++ b/ecc/bls12-381/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // commit t1, t2 ct1 := make([]fr.Element, s) @@ -177,7 +177,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive challenge for z - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return proof, err } @@ -206,7 +206,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { lsNum := evaluateSecondPartNumReverse(lz, d) // derive challenge used for the folding - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return proof, err } @@ -229,7 +229,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive the evaluation challenge - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return proof, err } @@ -279,20 +279,20 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // derive the challenges - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return err } - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return err } - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return err } diff --git a/ecc/bls12-381/fr/plookup/table.go b/ecc/bls12-381/fr/plookup/table.go index cf11e8965..629198c44 100644 --- a/ecc/bls12-381/fr/plookup/table.go +++ b/ecc/bls12-381/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check the sizes if len(f) != len(t) { @@ -145,7 +145,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, comms[nbRows+i] = new(kzg.Digest) comms[nbRows+i].Set(&proof.ts[i]) } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return proof, err } @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { @@ -197,7 +197,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { comms[i] = &proof.fs[i] comms[i+nbRows] = &proof.ts[i] } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return err } diff --git a/ecc/bls12-381/fr/plookup/vector.go b/ecc/bls12-381/fr/plookup/vector.go index 044835c32..cb0695abb 100644 --- a/ecc/bls12-381/fr/plookup/vector.go +++ b/ecc/bls12-381/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // create domains var domainSmall *fft.Domain @@ -441,11 +441,11 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // derive beta, gamma - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return proof, err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return proof, err } @@ -495,7 +495,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er lh1h2 := evaluateOverlapH1h2BitReversed(_lh1, _lh2, domainBig) // compute the quotient - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return proof, err } @@ -506,7 +506,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // build the opening proofs - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return proof, err } @@ -567,25 +567,25 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // derive the various challenges - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return err } - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return err } - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return err } diff --git a/ecc/bls12-381/fr/sumcheck/sumcheck.go b/ecc/bls12-381/fr/sumcheck/sumcheck.go index ee3675773..4da3022a5 100644 --- a/ecc/bls12-381/fr/sumcheck/sumcheck.go +++ b/ecc/bls12-381/fr/sumcheck/sumcheck.go @@ -66,8 +66,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) } for i := range settings.BaseChallenges { diff --git a/ecc/bls12-381/kzg/kzg.go b/ecc/bls12-381/kzg/kzg.go index 42540cd28..69c5d03f3 100644 --- a/ecc/bls12-381/kzg/kzg.go +++ b/ecc/bls12-381/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, "gamma") + fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bls24-315/fr/fri/fri.go b/ecc/bls24-315/fr/fri/fri.go index b117c0235..5770496f0 100644 --- a/ecc/bls24-315/fr/fri/fri.go +++ b/ecc/bls24-315/fr/fri/fri.go @@ -398,7 +398,7 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -552,7 +552,7 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls24-315/fr/gkr/gkr.go b/ecc/bls24-315/fr/gkr/gkr.go index 968acb37d..4ed8e075c 100644 --- a/ecc/bls24-315/fr/gkr/gkr.go +++ b/ecc/bls24-315/fr/gkr/gkr.go @@ -490,9 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bls24-315/fr/mimc/mimc.go b/ecc/bls24-315/fr/mimc/mimc.go index 61137054e..c6a3f729d 100644 --- a/ecc/bls24-315/fr/mimc/mimc.go +++ b/ecc/bls24-315/fr/mimc/mimc.go @@ -183,10 +183,11 @@ func initConstants() { } // WriteString writes a string that doesn't necessarily consist of field elements -func (d *digest) WriteString(rawBytes []byte) { +func (d *digest) WriteString(rawBytes []byte) error { if elems, err := fr.Hash(rawBytes, []byte("string:"), 1); err != nil { - panic(err) + return err } else { d.data = append(d.data, elems[0]) } + return nil } diff --git a/ecc/bls24-315/fr/pedersen/pedersen.go b/ecc/bls24-315/fr/pedersen/pedersen.go index 961616211..dd6ba9897 100644 --- a/ecc/bls24-315/fr/pedersen/pedersen.go +++ b/ecc/bls24-315/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), "r") + t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bls24-315/fr/permutation/permutation.go b/ecc/bls24-315/fr/permutation/permutation.go index b45676c52..eec77c896 100644 --- a/ecc/bls24-315/fr/permutation/permutation.go +++ b/ecc/bls24-315/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // commit t1, t2 ct1 := make([]fr.Element, s) @@ -177,7 +177,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive challenge for z - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return proof, err } @@ -206,7 +206,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { lsNum := evaluateSecondPartNumReverse(lz, d) // derive challenge used for the folding - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return proof, err } @@ -229,7 +229,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive the evaluation challenge - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return proof, err } @@ -279,20 +279,20 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // derive the challenges - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return err } - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return err } - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return err } diff --git a/ecc/bls24-315/fr/plookup/table.go b/ecc/bls24-315/fr/plookup/table.go index 51c8858c2..47000318a 100644 --- a/ecc/bls24-315/fr/plookup/table.go +++ b/ecc/bls24-315/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check the sizes if len(f) != len(t) { @@ -145,7 +145,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, comms[nbRows+i] = new(kzg.Digest) comms[nbRows+i].Set(&proof.ts[i]) } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return proof, err } @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { @@ -197,7 +197,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { comms[i] = &proof.fs[i] comms[i+nbRows] = &proof.ts[i] } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return err } diff --git a/ecc/bls24-315/fr/plookup/vector.go b/ecc/bls24-315/fr/plookup/vector.go index a446e2e25..379b53368 100644 --- a/ecc/bls24-315/fr/plookup/vector.go +++ b/ecc/bls24-315/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // create domains var domainSmall *fft.Domain @@ -441,11 +441,11 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // derive beta, gamma - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return proof, err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return proof, err } @@ -495,7 +495,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er lh1h2 := evaluateOverlapH1h2BitReversed(_lh1, _lh2, domainBig) // compute the quotient - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return proof, err } @@ -506,7 +506,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // build the opening proofs - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return proof, err } @@ -567,25 +567,25 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // derive the various challenges - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return err } - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return err } - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return err } diff --git a/ecc/bls24-315/fr/sumcheck/sumcheck.go b/ecc/bls24-315/fr/sumcheck/sumcheck.go index ba4f2c1eb..e926b6951 100644 --- a/ecc/bls24-315/fr/sumcheck/sumcheck.go +++ b/ecc/bls24-315/fr/sumcheck/sumcheck.go @@ -66,8 +66,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) } for i := range settings.BaseChallenges { diff --git a/ecc/bls24-315/kzg/kzg.go b/ecc/bls24-315/kzg/kzg.go index 43e16d9c0..6859c91ef 100644 --- a/ecc/bls24-315/kzg/kzg.go +++ b/ecc/bls24-315/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, "gamma") + fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bls24-317/fr/fri/fri.go b/ecc/bls24-317/fr/fri/fri.go index 135cfb127..2bb0ec47f 100644 --- a/ecc/bls24-317/fr/fri/fri.go +++ b/ecc/bls24-317/fr/fri/fri.go @@ -398,7 +398,7 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -552,7 +552,7 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls24-317/fr/gkr/gkr.go b/ecc/bls24-317/fr/gkr/gkr.go index a9c4f9670..a8194a898 100644 --- a/ecc/bls24-317/fr/gkr/gkr.go +++ b/ecc/bls24-317/fr/gkr/gkr.go @@ -490,9 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bls24-317/fr/mimc/mimc.go b/ecc/bls24-317/fr/mimc/mimc.go index 15b07da35..9947cfeba 100644 --- a/ecc/bls24-317/fr/mimc/mimc.go +++ b/ecc/bls24-317/fr/mimc/mimc.go @@ -185,10 +185,11 @@ func initConstants() { } // WriteString writes a string that doesn't necessarily consist of field elements -func (d *digest) WriteString(rawBytes []byte) { +func (d *digest) WriteString(rawBytes []byte) error { if elems, err := fr.Hash(rawBytes, []byte("string:"), 1); err != nil { - panic(err) + return err } else { d.data = append(d.data, elems[0]) } + return nil } diff --git a/ecc/bls24-317/fr/pedersen/pedersen.go b/ecc/bls24-317/fr/pedersen/pedersen.go index 684498ef1..9e720f20b 100644 --- a/ecc/bls24-317/fr/pedersen/pedersen.go +++ b/ecc/bls24-317/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), "r") + t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bls24-317/fr/permutation/permutation.go b/ecc/bls24-317/fr/permutation/permutation.go index 8aa2bb92f..8c1032fed 100644 --- a/ecc/bls24-317/fr/permutation/permutation.go +++ b/ecc/bls24-317/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // commit t1, t2 ct1 := make([]fr.Element, s) @@ -177,7 +177,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive challenge for z - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return proof, err } @@ -206,7 +206,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { lsNum := evaluateSecondPartNumReverse(lz, d) // derive challenge used for the folding - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return proof, err } @@ -229,7 +229,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive the evaluation challenge - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return proof, err } @@ -279,20 +279,20 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // derive the challenges - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return err } - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return err } - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return err } diff --git a/ecc/bls24-317/fr/plookup/table.go b/ecc/bls24-317/fr/plookup/table.go index 9720f3d37..93d33262e 100644 --- a/ecc/bls24-317/fr/plookup/table.go +++ b/ecc/bls24-317/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check the sizes if len(f) != len(t) { @@ -145,7 +145,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, comms[nbRows+i] = new(kzg.Digest) comms[nbRows+i].Set(&proof.ts[i]) } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return proof, err } @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { @@ -197,7 +197,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { comms[i] = &proof.fs[i] comms[i+nbRows] = &proof.ts[i] } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return err } diff --git a/ecc/bls24-317/fr/plookup/vector.go b/ecc/bls24-317/fr/plookup/vector.go index 3d618ff40..950184275 100644 --- a/ecc/bls24-317/fr/plookup/vector.go +++ b/ecc/bls24-317/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // create domains var domainSmall *fft.Domain @@ -441,11 +441,11 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // derive beta, gamma - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return proof, err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return proof, err } @@ -495,7 +495,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er lh1h2 := evaluateOverlapH1h2BitReversed(_lh1, _lh2, domainBig) // compute the quotient - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return proof, err } @@ -506,7 +506,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // build the opening proofs - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return proof, err } @@ -567,25 +567,25 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // derive the various challenges - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return err } - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return err } - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return err } diff --git a/ecc/bls24-317/fr/sumcheck/sumcheck.go b/ecc/bls24-317/fr/sumcheck/sumcheck.go index 5d294c205..2e22a9334 100644 --- a/ecc/bls24-317/fr/sumcheck/sumcheck.go +++ b/ecc/bls24-317/fr/sumcheck/sumcheck.go @@ -66,8 +66,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) } for i := range settings.BaseChallenges { diff --git a/ecc/bls24-317/kzg/kzg.go b/ecc/bls24-317/kzg/kzg.go index 791e3d1f8..ab58f302c 100644 --- a/ecc/bls24-317/kzg/kzg.go +++ b/ecc/bls24-317/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, "gamma") + fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bn254/fr/fri/fri.go b/ecc/bn254/fr/fri/fri.go index 6559829ec..027b89700 100644 --- a/ecc/bn254/fr/fri/fri.go +++ b/ecc/bn254/fr/fri/fri.go @@ -398,7 +398,7 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -552,7 +552,7 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bn254/fr/gkr/gkr.go b/ecc/bn254/fr/gkr/gkr.go index a96fb9110..293c2d7a3 100644 --- a/ecc/bn254/fr/gkr/gkr.go +++ b/ecc/bn254/fr/gkr/gkr.go @@ -490,9 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bn254/fr/mimc/mimc.go b/ecc/bn254/fr/mimc/mimc.go index 254ef43bd..1d59a7940 100644 --- a/ecc/bn254/fr/mimc/mimc.go +++ b/ecc/bn254/fr/mimc/mimc.go @@ -183,10 +183,11 @@ func initConstants() { } // WriteString writes a string that doesn't necessarily consist of field elements -func (d *digest) WriteString(rawBytes []byte) { +func (d *digest) WriteString(rawBytes []byte) error { if elems, err := fr.Hash(rawBytes, []byte("string:"), 1); err != nil { - panic(err) + return err } else { d.data = append(d.data, elems[0]) } + return nil } diff --git a/ecc/bn254/fr/pedersen/pedersen.go b/ecc/bn254/fr/pedersen/pedersen.go index 7c6bf8c2c..5680a131d 100644 --- a/ecc/bn254/fr/pedersen/pedersen.go +++ b/ecc/bn254/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), "r") + t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bn254/fr/permutation/permutation.go b/ecc/bn254/fr/permutation/permutation.go index b59ab3aaa..7a0834523 100644 --- a/ecc/bn254/fr/permutation/permutation.go +++ b/ecc/bn254/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // commit t1, t2 ct1 := make([]fr.Element, s) @@ -177,7 +177,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive challenge for z - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return proof, err } @@ -206,7 +206,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { lsNum := evaluateSecondPartNumReverse(lz, d) // derive challenge used for the folding - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return proof, err } @@ -229,7 +229,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive the evaluation challenge - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return proof, err } @@ -279,20 +279,20 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // derive the challenges - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return err } - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return err } - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return err } diff --git a/ecc/bn254/fr/plookup/table.go b/ecc/bn254/fr/plookup/table.go index 7851831e7..ac6628874 100644 --- a/ecc/bn254/fr/plookup/table.go +++ b/ecc/bn254/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check the sizes if len(f) != len(t) { @@ -145,7 +145,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, comms[nbRows+i] = new(kzg.Digest) comms[nbRows+i].Set(&proof.ts[i]) } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return proof, err } @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { @@ -197,7 +197,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { comms[i] = &proof.fs[i] comms[i+nbRows] = &proof.ts[i] } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return err } diff --git a/ecc/bn254/fr/plookup/vector.go b/ecc/bn254/fr/plookup/vector.go index 93816fdab..ede9b2abb 100644 --- a/ecc/bn254/fr/plookup/vector.go +++ b/ecc/bn254/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // create domains var domainSmall *fft.Domain @@ -441,11 +441,11 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // derive beta, gamma - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return proof, err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return proof, err } @@ -495,7 +495,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er lh1h2 := evaluateOverlapH1h2BitReversed(_lh1, _lh2, domainBig) // compute the quotient - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return proof, err } @@ -506,7 +506,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // build the opening proofs - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return proof, err } @@ -567,25 +567,25 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // derive the various challenges - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return err } - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return err } - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return err } diff --git a/ecc/bn254/fr/sumcheck/sumcheck.go b/ecc/bn254/fr/sumcheck/sumcheck.go index 104a52e7e..65cdd2dcf 100644 --- a/ecc/bn254/fr/sumcheck/sumcheck.go +++ b/ecc/bn254/fr/sumcheck/sumcheck.go @@ -66,8 +66,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) } for i := range settings.BaseChallenges { diff --git a/ecc/bn254/kzg/kzg.go b/ecc/bn254/kzg/kzg.go index 067894ab5..3ac9177ae 100644 --- a/ecc/bn254/kzg/kzg.go +++ b/ecc/bn254/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, "gamma") + fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bw6-633/fr/fri/fri.go b/ecc/bw6-633/fr/fri/fri.go index 70e927600..a1f96048e 100644 --- a/ecc/bw6-633/fr/fri/fri.go +++ b/ecc/bw6-633/fr/fri/fri.go @@ -398,7 +398,7 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -552,7 +552,7 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bw6-633/fr/gkr/gkr.go b/ecc/bw6-633/fr/gkr/gkr.go index b9c27df17..8dbc340b6 100644 --- a/ecc/bw6-633/fr/gkr/gkr.go +++ b/ecc/bw6-633/fr/gkr/gkr.go @@ -490,9 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bw6-633/fr/mimc/mimc.go b/ecc/bw6-633/fr/mimc/mimc.go index 4ee249897..6b830e713 100644 --- a/ecc/bw6-633/fr/mimc/mimc.go +++ b/ecc/bw6-633/fr/mimc/mimc.go @@ -183,10 +183,11 @@ func initConstants() { } // WriteString writes a string that doesn't necessarily consist of field elements -func (d *digest) WriteString(rawBytes []byte) { +func (d *digest) WriteString(rawBytes []byte) error { if elems, err := fr.Hash(rawBytes, []byte("string:"), 1); err != nil { - panic(err) + return err } else { d.data = append(d.data, elems[0]) } + return nil } diff --git a/ecc/bw6-633/fr/pedersen/pedersen.go b/ecc/bw6-633/fr/pedersen/pedersen.go index 0dd39010d..6f64b9aed 100644 --- a/ecc/bw6-633/fr/pedersen/pedersen.go +++ b/ecc/bw6-633/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), "r") + t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bw6-633/fr/permutation/permutation.go b/ecc/bw6-633/fr/permutation/permutation.go index 8f3cfd52d..081279330 100644 --- a/ecc/bw6-633/fr/permutation/permutation.go +++ b/ecc/bw6-633/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // commit t1, t2 ct1 := make([]fr.Element, s) @@ -177,7 +177,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive challenge for z - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return proof, err } @@ -206,7 +206,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { lsNum := evaluateSecondPartNumReverse(lz, d) // derive challenge used for the folding - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return proof, err } @@ -229,7 +229,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive the evaluation challenge - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return proof, err } @@ -279,20 +279,20 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // derive the challenges - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return err } - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return err } - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return err } diff --git a/ecc/bw6-633/fr/plookup/table.go b/ecc/bw6-633/fr/plookup/table.go index dcfe721d9..a14ac0587 100644 --- a/ecc/bw6-633/fr/plookup/table.go +++ b/ecc/bw6-633/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check the sizes if len(f) != len(t) { @@ -145,7 +145,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, comms[nbRows+i] = new(kzg.Digest) comms[nbRows+i].Set(&proof.ts[i]) } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return proof, err } @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { @@ -197,7 +197,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { comms[i] = &proof.fs[i] comms[i+nbRows] = &proof.ts[i] } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return err } diff --git a/ecc/bw6-633/fr/plookup/vector.go b/ecc/bw6-633/fr/plookup/vector.go index 13a821b2b..024dae384 100644 --- a/ecc/bw6-633/fr/plookup/vector.go +++ b/ecc/bw6-633/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // create domains var domainSmall *fft.Domain @@ -441,11 +441,11 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // derive beta, gamma - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return proof, err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return proof, err } @@ -495,7 +495,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er lh1h2 := evaluateOverlapH1h2BitReversed(_lh1, _lh2, domainBig) // compute the quotient - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return proof, err } @@ -506,7 +506,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // build the opening proofs - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return proof, err } @@ -567,25 +567,25 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // derive the various challenges - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return err } - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return err } - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return err } diff --git a/ecc/bw6-633/fr/sumcheck/sumcheck.go b/ecc/bw6-633/fr/sumcheck/sumcheck.go index 3e401b771..f49e4457c 100644 --- a/ecc/bw6-633/fr/sumcheck/sumcheck.go +++ b/ecc/bw6-633/fr/sumcheck/sumcheck.go @@ -66,8 +66,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) } for i := range settings.BaseChallenges { diff --git a/ecc/bw6-633/kzg/kzg.go b/ecc/bw6-633/kzg/kzg.go index cf59dff0f..4e0e136e0 100644 --- a/ecc/bw6-633/kzg/kzg.go +++ b/ecc/bw6-633/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, "gamma") + fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bw6-756/fr/fri/fri.go b/ecc/bw6-756/fr/fri/fri.go index 29d74e962..efe5f501a 100644 --- a/ecc/bw6-756/fr/fri/fri.go +++ b/ecc/bw6-756/fr/fri/fri.go @@ -398,7 +398,7 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -552,7 +552,7 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bw6-756/fr/gkr/gkr.go b/ecc/bw6-756/fr/gkr/gkr.go index 650170be4..6b7b861b0 100644 --- a/ecc/bw6-756/fr/gkr/gkr.go +++ b/ecc/bw6-756/fr/gkr/gkr.go @@ -490,9 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bw6-756/fr/mimc/mimc.go b/ecc/bw6-756/fr/mimc/mimc.go index c9a2992b0..e1f47d69d 100644 --- a/ecc/bw6-756/fr/mimc/mimc.go +++ b/ecc/bw6-756/fr/mimc/mimc.go @@ -183,10 +183,11 @@ func initConstants() { } // WriteString writes a string that doesn't necessarily consist of field elements -func (d *digest) WriteString(rawBytes []byte) { +func (d *digest) WriteString(rawBytes []byte) error { if elems, err := fr.Hash(rawBytes, []byte("string:"), 1); err != nil { - panic(err) + return err } else { d.data = append(d.data, elems[0]) } + return nil } diff --git a/ecc/bw6-756/fr/pedersen/pedersen.go b/ecc/bw6-756/fr/pedersen/pedersen.go index 2d757b8ec..0230595d3 100644 --- a/ecc/bw6-756/fr/pedersen/pedersen.go +++ b/ecc/bw6-756/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), "r") + t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bw6-756/fr/permutation/permutation.go b/ecc/bw6-756/fr/permutation/permutation.go index 5a80f995e..43638f397 100644 --- a/ecc/bw6-756/fr/permutation/permutation.go +++ b/ecc/bw6-756/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // commit t1, t2 ct1 := make([]fr.Element, s) @@ -177,7 +177,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive challenge for z - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return proof, err } @@ -206,7 +206,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { lsNum := evaluateSecondPartNumReverse(lz, d) // derive challenge used for the folding - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return proof, err } @@ -229,7 +229,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive the evaluation challenge - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return proof, err } @@ -279,20 +279,20 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // derive the challenges - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return err } - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return err } - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return err } diff --git a/ecc/bw6-756/fr/plookup/table.go b/ecc/bw6-756/fr/plookup/table.go index bb8d418d4..336ee7abf 100644 --- a/ecc/bw6-756/fr/plookup/table.go +++ b/ecc/bw6-756/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check the sizes if len(f) != len(t) { @@ -145,7 +145,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, comms[nbRows+i] = new(kzg.Digest) comms[nbRows+i].Set(&proof.ts[i]) } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return proof, err } @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { @@ -197,7 +197,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { comms[i] = &proof.fs[i] comms[i+nbRows] = &proof.ts[i] } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return err } diff --git a/ecc/bw6-756/fr/plookup/vector.go b/ecc/bw6-756/fr/plookup/vector.go index beba8c4d3..3b9cc7e27 100644 --- a/ecc/bw6-756/fr/plookup/vector.go +++ b/ecc/bw6-756/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // create domains var domainSmall *fft.Domain @@ -441,11 +441,11 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // derive beta, gamma - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return proof, err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return proof, err } @@ -495,7 +495,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er lh1h2 := evaluateOverlapH1h2BitReversed(_lh1, _lh2, domainBig) // compute the quotient - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return proof, err } @@ -506,7 +506,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // build the opening proofs - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return proof, err } @@ -567,25 +567,25 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // derive the various challenges - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return err } - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return err } - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return err } diff --git a/ecc/bw6-756/fr/sumcheck/sumcheck.go b/ecc/bw6-756/fr/sumcheck/sumcheck.go index 0cbce7fa7..d9c52e737 100644 --- a/ecc/bw6-756/fr/sumcheck/sumcheck.go +++ b/ecc/bw6-756/fr/sumcheck/sumcheck.go @@ -66,8 +66,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) } for i := range settings.BaseChallenges { diff --git a/ecc/bw6-756/kzg/kzg.go b/ecc/bw6-756/kzg/kzg.go index 42539e691..046c456ca 100644 --- a/ecc/bw6-756/kzg/kzg.go +++ b/ecc/bw6-756/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, "gamma") + fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bw6-761/fr/fri/fri.go b/ecc/bw6-761/fr/fri/fri.go index 6c8cb0bce..290b000f8 100644 --- a/ecc/bw6-761/fr/fri/fri.go +++ b/ecc/bw6-761/fr/fri/fri.go @@ -398,7 +398,7 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -552,7 +552,7 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) - fs := fiatshamir.NewTranscript(s.h, xis...) + fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bw6-761/fr/gkr/gkr.go b/ecc/bw6-761/fr/gkr/gkr.go index a50b7617b..b8c8cb8df 100644 --- a/ecc/bw6-761/fr/gkr/gkr.go +++ b/ecc/bw6-761/fr/gkr/gkr.go @@ -490,9 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bw6-761/fr/mimc/mimc.go b/ecc/bw6-761/fr/mimc/mimc.go index d575a63d9..23e22256f 100644 --- a/ecc/bw6-761/fr/mimc/mimc.go +++ b/ecc/bw6-761/fr/mimc/mimc.go @@ -183,10 +183,11 @@ func initConstants() { } // WriteString writes a string that doesn't necessarily consist of field elements -func (d *digest) WriteString(rawBytes []byte) { +func (d *digest) WriteString(rawBytes []byte) error { if elems, err := fr.Hash(rawBytes, []byte("string:"), 1); err != nil { - panic(err) + return err } else { d.data = append(d.data, elems[0]) } + return nil } diff --git a/ecc/bw6-761/fr/pedersen/pedersen.go b/ecc/bw6-761/fr/pedersen/pedersen.go index c1ca758aa..0ffdce39c 100644 --- a/ecc/bw6-761/fr/pedersen/pedersen.go +++ b/ecc/bw6-761/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), "r") + t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bw6-761/fr/permutation/permutation.go b/ecc/bw6-761/fr/permutation/permutation.go index 30b3a5e00..406008181 100644 --- a/ecc/bw6-761/fr/permutation/permutation.go +++ b/ecc/bw6-761/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // commit t1, t2 ct1 := make([]fr.Element, s) @@ -177,7 +177,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive challenge for z - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return proof, err } @@ -206,7 +206,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { lsNum := evaluateSecondPartNumReverse(lz, d) // derive challenge used for the folding - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return proof, err } @@ -229,7 +229,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive the evaluation challenge - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return proof, err } @@ -279,20 +279,20 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) // derive the challenges - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return err } - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return err } - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return err } diff --git a/ecc/bw6-761/fr/plookup/table.go b/ecc/bw6-761/fr/plookup/table.go index bfbfc7cbf..9e4996a0d 100644 --- a/ecc/bw6-761/fr/plookup/table.go +++ b/ecc/bw6-761/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check the sizes if len(f) != len(t) { @@ -145,7 +145,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, comms[nbRows+i] = new(kzg.Digest) comms[nbRows+i].Set(&proof.ts[i]) } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return proof, err } @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "lambda") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { @@ -197,7 +197,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { comms[i] = &proof.fs[i] comms[i+nbRows] = &proof.ts[i] } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return err } diff --git a/ecc/bw6-761/fr/plookup/vector.go b/ecc/bw6-761/fr/plookup/vector.go index 3883123fc..0718108f5 100644 --- a/ecc/bw6-761/fr/plookup/vector.go +++ b/ecc/bw6-761/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // create domains var domainSmall *fft.Domain @@ -441,11 +441,11 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // derive beta, gamma - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return proof, err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return proof, err } @@ -495,7 +495,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er lh1h2 := evaluateOverlapH1h2BitReversed(_lh1, _lh2, domainBig) // compute the quotient - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return proof, err } @@ -506,7 +506,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // build the opening proofs - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return proof, err } @@ -567,25 +567,25 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") + fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) // derive the various challenges - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return err } - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return err } - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return err } diff --git a/ecc/bw6-761/fr/sumcheck/sumcheck.go b/ecc/bw6-761/fr/sumcheck/sumcheck.go index 1c6afa936..ea12b4e82 100644 --- a/ecc/bw6-761/fr/sumcheck/sumcheck.go +++ b/ecc/bw6-761/fr/sumcheck/sumcheck.go @@ -66,8 +66,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) } for i := range settings.BaseChallenges { diff --git a/ecc/bw6-761/kzg/kzg.go b/ecc/bw6-761/kzg/kzg.go index 8984c2ef7..ca384b4af 100644 --- a/ecc/bw6-761/kzg/kzg.go +++ b/ecc/bw6-761/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, "gamma") + fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } From 2d26a64358fb996218e99bd8040b596b9fbdc1c9 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 01:54:29 +0100 Subject: [PATCH 07/19] feat: overflow if long challenge name --- fiat-shamir/transcript.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fiat-shamir/transcript.go b/fiat-shamir/transcript.go index e43c44e26..cca628f97 100644 --- a/fiat-shamir/transcript.go +++ b/fiat-shamir/transcript.go @@ -125,11 +125,10 @@ func (t *Transcript) ComputeChallenge(challengeID string) ([]byte, error) { // doesn't provide WriteString method (which does hash to field // internally). return nil, fmt.Errorf("hash function doesn't provide challenge domain separation") - case len(challengeID) > t.h.BlockSize(): - return nil, fmt.Errorf("challenge name exceeds domain size") default: - tmp := make([]byte, t.h.BlockSize()) - copy(tmp[t.h.BlockSize()-len(challengeID):], []byte(challengeID)) + nbBlocks := (len([]byte(challengeID)) + 1 + t.h.BlockSize()) / t.h.BlockSize() + tmp := make([]byte, t.h.BlockSize()*nbBlocks) + copy(tmp[len(tmp)-len(challengeID):], []byte(challengeID)) if _, err := t.h.Write(tmp[:]); err != nil { return nil, fmt.Errorf("write: %w", err) } From ffdbace31a9c775522a71237e9778b2d6e55ee40 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 02:24:02 +0100 Subject: [PATCH 08/19] refactor: remove padding from fri --- internal/generator/fri/template/fri.go.tmpl | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/internal/generator/fri/template/fri.go.tmpl b/internal/generator/fri/template/fri.go.tmpl index ecee08ed5..7348ece6f 100644 --- a/internal/generator/fri/template/fri.go.tmpl +++ b/internal/generator/fri/template/fri.go.tmpl @@ -348,18 +348,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -378,9 +366,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges @@ -532,9 +520,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) From 821baecd374985f26eb718b4aa454e716ca7fb74 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 02:24:14 +0100 Subject: [PATCH 09/19] chore: go generate --- ecc/bls12-377/fr/fri/fri.go | 20 ++++---------------- ecc/bls12-378/fr/fri/fri.go | 20 ++++---------------- ecc/bls12-381/fr/fri/fri.go | 20 ++++---------------- ecc/bls24-315/fr/fri/fri.go | 20 ++++---------------- ecc/bls24-317/fr/fri/fri.go | 20 ++++---------------- ecc/bn254/fr/fri/fri.go | 20 ++++---------------- ecc/bw6-633/fr/fri/fri.go | 20 ++++---------------- ecc/bw6-756/fr/fri/fri.go | 20 ++++---------------- ecc/bw6-761/fr/fri/fri.go | 20 ++++---------------- 9 files changed, 36 insertions(+), 144 deletions(-) diff --git a/ecc/bls12-377/fr/fri/fri.go b/ecc/bls12-377/fr/fri/fri.go index 14f897270..9372033dc 100644 --- a/ecc/bls12-377/fr/fri/fri.go +++ b/ecc/bls12-377/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls12-378/fr/fri/fri.go b/ecc/bls12-378/fr/fri/fri.go index 78672890d..63ddd97ff 100644 --- a/ecc/bls12-378/fr/fri/fri.go +++ b/ecc/bls12-378/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls12-381/fr/fri/fri.go b/ecc/bls12-381/fr/fri/fri.go index e6799db6f..8acf3f124 100644 --- a/ecc/bls12-381/fr/fri/fri.go +++ b/ecc/bls12-381/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls24-315/fr/fri/fri.go b/ecc/bls24-315/fr/fri/fri.go index 5770496f0..7c0565f38 100644 --- a/ecc/bls24-315/fr/fri/fri.go +++ b/ecc/bls24-315/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls24-317/fr/fri/fri.go b/ecc/bls24-317/fr/fri/fri.go index 2bb0ec47f..0b18e52b5 100644 --- a/ecc/bls24-317/fr/fri/fri.go +++ b/ecc/bls24-317/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bn254/fr/fri/fri.go b/ecc/bn254/fr/fri/fri.go index 027b89700..07fb16642 100644 --- a/ecc/bn254/fr/fri/fri.go +++ b/ecc/bn254/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bw6-633/fr/fri/fri.go b/ecc/bw6-633/fr/fri/fri.go index a1f96048e..6fb16597a 100644 --- a/ecc/bw6-633/fr/fri/fri.go +++ b/ecc/bw6-633/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bw6-756/fr/fri/fri.go b/ecc/bw6-756/fr/fri/fri.go index efe5f501a..ab5e92ccf 100644 --- a/ecc/bw6-756/fr/fri/fri.go +++ b/ecc/bw6-756/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bw6-761/fr/fri/fri.go b/ecc/bw6-761/fr/fri/fri.go index 290b000f8..6aac92393 100644 --- a/ecc/bw6-761/fr/fri/fri.go +++ b/ecc/bw6-761/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) xi := make([]fr.Element, s.nbSteps) From c173c8c0865d8798679ad164e6732d83ee3a3c15 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 11:46:49 +0100 Subject: [PATCH 10/19] fix: challenge pad length --- fiat-shamir/transcript.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fiat-shamir/transcript.go b/fiat-shamir/transcript.go index cca628f97..e712d7627 100644 --- a/fiat-shamir/transcript.go +++ b/fiat-shamir/transcript.go @@ -127,7 +127,7 @@ func (t *Transcript) ComputeChallenge(challengeID string) ([]byte, error) { return nil, fmt.Errorf("hash function doesn't provide challenge domain separation") default: nbBlocks := (len([]byte(challengeID)) + 1 + t.h.BlockSize()) / t.h.BlockSize() - tmp := make([]byte, t.h.BlockSize()*nbBlocks) + tmp := make([]byte, (t.h.BlockSize()-1)*nbBlocks) copy(tmp[len(tmp)-len(challengeID):], []byte(challengeID)) if _, err := t.h.Write(tmp[:]); err != nil { return nil, fmt.Errorf("write: %w", err) From ad7a2816a7a52c2470abda18b1de4f386059c7b6 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 12:14:23 +0100 Subject: [PATCH 11/19] fix: mimc requires full block --- fiat-shamir/transcript.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fiat-shamir/transcript.go b/fiat-shamir/transcript.go index e712d7627..7ee2dfc27 100644 --- a/fiat-shamir/transcript.go +++ b/fiat-shamir/transcript.go @@ -127,7 +127,7 @@ func (t *Transcript) ComputeChallenge(challengeID string) ([]byte, error) { return nil, fmt.Errorf("hash function doesn't provide challenge domain separation") default: nbBlocks := (len([]byte(challengeID)) + 1 + t.h.BlockSize()) / t.h.BlockSize() - tmp := make([]byte, (t.h.BlockSize()-1)*nbBlocks) + tmp := make([]byte, (t.h.BlockSize())*nbBlocks) copy(tmp[len(tmp)-len(challengeID):], []byte(challengeID)) if _, err := t.h.Write(tmp[:]); err != nil { return nil, fmt.Errorf("write: %w", err) From 9a5013f204b2d0399ec2d0443f476e331c7f4a30 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 23:54:28 +0100 Subject: [PATCH 12/19] feat: direct challenge hashing --- fiat-shamir/options.go | 12 +----------- fiat-shamir/transcript.go | 22 ++-------------------- 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/fiat-shamir/options.go b/fiat-shamir/options.go index 3e9832ae1..22875a464 100644 --- a/fiat-shamir/options.go +++ b/fiat-shamir/options.go @@ -1,22 +1,12 @@ package fiatshamir type transcriptConfig struct { - withDomainSeparation bool - fixedChallenges []string + fixedChallenges []string } // TranscriptOption allows modifying the [Transcript] operation. type TranscriptOption func(tc *transcriptConfig) error -// WithDomainSeparation adds domain separation string `string:` when hashing -// challenge name as defined in RCF 9380. -func WithDomainSeparation() TranscriptOption { - return func(tc *transcriptConfig) error { - tc.withDomainSeparation = true - return nil - } -} - // WithStaticChallenges fixes the allowed challenges. Otherwise challenges are // appended when bound. func WithStaticChallenges(challenges ...string) TranscriptOption { diff --git a/fiat-shamir/transcript.go b/fiat-shamir/transcript.go index 7ee2dfc27..324c3763c 100644 --- a/fiat-shamir/transcript.go +++ b/fiat-shamir/transcript.go @@ -113,26 +113,8 @@ func (t *Transcript) ComputeChallenge(challengeID string) ([]byte, error) { t.h.Reset() defer t.h.Reset() - htf, ok := t.h.(interface{ WriteString(rawBytes []byte) error }) - switch { - case t.config.withDomainSeparation && ok: - // requested domain separation and the hash function has the method - if err := htf.WriteString([]byte(challengeID)); err != nil { - return nil, fmt.Errorf("write string: %w", err) - } - case t.config.withDomainSeparation && !ok: - // problem - we requested domain separation buth the hash function - // doesn't provide WriteString method (which does hash to field - // internally). - return nil, fmt.Errorf("hash function doesn't provide challenge domain separation") - default: - nbBlocks := (len([]byte(challengeID)) + 1 + t.h.BlockSize()) / t.h.BlockSize() - tmp := make([]byte, (t.h.BlockSize())*nbBlocks) - copy(tmp[len(tmp)-len(challengeID):], []byte(challengeID)) - if _, err := t.h.Write(tmp[:]); err != nil { - return nil, fmt.Errorf("write: %w", err) - } - + if _, err := t.h.Write([]byte(challengeID)); err != nil { + return nil, fmt.Errorf("write: %w", err) } // write the previous challenge if it's not the first challenge From 8717dacea39fc69419a57d1957f33c36c4b6e1c4 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 19 Dec 2023 23:59:57 +0100 Subject: [PATCH 13/19] Revert "chore: use options in templates" This reverts commit 3920d8e79fc8be5ef8472dafec1051e5fb7d529d. --- internal/generator/fri/template/fri.go.tmpl | 8 ++++---- internal/generator/gkr/template/gkr.go.tmpl | 4 +++- internal/generator/kzg/template/kzg.go.tmpl | 2 +- .../pedersen/template/pedersen.go.tmpl | 2 +- .../permutation/template/permutation.go.tmpl | 16 +++++++-------- .../generator/plookup/template/table.go.tmpl | 8 ++++---- .../generator/plookup/template/vector.go.tmpl | 20 +++++++++---------- .../sumcheck/template/sumcheck.go.tmpl | 3 ++- .../small_rational/gkr/gkr.go | 4 +++- .../small_rational/sumcheck/sumcheck.go | 3 ++- 10 files changed, 38 insertions(+), 32 deletions(-) diff --git a/internal/generator/fri/template/fri.go.tmpl b/internal/generator/fri/template/fri.go.tmpl index 7348ece6f..3434c4882 100644 --- a/internal/generator/fri/template/fri.go.tmpl +++ b/internal/generator/fri/template/fri.go.tmpl @@ -368,8 +368,8 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El for i := 0; i < s.nbSteps; i++ { xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -522,8 +522,8 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro for i := 0; i < s.nbSteps; i++ { xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/internal/generator/gkr/template/gkr.go.tmpl b/internal/generator/gkr/template/gkr.go.tmpl index 9a00516cd..6a09ac332 100644 --- a/internal/generator/gkr/template/gkr.go.tmpl +++ b/internal/generator/gkr/template/gkr.go.tmpl @@ -475,7 +475,9 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript( + transcriptSettings.Hash, challengeNames...) + o.transcript = &transcript for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/internal/generator/kzg/template/kzg.go.tmpl b/internal/generator/kzg/template/kzg.go.tmpl index fa83fbe8e..632c47c2b 100644 --- a/internal/generator/kzg/template/kzg.go.tmpl +++ b/internal/generator/kzg/template/kzg.go.tmpl @@ -538,7 +538,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) + fs := fiatshamir.NewTranscript(hf, "gamma") if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/internal/generator/pedersen/template/pedersen.go.tmpl b/internal/generator/pedersen/template/pedersen.go.tmpl index bcbf6951c..c84d17559 100644 --- a/internal/generator/pedersen/template/pedersen.go.tmpl +++ b/internal/generator/pedersen/template/pedersen.go.tmpl @@ -207,7 +207,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) + t := fiatshamir.NewTranscript(sha256.New(), "r") for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/internal/generator/permutation/template/permutation.go.tmpl b/internal/generator/permutation/template/permutation.go.tmpl index 6dd466c1c..9ef791a63 100644 --- a/internal/generator/permutation/template/permutation.go.tmpl +++ b/internal/generator/permutation/template/permutation.go.tmpl @@ -138,7 +138,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // commit t1, t2 ct1 := make([]fr.Element, s) @@ -159,7 +159,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive challenge for z - epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return proof, err } @@ -188,7 +188,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { lsNum := evaluateSecondPartNumReverse(lz, d) // derive challenge used for the folding - omega, err := deriveRandomness(fs, "omega", &proof.z) + omega, err := deriveRandomness(&fs, "omega", &proof.z) if err != nil { return proof, err } @@ -211,7 +211,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive the evaluation challenge - eta, err := deriveRandomness(fs, "eta", &proof.q) + eta, err := deriveRandomness(&fs, "eta", &proof.q) if err != nil { return proof, err } @@ -261,20 +261,20 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // derive the challenges - epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return err } - omega, err := deriveRandomness(fs, "omega", &proof.z) + omega, err := deriveRandomness(&fs, "omega", &proof.z) if err != nil { return err } - eta, err := deriveRandomness(fs, "eta", &proof.q) + eta, err := deriveRandomness(&fs, "eta", &proof.q) if err != nil { return err } diff --git a/internal/generator/plookup/template/table.go.tmpl b/internal/generator/plookup/template/table.go.tmpl index 3d4459c66..29f0339bf 100644 --- a/internal/generator/plookup/template/table.go.tmpl +++ b/internal/generator/plookup/template/table.go.tmpl @@ -52,7 +52,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check the sizes if len(f) != len(t) { @@ -127,7 +127,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, comms[nbRows+i] = new(kzg.Digest) comms[nbRows+i].Set(&proof.ts[i]) } - lambda, err := deriveRandomness(fs, "lambda", comms...) + lambda, err := deriveRandomness(&fs, "lambda", comms...) if err != nil { return proof, err } @@ -165,7 +165,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { @@ -179,7 +179,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { comms[i] = &proof.fs[i] comms[i+nbRows] = &proof.ts[i] } - lambda, err := deriveRandomness(fs, "lambda", comms...) + lambda, err := deriveRandomness(&fs, "lambda", comms...) if err != nil { return err } diff --git a/internal/generator/plookup/template/vector.go.tmpl b/internal/generator/plookup/template/vector.go.tmpl index 4c596a51e..1970b864f 100644 --- a/internal/generator/plookup/template/vector.go.tmpl +++ b/internal/generator/plookup/template/vector.go.tmpl @@ -346,7 +346,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // create domains var domainSmall *fft.Domain @@ -424,11 +424,11 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // derive beta, gamma - beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return proof, err } - gamma, err := deriveRandomness(fs, "gamma") + gamma, err := deriveRandomness(&fs, "gamma") if err != nil { return proof, err } @@ -478,7 +478,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er lh1h2 := evaluateOverlapH1h2BitReversed(_lh1, _lh2, domainBig) // compute the quotient - alpha, err := deriveRandomness(fs, "alpha", &proof.z) + alpha, err := deriveRandomness(&fs, "alpha", &proof.z) if err != nil { return proof, err } @@ -489,7 +489,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // build the opening proofs - nu, err := deriveRandomness(fs, "nu", &proof.h) + nu, err := deriveRandomness(&fs, "nu", &proof.h) if err != nil { return proof, err } @@ -550,25 +550,25 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // derive the various challenges - beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return err } - gamma, err := deriveRandomness(fs, "gamma") + gamma, err := deriveRandomness(&fs, "gamma") if err != nil { return err } - alpha, err := deriveRandomness(fs, "alpha", &proof.z) + alpha, err := deriveRandomness(&fs, "alpha", &proof.z) if err != nil { return err } - nu, err := deriveRandomness(fs, "nu", &proof.h) + nu, err := deriveRandomness(&fs, "nu", &proof.h) if err != nil { return err } diff --git a/internal/generator/sumcheck/template/sumcheck.go.tmpl b/internal/generator/sumcheck/template/sumcheck.go.tmpl index 90a60cb02..80881bdcc 100644 --- a/internal/generator/sumcheck/template/sumcheck.go.tmpl +++ b/internal/generator/sumcheck/template/sumcheck.go.tmpl @@ -48,7 +48,8 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) + settings.Transcript = &transcript } for i := range settings.BaseChallenges { diff --git a/internal/generator/test_vector_utils/small_rational/gkr/gkr.go b/internal/generator/test_vector_utils/small_rational/gkr/gkr.go index 839abf2e7..ae7261e52 100644 --- a/internal/generator/test_vector_utils/small_rational/gkr/gkr.go +++ b/internal/generator/test_vector_utils/small_rational/gkr/gkr.go @@ -490,7 +490,9 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript( + transcriptSettings.Hash, challengeNames...) + o.transcript = &transcript for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/internal/generator/test_vector_utils/small_rational/sumcheck/sumcheck.go b/internal/generator/test_vector_utils/small_rational/sumcheck/sumcheck.go index 236d7fbd6..4f33c8017 100644 --- a/internal/generator/test_vector_utils/small_rational/sumcheck/sumcheck.go +++ b/internal/generator/test_vector_utils/small_rational/sumcheck/sumcheck.go @@ -66,7 +66,8 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) + settings.Transcript = &transcript } for i := range settings.BaseChallenges { From 8ad0d86d1aa2e06d757bb2bc0c0c30b442283b3b Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Wed, 20 Dec 2023 00:03:17 +0100 Subject: [PATCH 14/19] Revert "refactor: remove padding from fri" This reverts commit ffdbace31a9c775522a71237e9778b2d6e55ee40. --- internal/generator/fri/template/fri.go.tmpl | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/internal/generator/fri/template/fri.go.tmpl b/internal/generator/fri/template/fri.go.tmpl index 3434c4882..f226f87a4 100644 --- a/internal/generator/fri/template/fri.go.tmpl +++ b/internal/generator/fri/template/fri.go.tmpl @@ -348,6 +348,18 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } +// paddNaming takes s = 0xA1.... and turns +// it into s' = 0xA1.. || 0..0 of size frSize bytes. +// Using this, when writing the domain separator in FiatShamir, it takes +// the same size as a snark variable (=number of byte in the block of a snark compliant +// hash function like mimc), so it is compliant with snark circuit. +func paddNaming(s string, size int) string { + a := make([]byte, size) + b := []byte(s) + copy(a, b) + return string(a) +} + // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -366,7 +378,7 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) fs := fiatshamir.NewTranscript(s.h, xis...) @@ -520,7 +532,7 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } xis[s.nbSteps] = paddNaming("s0", fr.Bytes) fs := fiatshamir.NewTranscript(s.h, xis...) From be4b28d4a82a061664ad026e62820b4add7a7be5 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Wed, 20 Dec 2023 00:04:15 +0100 Subject: [PATCH 15/19] revert: remove transcript options --- fiat-shamir/options.go | 25 ------------------------- fiat-shamir/transcript.go | 13 ++++--------- 2 files changed, 4 insertions(+), 34 deletions(-) delete mode 100644 fiat-shamir/options.go diff --git a/fiat-shamir/options.go b/fiat-shamir/options.go deleted file mode 100644 index 22875a464..000000000 --- a/fiat-shamir/options.go +++ /dev/null @@ -1,25 +0,0 @@ -package fiatshamir - -type transcriptConfig struct { - fixedChallenges []string -} - -// TranscriptOption allows modifying the [Transcript] operation. -type TranscriptOption func(tc *transcriptConfig) error - -// WithStaticChallenges fixes the allowed challenges. Otherwise challenges are -// appended when bound. -func WithStaticChallenges(challenges ...string) TranscriptOption { - return func(tc *transcriptConfig) error { - tc.fixedChallenges = challenges - return nil - } -} - -func newConfig(opts ...TranscriptOption) *transcriptConfig { - tc := &transcriptConfig{} - for _, opt := range opts { - opt(tc) - } - return tc -} diff --git a/fiat-shamir/transcript.go b/fiat-shamir/transcript.go index 324c3763c..8dc7e3163 100644 --- a/fiat-shamir/transcript.go +++ b/fiat-shamir/transcript.go @@ -34,8 +34,6 @@ type Transcript struct { challenges map[string]challenge previous *challenge - - config *transcriptConfig } type challenge struct { @@ -48,18 +46,15 @@ type challenge struct { // NewTranscript returns a new transcript. // h is the hash function that is used to compute the challenges. // challenges are the name of the challenges. The order of the challenges IDs matters. -func NewTranscript(h hash.Hash, opts ...TranscriptOption) *Transcript { - cfg := newConfig(opts...) +func NewTranscript(h hash.Hash, challengesID ...string) *Transcript { + n := len(challengesID) challenges := make(map[string]challenge) - if cfg.fixedChallenges != nil { - for i := range cfg.fixedChallenges { - challenges[cfg.fixedChallenges[i]] = challenge{position: i} - } + for i := range challengesID { + challenges[challengesID[i]] = challenge{position: i} } t := &Transcript{ challenges: challenges, h: h, - config: cfg, } return t } From 136750231008e1db8511d1b46d7805d87cf240cb Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Wed, 20 Dec 2023 00:17:13 +0100 Subject: [PATCH 16/19] chore: cleanup templates --- fiat-shamir/transcript.go | 8 +------- fiat-shamir/transcript_test.go | 9 +-------- internal/generator/gkr/template/gkr.go.tmpl | 4 +--- .../permutation/template/permutation.go.tmpl | 12 ++++++------ .../generator/plookup/template/table.go.tmpl | 4 ++-- .../generator/plookup/template/vector.go.tmpl | 16 ++++++++-------- .../generator/sumcheck/template/sumcheck.go.tmpl | 2 +- .../test_vector_utils/small_rational/gkr/gkr.go | 4 +--- .../small_rational/sumcheck/sumcheck.go | 2 +- 9 files changed, 22 insertions(+), 39 deletions(-) diff --git a/fiat-shamir/transcript.go b/fiat-shamir/transcript.go index 8dc7e3163..a50f1ba65 100644 --- a/fiat-shamir/transcript.go +++ b/fiat-shamir/transcript.go @@ -47,7 +47,6 @@ type challenge struct { // h is the hash function that is used to compute the challenges. // challenges are the name of the challenges. The order of the challenges IDs matters. func NewTranscript(h hash.Hash, challengesID ...string) *Transcript { - n := len(challengesID) challenges := make(map[string]challenge) for i := range challengesID { challenges[challengesID[i]] = challenge{position: i} @@ -67,12 +66,7 @@ func (t *Transcript) Bind(challengeID string, bValue []byte) error { currentChallenge, ok := t.challenges[challengeID] if !ok { - if t.config.fixedChallenges != nil { - return errChallengeNotFound - } else { - t.challenges[challengeID] = challenge{position: len(t.challenges)} - currentChallenge = t.challenges[challengeID] - } + return errChallengeNotFound } if currentChallenge.isComputed { diff --git a/fiat-shamir/transcript_test.go b/fiat-shamir/transcript_test.go index f2ca5b9bb..8451aae32 100644 --- a/fiat-shamir/transcript_test.go +++ b/fiat-shamir/transcript_test.go @@ -22,7 +22,7 @@ import ( func initTranscript() *Transcript { - fs := NewTranscript(sha256.New(), WithStaticChallenges("alpha", "beta", "gamma")) + fs := NewTranscript(sha256.New(), "alpha", "beta", "gamma") values := [][]byte{[]byte("v1"), []byte("v2"), []byte("v3"), []byte("v4"), []byte("v5"), []byte("v6")} if err := fs.Bind("alpha", values[0]); err != nil { @@ -139,10 +139,3 @@ func TestBindToComputedChallenge(t *testing.T) { } } - -func TestDynamicChallenges(t *testing.T) { - ts := NewTranscript(sha256.New()) - if err := ts.Bind("alpha", []byte("test")); err != nil { - t.Fatal(err) - } -} diff --git a/internal/generator/gkr/template/gkr.go.tmpl b/internal/generator/gkr/template/gkr.go.tmpl index 6a09ac332..049702508 100644 --- a/internal/generator/gkr/template/gkr.go.tmpl +++ b/internal/generator/gkr/template/gkr.go.tmpl @@ -475,9 +475,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, challengeNames...) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/internal/generator/permutation/template/permutation.go.tmpl b/internal/generator/permutation/template/permutation.go.tmpl index 9ef791a63..c90343e4f 100644 --- a/internal/generator/permutation/template/permutation.go.tmpl +++ b/internal/generator/permutation/template/permutation.go.tmpl @@ -159,7 +159,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive challenge for z - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return proof, err } @@ -188,7 +188,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { lsNum := evaluateSecondPartNumReverse(lz, d) // derive challenge used for the folding - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return proof, err } @@ -211,7 +211,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { } // derive the evaluation challenge - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return proof, err } @@ -264,17 +264,17 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // derive the challenges - epsilon, err := deriveRandomness(&fs, "epsilon", &proof.t1, &proof.t2) + epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) if err != nil { return err } - omega, err := deriveRandomness(&fs, "omega", &proof.z) + omega, err := deriveRandomness(fs, "omega", &proof.z) if err != nil { return err } - eta, err := deriveRandomness(&fs, "eta", &proof.q) + eta, err := deriveRandomness(fs, "eta", &proof.q) if err != nil { return err } diff --git a/internal/generator/plookup/template/table.go.tmpl b/internal/generator/plookup/template/table.go.tmpl index 29f0339bf..fcdec07f8 100644 --- a/internal/generator/plookup/template/table.go.tmpl +++ b/internal/generator/plookup/template/table.go.tmpl @@ -127,7 +127,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, comms[nbRows+i] = new(kzg.Digest) comms[nbRows+i].Set(&proof.ts[i]) } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return proof, err } @@ -179,7 +179,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { comms[i] = &proof.fs[i] comms[i+nbRows] = &proof.ts[i] } - lambda, err := deriveRandomness(&fs, "lambda", comms...) + lambda, err := deriveRandomness(fs, "lambda", comms...) if err != nil { return err } diff --git a/internal/generator/plookup/template/vector.go.tmpl b/internal/generator/plookup/template/vector.go.tmpl index 1970b864f..c9f654336 100644 --- a/internal/generator/plookup/template/vector.go.tmpl +++ b/internal/generator/plookup/template/vector.go.tmpl @@ -424,11 +424,11 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // derive beta, gamma - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return proof, err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return proof, err } @@ -478,7 +478,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er lh1h2 := evaluateOverlapH1h2BitReversed(_lh1, _lh2, domainBig) // compute the quotient - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return proof, err } @@ -489,7 +489,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er } // build the opening proofs - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return proof, err } @@ -553,22 +553,22 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // derive the various challenges - beta, err := deriveRandomness(&fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) + beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) if err != nil { return err } - gamma, err := deriveRandomness(&fs, "gamma") + gamma, err := deriveRandomness(fs, "gamma") if err != nil { return err } - alpha, err := deriveRandomness(&fs, "alpha", &proof.z) + alpha, err := deriveRandomness(fs, "alpha", &proof.z) if err != nil { return err } - nu, err := deriveRandomness(&fs, "nu", &proof.h) + nu, err := deriveRandomness(fs, "nu", &proof.h) if err != nil { return err } diff --git a/internal/generator/sumcheck/template/sumcheck.go.tmpl b/internal/generator/sumcheck/template/sumcheck.go.tmpl index 80881bdcc..a4e17da82 100644 --- a/internal/generator/sumcheck/template/sumcheck.go.tmpl +++ b/internal/generator/sumcheck/template/sumcheck.go.tmpl @@ -49,7 +49,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) } if settings.Transcript == nil { transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = transcript } for i := range settings.BaseChallenges { diff --git a/internal/generator/test_vector_utils/small_rational/gkr/gkr.go b/internal/generator/test_vector_utils/small_rational/gkr/gkr.go index ae7261e52..a2bef7d1e 100644 --- a/internal/generator/test_vector_utils/small_rational/gkr/gkr.go +++ b/internal/generator/test_vector_utils/small_rational/gkr/gkr.go @@ -490,9 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - transcript := fiatshamir.NewTranscript( - transcriptSettings.Hash, challengeNames...) - o.transcript = &transcript + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, challengeNames...) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/internal/generator/test_vector_utils/small_rational/sumcheck/sumcheck.go b/internal/generator/test_vector_utils/small_rational/sumcheck/sumcheck.go index 4f33c8017..cb86eb419 100644 --- a/internal/generator/test_vector_utils/small_rational/sumcheck/sumcheck.go +++ b/internal/generator/test_vector_utils/small_rational/sumcheck/sumcheck.go @@ -67,7 +67,7 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) } if settings.Transcript == nil { transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) - settings.Transcript = &transcript + settings.Transcript = transcript } for i := range settings.BaseChallenges { From 4d4836903216dddcf95dd41e12f50d9ef4ff028c Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Wed, 20 Dec 2023 00:18:09 +0100 Subject: [PATCH 17/19] feat: pad short inputs to mimc --- internal/generator/crypto/hash/mimc/template/mimc.go.tmpl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/internal/generator/crypto/hash/mimc/template/mimc.go.tmpl b/internal/generator/crypto/hash/mimc/template/mimc.go.tmpl index 6e1b2a8d8..a752a3bcc 100644 --- a/internal/generator/crypto/hash/mimc/template/mimc.go.tmpl +++ b/internal/generator/crypto/hash/mimc/template/mimc.go.tmpl @@ -100,6 +100,14 @@ func (d *digest) BlockSize() int { // // To hash arbitrary data ([]byte not representing canonical field elements) use fr.Hash first func (d *digest) Write(p []byte) (int, error) { + // we usually expect multiple of block size. But sometimes we hash short + // values (FS transcript). Instead of forcing to hash to field, we left-pad the + // input here. + if len(p) > 0 && len(p) < BlockSize { + pp := make([]byte,BlockSize) + copy(pp[len(pp)-len(p):], p) + p = pp + } var start int for start = 0; start < len(p); start += BlockSize { From a67a63987693479a6279927aebb046a2d8519fb6 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Wed, 20 Dec 2023 00:20:04 +0100 Subject: [PATCH 18/19] chore: generate --- ecc/bls12-377/fr/fri/fri.go | 24 ++++++++++++++----- ecc/bls12-377/fr/gkr/gkr.go | 2 +- ecc/bls12-377/fr/mimc/mimc.go | 8 +++++++ ecc/bls12-377/fr/pedersen/pedersen.go | 2 +- ecc/bls12-377/fr/permutation/permutation.go | 4 ++-- ecc/bls12-377/fr/plookup/table.go | 4 ++-- ecc/bls12-377/fr/plookup/vector.go | 4 ++-- ecc/bls12-377/fr/sumcheck/sumcheck.go | 3 ++- ecc/bls12-377/kzg/kzg.go | 2 +- ecc/bls12-378/fr/fri/fri.go | 24 ++++++++++++++----- ecc/bls12-378/fr/gkr/gkr.go | 2 +- ecc/bls12-378/fr/mimc/mimc.go | 8 +++++++ ecc/bls12-378/fr/pedersen/pedersen.go | 2 +- ecc/bls12-378/fr/permutation/permutation.go | 4 ++-- ecc/bls12-378/fr/plookup/table.go | 4 ++-- ecc/bls12-378/fr/plookup/vector.go | 4 ++-- ecc/bls12-378/fr/sumcheck/sumcheck.go | 3 ++- ecc/bls12-378/kzg/kzg.go | 2 +- ecc/bls12-381/fr/fri/fri.go | 24 ++++++++++++++----- ecc/bls12-381/fr/gkr/gkr.go | 2 +- ecc/bls12-381/fr/mimc/mimc.go | 8 +++++++ ecc/bls12-381/fr/pedersen/pedersen.go | 2 +- ecc/bls12-381/fr/permutation/permutation.go | 4 ++-- ecc/bls12-381/fr/plookup/table.go | 4 ++-- ecc/bls12-381/fr/plookup/vector.go | 4 ++-- ecc/bls12-381/fr/sumcheck/sumcheck.go | 3 ++- ecc/bls12-381/kzg/kzg.go | 2 +- ecc/bls24-315/fr/fri/fri.go | 24 ++++++++++++++----- ecc/bls24-315/fr/gkr/gkr.go | 2 +- ecc/bls24-315/fr/mimc/mimc.go | 8 +++++++ ecc/bls24-315/fr/pedersen/pedersen.go | 2 +- ecc/bls24-315/fr/permutation/permutation.go | 4 ++-- ecc/bls24-315/fr/plookup/table.go | 4 ++-- ecc/bls24-315/fr/plookup/vector.go | 4 ++-- ecc/bls24-315/fr/sumcheck/sumcheck.go | 3 ++- ecc/bls24-315/kzg/kzg.go | 2 +- ecc/bls24-317/fr/fri/fri.go | 24 ++++++++++++++----- ecc/bls24-317/fr/gkr/gkr.go | 2 +- ecc/bls24-317/fr/mimc/mimc.go | 8 +++++++ ecc/bls24-317/fr/pedersen/pedersen.go | 2 +- ecc/bls24-317/fr/permutation/permutation.go | 4 ++-- ecc/bls24-317/fr/plookup/table.go | 4 ++-- ecc/bls24-317/fr/plookup/vector.go | 4 ++-- ecc/bls24-317/fr/sumcheck/sumcheck.go | 3 ++- ecc/bls24-317/kzg/kzg.go | 2 +- ecc/bn254/fr/fri/fri.go | 24 ++++++++++++++----- ecc/bn254/fr/gkr/gkr.go | 2 +- ecc/bn254/fr/mimc/mimc.go | 8 +++++++ ecc/bn254/fr/mimc/mimc_test.go | 2 +- ecc/bn254/fr/pedersen/pedersen.go | 2 +- ecc/bn254/fr/permutation/permutation.go | 4 ++-- ecc/bn254/fr/plookup/table.go | 4 ++-- ecc/bn254/fr/plookup/vector.go | 4 ++-- ecc/bn254/fr/sumcheck/sumcheck.go | 3 ++- .../test_vector_utils_test.go | 4 ++-- ecc/bn254/kzg/kzg.go | 2 +- ecc/bw6-633/fr/fri/fri.go | 24 ++++++++++++++----- ecc/bw6-633/fr/gkr/gkr.go | 2 +- ecc/bw6-633/fr/mimc/mimc.go | 8 +++++++ ecc/bw6-633/fr/pedersen/pedersen.go | 2 +- ecc/bw6-633/fr/permutation/permutation.go | 4 ++-- ecc/bw6-633/fr/plookup/table.go | 4 ++-- ecc/bw6-633/fr/plookup/vector.go | 4 ++-- ecc/bw6-633/fr/sumcheck/sumcheck.go | 3 ++- ecc/bw6-633/kzg/kzg.go | 2 +- ecc/bw6-756/fr/fri/fri.go | 24 ++++++++++++++----- ecc/bw6-756/fr/gkr/gkr.go | 2 +- ecc/bw6-756/fr/mimc/mimc.go | 8 +++++++ ecc/bw6-756/fr/pedersen/pedersen.go | 2 +- ecc/bw6-756/fr/permutation/permutation.go | 4 ++-- ecc/bw6-756/fr/plookup/table.go | 4 ++-- ecc/bw6-756/fr/plookup/vector.go | 4 ++-- ecc/bw6-756/fr/sumcheck/sumcheck.go | 3 ++- ecc/bw6-756/kzg/kzg.go | 2 +- ecc/bw6-761/fr/fri/fri.go | 24 ++++++++++++++----- ecc/bw6-761/fr/gkr/gkr.go | 2 +- ecc/bw6-761/fr/mimc/mimc.go | 8 +++++++ ecc/bw6-761/fr/pedersen/pedersen.go | 2 +- ecc/bw6-761/fr/permutation/permutation.go | 4 ++-- ecc/bw6-761/fr/plookup/table.go | 4 ++-- ecc/bw6-761/fr/plookup/vector.go | 4 ++-- ecc/bw6-761/fr/sumcheck/sumcheck.go | 3 ++- ecc/bw6-761/kzg/kzg.go | 2 +- 83 files changed, 336 insertions(+), 147 deletions(-) diff --git a/ecc/bls12-377/fr/fri/fri.go b/ecc/bls12-377/fr/fri/fri.go index 9372033dc..91cc031ee 100644 --- a/ecc/bls12-377/fr/fri/fri.go +++ b/ecc/bls12-377/fr/fri/fri.go @@ -365,6 +365,18 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } +// paddNaming takes s = 0xA1.... and turns +// it into s' = 0xA1.. || 0..0 of size frSize bytes. +// Using this, when writing the domain separator in FiatShamir, it takes +// the same size as a snark variable (=number of byte in the block of a snark compliant +// hash function like mimc), so it is compliant with snark circuit. +func paddNaming(s string, size int) string { + a := make([]byte, size) + b := []byte(s) + copy(a, b) + return string(a) +} + // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -383,10 +395,10 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -537,10 +549,10 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls12-377/fr/gkr/gkr.go b/ecc/bls12-377/fr/gkr/gkr.go index d92c6e559..19f4e9bb2 100644 --- a/ecc/bls12-377/fr/gkr/gkr.go +++ b/ecc/bls12-377/fr/gkr/gkr.go @@ -490,7 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, challengeNames...) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bls12-377/fr/mimc/mimc.go b/ecc/bls12-377/fr/mimc/mimc.go index d73781c79..d393f0d74 100644 --- a/ecc/bls12-377/fr/mimc/mimc.go +++ b/ecc/bls12-377/fr/mimc/mimc.go @@ -100,6 +100,14 @@ func (d *digest) BlockSize() int { // // To hash arbitrary data ([]byte not representing canonical field elements) use fr.Hash first func (d *digest) Write(p []byte) (int, error) { + // we usually expect multiple of block size. But sometimes we hash short + // values (FS transcript). Instead of forcing to hash to field, we left-pad the + // input here. + if len(p) > 0 && len(p) < BlockSize { + pp := make([]byte, BlockSize) + copy(pp[len(pp)-len(p):], p) + p = pp + } var start int for start = 0; start < len(p); start += BlockSize { diff --git a/ecc/bls12-377/fr/pedersen/pedersen.go b/ecc/bls12-377/fr/pedersen/pedersen.go index 3645909a5..31130283a 100644 --- a/ecc/bls12-377/fr/pedersen/pedersen.go +++ b/ecc/bls12-377/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) + t := fiatshamir.NewTranscript(sha256.New(), "r") for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bls12-377/fr/permutation/permutation.go b/ecc/bls12-377/fr/permutation/permutation.go index 9e8302018..e5c2770df 100644 --- a/ecc/bls12-377/fr/permutation/permutation.go +++ b/ecc/bls12-377/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // commit t1, t2 ct1 := make([]fr.Element, s) @@ -279,7 +279,7 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // derive the challenges epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) diff --git a/ecc/bls12-377/fr/plookup/table.go b/ecc/bls12-377/fr/plookup/table.go index 72e68891e..4a299138a 100644 --- a/ecc/bls12-377/fr/plookup/table.go +++ b/ecc/bls12-377/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check the sizes if len(f) != len(t) { @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { diff --git a/ecc/bls12-377/fr/plookup/vector.go b/ecc/bls12-377/fr/plookup/vector.go index 0998753fe..98583fded 100644 --- a/ecc/bls12-377/fr/plookup/vector.go +++ b/ecc/bls12-377/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // create domains var domainSmall *fft.Domain @@ -567,7 +567,7 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // derive the various challenges beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) diff --git a/ecc/bls12-377/fr/sumcheck/sumcheck.go b/ecc/bls12-377/fr/sumcheck/sumcheck.go index 228faa75b..cdea58ba8 100644 --- a/ecc/bls12-377/fr/sumcheck/sumcheck.go +++ b/ecc/bls12-377/fr/sumcheck/sumcheck.go @@ -66,7 +66,8 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) + settings.Transcript = transcript } for i := range settings.BaseChallenges { diff --git a/ecc/bls12-377/kzg/kzg.go b/ecc/bls12-377/kzg/kzg.go index dc8451d8a..3458d655e 100644 --- a/ecc/bls12-377/kzg/kzg.go +++ b/ecc/bls12-377/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) + fs := fiatshamir.NewTranscript(hf, "gamma") if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bls12-378/fr/fri/fri.go b/ecc/bls12-378/fr/fri/fri.go index 63ddd97ff..145e2defd 100644 --- a/ecc/bls12-378/fr/fri/fri.go +++ b/ecc/bls12-378/fr/fri/fri.go @@ -365,6 +365,18 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } +// paddNaming takes s = 0xA1.... and turns +// it into s' = 0xA1.. || 0..0 of size frSize bytes. +// Using this, when writing the domain separator in FiatShamir, it takes +// the same size as a snark variable (=number of byte in the block of a snark compliant +// hash function like mimc), so it is compliant with snark circuit. +func paddNaming(s string, size int) string { + a := make([]byte, size) + b := []byte(s) + copy(a, b) + return string(a) +} + // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -383,10 +395,10 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -537,10 +549,10 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls12-378/fr/gkr/gkr.go b/ecc/bls12-378/fr/gkr/gkr.go index 5b513de8f..c576d7aca 100644 --- a/ecc/bls12-378/fr/gkr/gkr.go +++ b/ecc/bls12-378/fr/gkr/gkr.go @@ -490,7 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, challengeNames...) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bls12-378/fr/mimc/mimc.go b/ecc/bls12-378/fr/mimc/mimc.go index 632cacd83..38cde3905 100644 --- a/ecc/bls12-378/fr/mimc/mimc.go +++ b/ecc/bls12-378/fr/mimc/mimc.go @@ -100,6 +100,14 @@ func (d *digest) BlockSize() int { // // To hash arbitrary data ([]byte not representing canonical field elements) use fr.Hash first func (d *digest) Write(p []byte) (int, error) { + // we usually expect multiple of block size. But sometimes we hash short + // values (FS transcript). Instead of forcing to hash to field, we left-pad the + // input here. + if len(p) > 0 && len(p) < BlockSize { + pp := make([]byte, BlockSize) + copy(pp[len(pp)-len(p):], p) + p = pp + } var start int for start = 0; start < len(p); start += BlockSize { diff --git a/ecc/bls12-378/fr/pedersen/pedersen.go b/ecc/bls12-378/fr/pedersen/pedersen.go index cb7585a85..96c963e3a 100644 --- a/ecc/bls12-378/fr/pedersen/pedersen.go +++ b/ecc/bls12-378/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) + t := fiatshamir.NewTranscript(sha256.New(), "r") for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bls12-378/fr/permutation/permutation.go b/ecc/bls12-378/fr/permutation/permutation.go index 609de2c71..0f7b60f1b 100644 --- a/ecc/bls12-378/fr/permutation/permutation.go +++ b/ecc/bls12-378/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // commit t1, t2 ct1 := make([]fr.Element, s) @@ -279,7 +279,7 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // derive the challenges epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) diff --git a/ecc/bls12-378/fr/plookup/table.go b/ecc/bls12-378/fr/plookup/table.go index 1dbcdc447..cff6a8cf6 100644 --- a/ecc/bls12-378/fr/plookup/table.go +++ b/ecc/bls12-378/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check the sizes if len(f) != len(t) { @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { diff --git a/ecc/bls12-378/fr/plookup/vector.go b/ecc/bls12-378/fr/plookup/vector.go index e27e3aa33..59d37e7e1 100644 --- a/ecc/bls12-378/fr/plookup/vector.go +++ b/ecc/bls12-378/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // create domains var domainSmall *fft.Domain @@ -567,7 +567,7 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // derive the various challenges beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) diff --git a/ecc/bls12-378/fr/sumcheck/sumcheck.go b/ecc/bls12-378/fr/sumcheck/sumcheck.go index c843b0873..88c1ed861 100644 --- a/ecc/bls12-378/fr/sumcheck/sumcheck.go +++ b/ecc/bls12-378/fr/sumcheck/sumcheck.go @@ -66,7 +66,8 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) + settings.Transcript = transcript } for i := range settings.BaseChallenges { diff --git a/ecc/bls12-378/kzg/kzg.go b/ecc/bls12-378/kzg/kzg.go index 66c64f185..3624d41e0 100644 --- a/ecc/bls12-378/kzg/kzg.go +++ b/ecc/bls12-378/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) + fs := fiatshamir.NewTranscript(hf, "gamma") if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bls12-381/fr/fri/fri.go b/ecc/bls12-381/fr/fri/fri.go index 8acf3f124..52bf2091e 100644 --- a/ecc/bls12-381/fr/fri/fri.go +++ b/ecc/bls12-381/fr/fri/fri.go @@ -365,6 +365,18 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } +// paddNaming takes s = 0xA1.... and turns +// it into s' = 0xA1.. || 0..0 of size frSize bytes. +// Using this, when writing the domain separator in FiatShamir, it takes +// the same size as a snark variable (=number of byte in the block of a snark compliant +// hash function like mimc), so it is compliant with snark circuit. +func paddNaming(s string, size int) string { + a := make([]byte, size) + b := []byte(s) + copy(a, b) + return string(a) +} + // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -383,10 +395,10 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -537,10 +549,10 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls12-381/fr/gkr/gkr.go b/ecc/bls12-381/fr/gkr/gkr.go index c9a2a4044..64b48da06 100644 --- a/ecc/bls12-381/fr/gkr/gkr.go +++ b/ecc/bls12-381/fr/gkr/gkr.go @@ -490,7 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, challengeNames...) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bls12-381/fr/mimc/mimc.go b/ecc/bls12-381/fr/mimc/mimc.go index 6db7f47c2..716a655b4 100644 --- a/ecc/bls12-381/fr/mimc/mimc.go +++ b/ecc/bls12-381/fr/mimc/mimc.go @@ -100,6 +100,14 @@ func (d *digest) BlockSize() int { // // To hash arbitrary data ([]byte not representing canonical field elements) use fr.Hash first func (d *digest) Write(p []byte) (int, error) { + // we usually expect multiple of block size. But sometimes we hash short + // values (FS transcript). Instead of forcing to hash to field, we left-pad the + // input here. + if len(p) > 0 && len(p) < BlockSize { + pp := make([]byte, BlockSize) + copy(pp[len(pp)-len(p):], p) + p = pp + } var start int for start = 0; start < len(p); start += BlockSize { diff --git a/ecc/bls12-381/fr/pedersen/pedersen.go b/ecc/bls12-381/fr/pedersen/pedersen.go index fe5dca8a2..204c6f13b 100644 --- a/ecc/bls12-381/fr/pedersen/pedersen.go +++ b/ecc/bls12-381/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) + t := fiatshamir.NewTranscript(sha256.New(), "r") for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bls12-381/fr/permutation/permutation.go b/ecc/bls12-381/fr/permutation/permutation.go index 892a370d4..00c0cebfd 100644 --- a/ecc/bls12-381/fr/permutation/permutation.go +++ b/ecc/bls12-381/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // commit t1, t2 ct1 := make([]fr.Element, s) @@ -279,7 +279,7 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // derive the challenges epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) diff --git a/ecc/bls12-381/fr/plookup/table.go b/ecc/bls12-381/fr/plookup/table.go index 629198c44..c191752da 100644 --- a/ecc/bls12-381/fr/plookup/table.go +++ b/ecc/bls12-381/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check the sizes if len(f) != len(t) { @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { diff --git a/ecc/bls12-381/fr/plookup/vector.go b/ecc/bls12-381/fr/plookup/vector.go index cb0695abb..4ed22fb16 100644 --- a/ecc/bls12-381/fr/plookup/vector.go +++ b/ecc/bls12-381/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // create domains var domainSmall *fft.Domain @@ -567,7 +567,7 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // derive the various challenges beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) diff --git a/ecc/bls12-381/fr/sumcheck/sumcheck.go b/ecc/bls12-381/fr/sumcheck/sumcheck.go index 4da3022a5..7f7d605ef 100644 --- a/ecc/bls12-381/fr/sumcheck/sumcheck.go +++ b/ecc/bls12-381/fr/sumcheck/sumcheck.go @@ -66,7 +66,8 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) + settings.Transcript = transcript } for i := range settings.BaseChallenges { diff --git a/ecc/bls12-381/kzg/kzg.go b/ecc/bls12-381/kzg/kzg.go index 69c5d03f3..42540cd28 100644 --- a/ecc/bls12-381/kzg/kzg.go +++ b/ecc/bls12-381/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) + fs := fiatshamir.NewTranscript(hf, "gamma") if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bls24-315/fr/fri/fri.go b/ecc/bls24-315/fr/fri/fri.go index 7c0565f38..b117c0235 100644 --- a/ecc/bls24-315/fr/fri/fri.go +++ b/ecc/bls24-315/fr/fri/fri.go @@ -365,6 +365,18 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } +// paddNaming takes s = 0xA1.... and turns +// it into s' = 0xA1.. || 0..0 of size frSize bytes. +// Using this, when writing the domain separator in FiatShamir, it takes +// the same size as a snark variable (=number of byte in the block of a snark compliant +// hash function like mimc), so it is compliant with snark circuit. +func paddNaming(s string, size int) string { + a := make([]byte, size) + b := []byte(s) + copy(a, b) + return string(a) +} + // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -383,10 +395,10 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -537,10 +549,10 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls24-315/fr/gkr/gkr.go b/ecc/bls24-315/fr/gkr/gkr.go index 4ed8e075c..ca1f4c833 100644 --- a/ecc/bls24-315/fr/gkr/gkr.go +++ b/ecc/bls24-315/fr/gkr/gkr.go @@ -490,7 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, challengeNames...) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bls24-315/fr/mimc/mimc.go b/ecc/bls24-315/fr/mimc/mimc.go index c6a3f729d..1912d66df 100644 --- a/ecc/bls24-315/fr/mimc/mimc.go +++ b/ecc/bls24-315/fr/mimc/mimc.go @@ -100,6 +100,14 @@ func (d *digest) BlockSize() int { // // To hash arbitrary data ([]byte not representing canonical field elements) use fr.Hash first func (d *digest) Write(p []byte) (int, error) { + // we usually expect multiple of block size. But sometimes we hash short + // values (FS transcript). Instead of forcing to hash to field, we left-pad the + // input here. + if len(p) > 0 && len(p) < BlockSize { + pp := make([]byte, BlockSize) + copy(pp[len(pp)-len(p):], p) + p = pp + } var start int for start = 0; start < len(p); start += BlockSize { diff --git a/ecc/bls24-315/fr/pedersen/pedersen.go b/ecc/bls24-315/fr/pedersen/pedersen.go index dd6ba9897..961616211 100644 --- a/ecc/bls24-315/fr/pedersen/pedersen.go +++ b/ecc/bls24-315/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) + t := fiatshamir.NewTranscript(sha256.New(), "r") for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bls24-315/fr/permutation/permutation.go b/ecc/bls24-315/fr/permutation/permutation.go index eec77c896..6a87a7c92 100644 --- a/ecc/bls24-315/fr/permutation/permutation.go +++ b/ecc/bls24-315/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // commit t1, t2 ct1 := make([]fr.Element, s) @@ -279,7 +279,7 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // derive the challenges epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) diff --git a/ecc/bls24-315/fr/plookup/table.go b/ecc/bls24-315/fr/plookup/table.go index 47000318a..b710796f2 100644 --- a/ecc/bls24-315/fr/plookup/table.go +++ b/ecc/bls24-315/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check the sizes if len(f) != len(t) { @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { diff --git a/ecc/bls24-315/fr/plookup/vector.go b/ecc/bls24-315/fr/plookup/vector.go index 379b53368..6fefe36ac 100644 --- a/ecc/bls24-315/fr/plookup/vector.go +++ b/ecc/bls24-315/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // create domains var domainSmall *fft.Domain @@ -567,7 +567,7 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // derive the various challenges beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) diff --git a/ecc/bls24-315/fr/sumcheck/sumcheck.go b/ecc/bls24-315/fr/sumcheck/sumcheck.go index e926b6951..3c7412347 100644 --- a/ecc/bls24-315/fr/sumcheck/sumcheck.go +++ b/ecc/bls24-315/fr/sumcheck/sumcheck.go @@ -66,7 +66,8 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) + settings.Transcript = transcript } for i := range settings.BaseChallenges { diff --git a/ecc/bls24-315/kzg/kzg.go b/ecc/bls24-315/kzg/kzg.go index 6859c91ef..43e16d9c0 100644 --- a/ecc/bls24-315/kzg/kzg.go +++ b/ecc/bls24-315/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) + fs := fiatshamir.NewTranscript(hf, "gamma") if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bls24-317/fr/fri/fri.go b/ecc/bls24-317/fr/fri/fri.go index 0b18e52b5..135cfb127 100644 --- a/ecc/bls24-317/fr/fri/fri.go +++ b/ecc/bls24-317/fr/fri/fri.go @@ -365,6 +365,18 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } +// paddNaming takes s = 0xA1.... and turns +// it into s' = 0xA1.. || 0..0 of size frSize bytes. +// Using this, when writing the domain separator in FiatShamir, it takes +// the same size as a snark variable (=number of byte in the block of a snark compliant +// hash function like mimc), so it is compliant with snark circuit. +func paddNaming(s string, size int) string { + a := make([]byte, size) + b := []byte(s) + copy(a, b) + return string(a) +} + // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -383,10 +395,10 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -537,10 +549,10 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls24-317/fr/gkr/gkr.go b/ecc/bls24-317/fr/gkr/gkr.go index a8194a898..0dc5b4883 100644 --- a/ecc/bls24-317/fr/gkr/gkr.go +++ b/ecc/bls24-317/fr/gkr/gkr.go @@ -490,7 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, challengeNames...) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bls24-317/fr/mimc/mimc.go b/ecc/bls24-317/fr/mimc/mimc.go index 9947cfeba..c0050e056 100644 --- a/ecc/bls24-317/fr/mimc/mimc.go +++ b/ecc/bls24-317/fr/mimc/mimc.go @@ -100,6 +100,14 @@ func (d *digest) BlockSize() int { // // To hash arbitrary data ([]byte not representing canonical field elements) use fr.Hash first func (d *digest) Write(p []byte) (int, error) { + // we usually expect multiple of block size. But sometimes we hash short + // values (FS transcript). Instead of forcing to hash to field, we left-pad the + // input here. + if len(p) > 0 && len(p) < BlockSize { + pp := make([]byte, BlockSize) + copy(pp[len(pp)-len(p):], p) + p = pp + } var start int for start = 0; start < len(p); start += BlockSize { diff --git a/ecc/bls24-317/fr/pedersen/pedersen.go b/ecc/bls24-317/fr/pedersen/pedersen.go index 9e720f20b..684498ef1 100644 --- a/ecc/bls24-317/fr/pedersen/pedersen.go +++ b/ecc/bls24-317/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) + t := fiatshamir.NewTranscript(sha256.New(), "r") for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bls24-317/fr/permutation/permutation.go b/ecc/bls24-317/fr/permutation/permutation.go index 8c1032fed..ef7b7d2e3 100644 --- a/ecc/bls24-317/fr/permutation/permutation.go +++ b/ecc/bls24-317/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // commit t1, t2 ct1 := make([]fr.Element, s) @@ -279,7 +279,7 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // derive the challenges epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) diff --git a/ecc/bls24-317/fr/plookup/table.go b/ecc/bls24-317/fr/plookup/table.go index 93d33262e..5c1607cdb 100644 --- a/ecc/bls24-317/fr/plookup/table.go +++ b/ecc/bls24-317/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check the sizes if len(f) != len(t) { @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { diff --git a/ecc/bls24-317/fr/plookup/vector.go b/ecc/bls24-317/fr/plookup/vector.go index 950184275..05f916788 100644 --- a/ecc/bls24-317/fr/plookup/vector.go +++ b/ecc/bls24-317/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // create domains var domainSmall *fft.Domain @@ -567,7 +567,7 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // derive the various challenges beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) diff --git a/ecc/bls24-317/fr/sumcheck/sumcheck.go b/ecc/bls24-317/fr/sumcheck/sumcheck.go index 2e22a9334..81ff2e5f2 100644 --- a/ecc/bls24-317/fr/sumcheck/sumcheck.go +++ b/ecc/bls24-317/fr/sumcheck/sumcheck.go @@ -66,7 +66,8 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) + settings.Transcript = transcript } for i := range settings.BaseChallenges { diff --git a/ecc/bls24-317/kzg/kzg.go b/ecc/bls24-317/kzg/kzg.go index ab58f302c..791e3d1f8 100644 --- a/ecc/bls24-317/kzg/kzg.go +++ b/ecc/bls24-317/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) + fs := fiatshamir.NewTranscript(hf, "gamma") if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bn254/fr/fri/fri.go b/ecc/bn254/fr/fri/fri.go index 07fb16642..6559829ec 100644 --- a/ecc/bn254/fr/fri/fri.go +++ b/ecc/bn254/fr/fri/fri.go @@ -365,6 +365,18 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } +// paddNaming takes s = 0xA1.... and turns +// it into s' = 0xA1.. || 0..0 of size frSize bytes. +// Using this, when writing the domain separator in FiatShamir, it takes +// the same size as a snark variable (=number of byte in the block of a snark compliant +// hash function like mimc), so it is compliant with snark circuit. +func paddNaming(s string, size int) string { + a := make([]byte, size) + b := []byte(s) + copy(a, b) + return string(a) +} + // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -383,10 +395,10 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -537,10 +549,10 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bn254/fr/gkr/gkr.go b/ecc/bn254/fr/gkr/gkr.go index 293c2d7a3..df189b19d 100644 --- a/ecc/bn254/fr/gkr/gkr.go +++ b/ecc/bn254/fr/gkr/gkr.go @@ -490,7 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, challengeNames...) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bn254/fr/mimc/mimc.go b/ecc/bn254/fr/mimc/mimc.go index 1d59a7940..719ed4e8a 100644 --- a/ecc/bn254/fr/mimc/mimc.go +++ b/ecc/bn254/fr/mimc/mimc.go @@ -100,6 +100,14 @@ func (d *digest) BlockSize() int { // // To hash arbitrary data ([]byte not representing canonical field elements) use fr.Hash first func (d *digest) Write(p []byte) (int, error) { + // we usually expect multiple of block size. But sometimes we hash short + // values (FS transcript). Instead of forcing to hash to field, we left-pad the + // input here. + if len(p) > 0 && len(p) < BlockSize { + pp := make([]byte, BlockSize) + copy(pp[len(pp)-len(p):], p) + p = pp + } var start int for start = 0; start < len(p); start += BlockSize { diff --git a/ecc/bn254/fr/mimc/mimc_test.go b/ecc/bn254/fr/mimc/mimc_test.go index 5df2c442a..dbd9740ad 100644 --- a/ecc/bn254/fr/mimc/mimc_test.go +++ b/ecc/bn254/fr/mimc/mimc_test.go @@ -9,7 +9,7 @@ import ( ) func TestMiMCFiatShamir(t *testing.T) { - fs := fiatshamir.NewTranscript(mimc.NewMiMC(), fiatshamir.WithStaticChallenges("c0")) + fs := fiatshamir.NewTranscript(mimc.NewMiMC(), "c0") zero := make([]byte, mimc.BlockSize) err := fs.Bind("c0", zero) assert.NoError(t, err) diff --git a/ecc/bn254/fr/pedersen/pedersen.go b/ecc/bn254/fr/pedersen/pedersen.go index 5680a131d..7c6bf8c2c 100644 --- a/ecc/bn254/fr/pedersen/pedersen.go +++ b/ecc/bn254/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) + t := fiatshamir.NewTranscript(sha256.New(), "r") for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bn254/fr/permutation/permutation.go b/ecc/bn254/fr/permutation/permutation.go index 7a0834523..83abd07c2 100644 --- a/ecc/bn254/fr/permutation/permutation.go +++ b/ecc/bn254/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // commit t1, t2 ct1 := make([]fr.Element, s) @@ -279,7 +279,7 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // derive the challenges epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) diff --git a/ecc/bn254/fr/plookup/table.go b/ecc/bn254/fr/plookup/table.go index ac6628874..fe37c0d1b 100644 --- a/ecc/bn254/fr/plookup/table.go +++ b/ecc/bn254/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check the sizes if len(f) != len(t) { @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { diff --git a/ecc/bn254/fr/plookup/vector.go b/ecc/bn254/fr/plookup/vector.go index ede9b2abb..f6adf0bde 100644 --- a/ecc/bn254/fr/plookup/vector.go +++ b/ecc/bn254/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // create domains var domainSmall *fft.Domain @@ -567,7 +567,7 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // derive the various challenges beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) diff --git a/ecc/bn254/fr/sumcheck/sumcheck.go b/ecc/bn254/fr/sumcheck/sumcheck.go index 65cdd2dcf..473066bb5 100644 --- a/ecc/bn254/fr/sumcheck/sumcheck.go +++ b/ecc/bn254/fr/sumcheck/sumcheck.go @@ -66,7 +66,8 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) + settings.Transcript = transcript } for i := range settings.BaseChallenges { diff --git a/ecc/bn254/fr/test_vector_utils/test_vector_utils_test.go b/ecc/bn254/fr/test_vector_utils/test_vector_utils_test.go index 15c01a7e5..261b27686 100644 --- a/ecc/bn254/fr/test_vector_utils/test_vector_utils_test.go +++ b/ecc/bn254/fr/test_vector_utils/test_vector_utils_test.go @@ -10,8 +10,8 @@ import ( func TestCounterTranscriptInequality(t *testing.T) { const challengeName = "fC.0" - t1 := fiatshamir.NewTranscript(test_vector_utils.NewMessageCounter(1, 1), fiatshamir.WithStaticChallenges(challengeName)) - t2 := fiatshamir.NewTranscript(test_vector_utils.NewMessageCounter(0, 1), fiatshamir.WithStaticChallenges(challengeName)) + t1 := fiatshamir.NewTranscript(test_vector_utils.NewMessageCounter(1, 1), challengeName) + t2 := fiatshamir.NewTranscript(test_vector_utils.NewMessageCounter(0, 1), challengeName) var c1, c2 []byte var err error c1, err = t1.ComputeChallenge(challengeName) diff --git a/ecc/bn254/kzg/kzg.go b/ecc/bn254/kzg/kzg.go index 3ac9177ae..067894ab5 100644 --- a/ecc/bn254/kzg/kzg.go +++ b/ecc/bn254/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) + fs := fiatshamir.NewTranscript(hf, "gamma") if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bw6-633/fr/fri/fri.go b/ecc/bw6-633/fr/fri/fri.go index 6fb16597a..70e927600 100644 --- a/ecc/bw6-633/fr/fri/fri.go +++ b/ecc/bw6-633/fr/fri/fri.go @@ -365,6 +365,18 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } +// paddNaming takes s = 0xA1.... and turns +// it into s' = 0xA1.. || 0..0 of size frSize bytes. +// Using this, when writing the domain separator in FiatShamir, it takes +// the same size as a snark variable (=number of byte in the block of a snark compliant +// hash function like mimc), so it is compliant with snark circuit. +func paddNaming(s string, size int) string { + a := make([]byte, size) + b := []byte(s) + copy(a, b) + return string(a) +} + // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -383,10 +395,10 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -537,10 +549,10 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bw6-633/fr/gkr/gkr.go b/ecc/bw6-633/fr/gkr/gkr.go index 8dbc340b6..888c2c3c5 100644 --- a/ecc/bw6-633/fr/gkr/gkr.go +++ b/ecc/bw6-633/fr/gkr/gkr.go @@ -490,7 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, challengeNames...) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bw6-633/fr/mimc/mimc.go b/ecc/bw6-633/fr/mimc/mimc.go index 6b830e713..9cce55e36 100644 --- a/ecc/bw6-633/fr/mimc/mimc.go +++ b/ecc/bw6-633/fr/mimc/mimc.go @@ -100,6 +100,14 @@ func (d *digest) BlockSize() int { // // To hash arbitrary data ([]byte not representing canonical field elements) use fr.Hash first func (d *digest) Write(p []byte) (int, error) { + // we usually expect multiple of block size. But sometimes we hash short + // values (FS transcript). Instead of forcing to hash to field, we left-pad the + // input here. + if len(p) > 0 && len(p) < BlockSize { + pp := make([]byte, BlockSize) + copy(pp[len(pp)-len(p):], p) + p = pp + } var start int for start = 0; start < len(p); start += BlockSize { diff --git a/ecc/bw6-633/fr/pedersen/pedersen.go b/ecc/bw6-633/fr/pedersen/pedersen.go index 6f64b9aed..0dd39010d 100644 --- a/ecc/bw6-633/fr/pedersen/pedersen.go +++ b/ecc/bw6-633/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) + t := fiatshamir.NewTranscript(sha256.New(), "r") for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bw6-633/fr/permutation/permutation.go b/ecc/bw6-633/fr/permutation/permutation.go index 081279330..7ec0969dd 100644 --- a/ecc/bw6-633/fr/permutation/permutation.go +++ b/ecc/bw6-633/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // commit t1, t2 ct1 := make([]fr.Element, s) @@ -279,7 +279,7 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // derive the challenges epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) diff --git a/ecc/bw6-633/fr/plookup/table.go b/ecc/bw6-633/fr/plookup/table.go index a14ac0587..eb80ef8c6 100644 --- a/ecc/bw6-633/fr/plookup/table.go +++ b/ecc/bw6-633/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check the sizes if len(f) != len(t) { @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { diff --git a/ecc/bw6-633/fr/plookup/vector.go b/ecc/bw6-633/fr/plookup/vector.go index 024dae384..a50eb0001 100644 --- a/ecc/bw6-633/fr/plookup/vector.go +++ b/ecc/bw6-633/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // create domains var domainSmall *fft.Domain @@ -567,7 +567,7 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // derive the various challenges beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) diff --git a/ecc/bw6-633/fr/sumcheck/sumcheck.go b/ecc/bw6-633/fr/sumcheck/sumcheck.go index f49e4457c..db7abdacc 100644 --- a/ecc/bw6-633/fr/sumcheck/sumcheck.go +++ b/ecc/bw6-633/fr/sumcheck/sumcheck.go @@ -66,7 +66,8 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) + settings.Transcript = transcript } for i := range settings.BaseChallenges { diff --git a/ecc/bw6-633/kzg/kzg.go b/ecc/bw6-633/kzg/kzg.go index 4e0e136e0..cf59dff0f 100644 --- a/ecc/bw6-633/kzg/kzg.go +++ b/ecc/bw6-633/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) + fs := fiatshamir.NewTranscript(hf, "gamma") if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bw6-756/fr/fri/fri.go b/ecc/bw6-756/fr/fri/fri.go index ab5e92ccf..29d74e962 100644 --- a/ecc/bw6-756/fr/fri/fri.go +++ b/ecc/bw6-756/fr/fri/fri.go @@ -365,6 +365,18 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } +// paddNaming takes s = 0xA1.... and turns +// it into s' = 0xA1.. || 0..0 of size frSize bytes. +// Using this, when writing the domain separator in FiatShamir, it takes +// the same size as a snark variable (=number of byte in the block of a snark compliant +// hash function like mimc), so it is compliant with snark circuit. +func paddNaming(s string, size int) string { + a := make([]byte, size) + b := []byte(s) + copy(a, b) + return string(a) +} + // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -383,10 +395,10 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -537,10 +549,10 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bw6-756/fr/gkr/gkr.go b/ecc/bw6-756/fr/gkr/gkr.go index 6b7b861b0..5fe30d6d2 100644 --- a/ecc/bw6-756/fr/gkr/gkr.go +++ b/ecc/bw6-756/fr/gkr/gkr.go @@ -490,7 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, challengeNames...) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bw6-756/fr/mimc/mimc.go b/ecc/bw6-756/fr/mimc/mimc.go index e1f47d69d..8078aa6c3 100644 --- a/ecc/bw6-756/fr/mimc/mimc.go +++ b/ecc/bw6-756/fr/mimc/mimc.go @@ -100,6 +100,14 @@ func (d *digest) BlockSize() int { // // To hash arbitrary data ([]byte not representing canonical field elements) use fr.Hash first func (d *digest) Write(p []byte) (int, error) { + // we usually expect multiple of block size. But sometimes we hash short + // values (FS transcript). Instead of forcing to hash to field, we left-pad the + // input here. + if len(p) > 0 && len(p) < BlockSize { + pp := make([]byte, BlockSize) + copy(pp[len(pp)-len(p):], p) + p = pp + } var start int for start = 0; start < len(p); start += BlockSize { diff --git a/ecc/bw6-756/fr/pedersen/pedersen.go b/ecc/bw6-756/fr/pedersen/pedersen.go index 0230595d3..2d757b8ec 100644 --- a/ecc/bw6-756/fr/pedersen/pedersen.go +++ b/ecc/bw6-756/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) + t := fiatshamir.NewTranscript(sha256.New(), "r") for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bw6-756/fr/permutation/permutation.go b/ecc/bw6-756/fr/permutation/permutation.go index 43638f397..416a3742b 100644 --- a/ecc/bw6-756/fr/permutation/permutation.go +++ b/ecc/bw6-756/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // commit t1, t2 ct1 := make([]fr.Element, s) @@ -279,7 +279,7 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // derive the challenges epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) diff --git a/ecc/bw6-756/fr/plookup/table.go b/ecc/bw6-756/fr/plookup/table.go index 336ee7abf..e2f04587d 100644 --- a/ecc/bw6-756/fr/plookup/table.go +++ b/ecc/bw6-756/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check the sizes if len(f) != len(t) { @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { diff --git a/ecc/bw6-756/fr/plookup/vector.go b/ecc/bw6-756/fr/plookup/vector.go index 3b9cc7e27..fd1b5ff61 100644 --- a/ecc/bw6-756/fr/plookup/vector.go +++ b/ecc/bw6-756/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // create domains var domainSmall *fft.Domain @@ -567,7 +567,7 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // derive the various challenges beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) diff --git a/ecc/bw6-756/fr/sumcheck/sumcheck.go b/ecc/bw6-756/fr/sumcheck/sumcheck.go index d9c52e737..0a42bdb25 100644 --- a/ecc/bw6-756/fr/sumcheck/sumcheck.go +++ b/ecc/bw6-756/fr/sumcheck/sumcheck.go @@ -66,7 +66,8 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) + settings.Transcript = transcript } for i := range settings.BaseChallenges { diff --git a/ecc/bw6-756/kzg/kzg.go b/ecc/bw6-756/kzg/kzg.go index 046c456ca..42539e691 100644 --- a/ecc/bw6-756/kzg/kzg.go +++ b/ecc/bw6-756/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) + fs := fiatshamir.NewTranscript(hf, "gamma") if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } diff --git a/ecc/bw6-761/fr/fri/fri.go b/ecc/bw6-761/fr/fri/fri.go index 6aac92393..6c8cb0bce 100644 --- a/ecc/bw6-761/fr/fri/fri.go +++ b/ecc/bw6-761/fr/fri/fri.go @@ -365,6 +365,18 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } +// paddNaming takes s = 0xA1.... and turns +// it into s' = 0xA1.. || 0..0 of size frSize bytes. +// Using this, when writing the domain separator in FiatShamir, it takes +// the same size as a snark variable (=number of byte in the block of a snark compliant +// hash function like mimc), so it is compliant with snark circuit. +func paddNaming(s string, size int) string { + a := make([]byte, size) + b := []byte(s) + copy(a, b) + return string(a) +} + // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -383,10 +395,10 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges // are different at each round. @@ -537,10 +549,10 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = fmt.Sprintf("x%d", i) + xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) } - xis[s.nbSteps] = "s0" - fs := fiatshamir.NewTranscript(s.h, fiatshamir.WithStaticChallenges(xis...)) + xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bw6-761/fr/gkr/gkr.go b/ecc/bw6-761/fr/gkr/gkr.go index b8c8cb8df..c98a8ab05 100644 --- a/ecc/bw6-761/fr/gkr/gkr.go +++ b/ecc/bw6-761/fr/gkr/gkr.go @@ -490,7 +490,7 @@ func setup(c Circuit, assignment WireAssignment, transcriptSettings fiatshamir.S if transcriptSettings.Transcript == nil { challengeNames := ChallengeNames(o.sorted, o.nbVars, transcriptSettings.Prefix) - o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + o.transcript = fiatshamir.NewTranscript(transcriptSettings.Hash, challengeNames...) for i := range transcriptSettings.BaseChallenges { if err = o.transcript.Bind(challengeNames[0], transcriptSettings.BaseChallenges[i]); err != nil { return o, err diff --git a/ecc/bw6-761/fr/mimc/mimc.go b/ecc/bw6-761/fr/mimc/mimc.go index 23e22256f..d93fe32f2 100644 --- a/ecc/bw6-761/fr/mimc/mimc.go +++ b/ecc/bw6-761/fr/mimc/mimc.go @@ -100,6 +100,14 @@ func (d *digest) BlockSize() int { // // To hash arbitrary data ([]byte not representing canonical field elements) use fr.Hash first func (d *digest) Write(p []byte) (int, error) { + // we usually expect multiple of block size. But sometimes we hash short + // values (FS transcript). Instead of forcing to hash to field, we left-pad the + // input here. + if len(p) > 0 && len(p) < BlockSize { + pp := make([]byte, BlockSize) + copy(pp[len(pp)-len(p):], p) + p = pp + } var start int for start = 0; start < len(p); start += BlockSize { diff --git a/ecc/bw6-761/fr/pedersen/pedersen.go b/ecc/bw6-761/fr/pedersen/pedersen.go index 0ffdce39c..c1ca758aa 100644 --- a/ecc/bw6-761/fr/pedersen/pedersen.go +++ b/ecc/bw6-761/fr/pedersen/pedersen.go @@ -225,7 +225,7 @@ func (vk *VerifyingKey) Verify(commitment curve.G1Affine, knowledgeProof curve.G func getChallenge(fiatshamirSeeds [][]byte) (r fr.Element, err error) { // incorporate user-provided seeds into the transcript - t := fiatshamir.NewTranscript(sha256.New(), fiatshamir.WithStaticChallenges("r")) + t := fiatshamir.NewTranscript(sha256.New(), "r") for i := range fiatshamirSeeds { if err = t.Bind("r", fiatshamirSeeds[i]); err != nil { return diff --git a/ecc/bw6-761/fr/permutation/permutation.go b/ecc/bw6-761/fr/permutation/permutation.go index 406008181..d06ec57e0 100644 --- a/ecc/bw6-761/fr/permutation/permutation.go +++ b/ecc/bw6-761/fr/permutation/permutation.go @@ -156,7 +156,7 @@ func Prove(pk kzg.ProvingKey, t1, t2 []fr.Element) (Proof, error) { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // commit t1, t2 ct1 := make([]fr.Element, s) @@ -279,7 +279,7 @@ func Verify(vk kzg.VerifyingKey, proof Proof) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("epsilon", "omega", "eta")) + fs := fiatshamir.NewTranscript(hFunc, "epsilon", "omega", "eta") // derive the challenges epsilon, err := deriveRandomness(fs, "epsilon", &proof.t1, &proof.t2) diff --git a/ecc/bw6-761/fr/plookup/table.go b/ecc/bw6-761/fr/plookup/table.go index 9e4996a0d..cd90fb6ee 100644 --- a/ecc/bw6-761/fr/plookup/table.go +++ b/ecc/bw6-761/fr/plookup/table.go @@ -70,7 +70,7 @@ func ProveLookupTables(pk kzg.ProvingKey, f, t []fr.Vector) (ProofLookupTables, hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check the sizes if len(f) != len(t) { @@ -183,7 +183,7 @@ func VerifyLookupTables(vk kzg.VerifyingKey, proof ProofLookupTables) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("lambda")) + fs := fiatshamir.NewTranscript(hFunc, "lambda") // check that the number of digests is the same if len(proof.fs) != len(proof.ts) { diff --git a/ecc/bw6-761/fr/plookup/vector.go b/ecc/bw6-761/fr/plookup/vector.go index 0718108f5..508ceb539 100644 --- a/ecc/bw6-761/fr/plookup/vector.go +++ b/ecc/bw6-761/fr/plookup/vector.go @@ -363,7 +363,7 @@ func ProveLookupVector(pk kzg.ProvingKey, f, t fr.Vector) (ProofLookupVector, er hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // create domains var domainSmall *fft.Domain @@ -567,7 +567,7 @@ func VerifyLookupVector(vk kzg.VerifyingKey, proof ProofLookupVector) error { hFunc := sha256.New() // transcript to derive the challenge - fs := fiatshamir.NewTranscript(hFunc, fiatshamir.WithStaticChallenges("beta", "gamma", "alpha", "nu")) + fs := fiatshamir.NewTranscript(hFunc, "beta", "gamma", "alpha", "nu") // derive the various challenges beta, err := deriveRandomness(fs, "beta", &proof.t, &proof.f, &proof.h1, &proof.h2) diff --git a/ecc/bw6-761/fr/sumcheck/sumcheck.go b/ecc/bw6-761/fr/sumcheck/sumcheck.go index ea12b4e82..6a8554c20 100644 --- a/ecc/bw6-761/fr/sumcheck/sumcheck.go +++ b/ecc/bw6-761/fr/sumcheck/sumcheck.go @@ -66,7 +66,8 @@ func setupTranscript(claimsNum int, varsNum int, settings *fiatshamir.Settings) challengeNames[i+numChallenges-varsNum] = prefix + strconv.Itoa(i) } if settings.Transcript == nil { - settings.Transcript = fiatshamir.NewTranscript(settings.Hash, fiatshamir.WithStaticChallenges(challengeNames...)) + transcript := fiatshamir.NewTranscript(settings.Hash, challengeNames...) + settings.Transcript = transcript } for i := range settings.BaseChallenges { diff --git a/ecc/bw6-761/kzg/kzg.go b/ecc/bw6-761/kzg/kzg.go index ca384b4af..8984c2ef7 100644 --- a/ecc/bw6-761/kzg/kzg.go +++ b/ecc/bw6-761/kzg/kzg.go @@ -550,7 +550,7 @@ func fold(di []Digest, fai []fr.Element, ci []fr.Element) (Digest, fr.Element, e func deriveGamma(point fr.Element, digests []Digest, claimedValues []fr.Element, hf hash.Hash, dataTranscript ...[]byte) (fr.Element, error) { // derive the challenge gamma, binded to the point and the commitments - fs := fiatshamir.NewTranscript(hf, fiatshamir.WithStaticChallenges("gamma")) + fs := fiatshamir.NewTranscript(hf, "gamma") if err := fs.Bind("gamma", point.Marshal()); err != nil { return fr.Element{}, err } From 9c66892ccf27cb761b680fa6aecd74115019f5d1 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Wed, 20 Dec 2023 00:50:07 +0100 Subject: [PATCH 19/19] feat: do not pad challenge names in FRI --- ecc/bls12-377/fr/fri/fri.go | 20 ++++---------------- ecc/bls12-378/fr/fri/fri.go | 20 ++++---------------- ecc/bls12-381/fr/fri/fri.go | 20 ++++---------------- ecc/bls24-315/fr/fri/fri.go | 20 ++++---------------- ecc/bls24-317/fr/fri/fri.go | 20 ++++---------------- ecc/bn254/fr/fri/fri.go | 20 ++++---------------- ecc/bw6-633/fr/fri/fri.go | 20 ++++---------------- ecc/bw6-756/fr/fri/fri.go | 20 ++++---------------- ecc/bw6-761/fr/fri/fri.go | 20 ++++---------------- internal/generator/fri/template/fri.go.tmpl | 20 ++++---------------- 10 files changed, 40 insertions(+), 160 deletions(-) diff --git a/ecc/bls12-377/fr/fri/fri.go b/ecc/bls12-377/fr/fri/fri.go index 91cc031ee..9a4a8bee1 100644 --- a/ecc/bls12-377/fr/fri/fri.go +++ b/ecc/bls12-377/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls12-378/fr/fri/fri.go b/ecc/bls12-378/fr/fri/fri.go index 145e2defd..fe392d533 100644 --- a/ecc/bls12-378/fr/fri/fri.go +++ b/ecc/bls12-378/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls12-381/fr/fri/fri.go b/ecc/bls12-381/fr/fri/fri.go index 52bf2091e..c206e7c5b 100644 --- a/ecc/bls12-381/fr/fri/fri.go +++ b/ecc/bls12-381/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls24-315/fr/fri/fri.go b/ecc/bls24-315/fr/fri/fri.go index b117c0235..10156d62f 100644 --- a/ecc/bls24-315/fr/fri/fri.go +++ b/ecc/bls24-315/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bls24-317/fr/fri/fri.go b/ecc/bls24-317/fr/fri/fri.go index 135cfb127..cbac4e378 100644 --- a/ecc/bls24-317/fr/fri/fri.go +++ b/ecc/bls24-317/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bn254/fr/fri/fri.go b/ecc/bn254/fr/fri/fri.go index 6559829ec..0bec8575d 100644 --- a/ecc/bn254/fr/fri/fri.go +++ b/ecc/bn254/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bw6-633/fr/fri/fri.go b/ecc/bw6-633/fr/fri/fri.go index 70e927600..b90dbc75f 100644 --- a/ecc/bw6-633/fr/fri/fri.go +++ b/ecc/bw6-633/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bw6-756/fr/fri/fri.go b/ecc/bw6-756/fr/fri/fri.go index 29d74e962..6ff1ee539 100644 --- a/ecc/bw6-756/fr/fri/fri.go +++ b/ecc/bw6-756/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/ecc/bw6-761/fr/fri/fri.go b/ecc/bw6-761/fr/fri/fri.go index 6c8cb0bce..0ebeec095 100644 --- a/ecc/bw6-761/fr/fri/fri.go +++ b/ecc/bw6-761/fr/fri/fri.go @@ -365,18 +365,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -395,9 +383,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges @@ -549,9 +537,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps) diff --git a/internal/generator/fri/template/fri.go.tmpl b/internal/generator/fri/template/fri.go.tmpl index f226f87a4..5870c1cd0 100644 --- a/internal/generator/fri/template/fri.go.tmpl +++ b/internal/generator/fri/template/fri.go.tmpl @@ -348,18 +348,6 @@ func foldPolynomialLagrangeBasis(pSorted []fr.Element, gInv, x fr.Element) []fr. return res } -// paddNaming takes s = 0xA1.... and turns -// it into s' = 0xA1.. || 0..0 of size frSize bytes. -// Using this, when writing the domain separator in FiatShamir, it takes -// the same size as a snark variable (=number of byte in the block of a snark compliant -// hash function like mimc), so it is compliant with snark circuit. -func paddNaming(s string, size int) string { - a := make([]byte, size) - b := []byte(s) - copy(a, b) - return string(a) -} - // buildProofOfProximitySingleRound generates a proof that a function, given as an oracle from // the verifier point of view, is in fact δ-close to a polynomial. // * salt is a variable for multi rounds, it allows to generate different challenges using Fiat Shamir @@ -378,9 +366,9 @@ func (s radixTwoFri) buildProofOfProximitySingleRound(salt fr.Element, p []fr.El // by replacing x by xᵢ. xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) // the salt is binded to the first challenge, to ensure the challenges @@ -532,9 +520,9 @@ func (s radixTwoFri) verifyProofOfProximitySingleRound(salt fr.Element, proof Ro // Fiat Shamir transcript to derive the challenges xis := make([]string, s.nbSteps+1) for i := 0; i < s.nbSteps; i++ { - xis[i] = paddNaming(fmt.Sprintf("x%d", i), fr.Bytes) + xis[i] = fmt.Sprintf("x%d", i) } - xis[s.nbSteps] = paddNaming("s0", fr.Bytes) + xis[s.nbSteps] = "s0" fs := fiatshamir.NewTranscript(s.h, xis...) xi := make([]fr.Element, s.nbSteps)