Browse Source

Upgrade to gnark 0.8 (#18)

* make proof with PIS public input

* upgraded to 0.8 gnark

* reduced pow witness

* fixed bug

* fixed test

* fixed bug

* adding profiling

* changed everything to be pointers

* convert remaining poseidon constants

* added the recursive_very_small

* added more outputs for benchmark
main
Kevin Jue 2 years ago
committed by GitHub
parent
commit
302b5f5bf1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 5441 additions and 2194 deletions
  1. +22
    -9
      benchmark.go
  2. +30
    -14
      field/goldilocks.go
  3. +26
    -23
      field/quadratic_extension.go
  4. +24
    -24
      field/quadratic_extension_test.go
  5. +8
    -12
      go.mod
  6. +19
    -17
      go.sum
  7. +1471
    -1114
      poseidon/constants.go
  8. +5
    -5
      poseidon/hash.go
  9. +43
    -37
      poseidon/poseidon.go
  10. +3
    -3
      poseidon/poseidon_test.go
  11. +2
    -2
      poseidon/public_inputs_hash_test.go
  12. +3
    -3
      utils/utils.go
  13. +62
    -19
      verifier/common/types.go
  14. +174
    -0
      verifier/data/recursive_very_small/common_circuit_data.json
  15. +2373
    -0
      verifier/data/recursive_very_small/proof_with_public_inputs.json
  16. +140
    -0
      verifier/data/recursive_very_small/verifier_only_circuit_data.json
  17. +16
    -15
      verifier/internal/fri/fri.go
  18. +152
    -95
      verifier/internal/fri/fri_test.go
  19. +1
    -1
      verifier/internal/fri/fri_utils.go
  20. +2
    -2
      verifier/internal/gates/base_sum_gate.go
  21. +2
    -2
      verifier/internal/gates/evaluate_gates.go
  22. +664
    -664
      verifier/internal/gates/gate_test.go
  23. +1
    -1
      verifier/internal/gates/poseidon_gate.go
  24. +1
    -1
      verifier/internal/gates/random_access_gate.go
  25. +3
    -3
      verifier/internal/plonk/challenger.go
  26. +19
    -19
      verifier/internal/plonk/challenger_test.go
  27. +3
    -3
      verifier/internal/plonk/plonk.go
  28. +1
    -1
      verifier/internal/plonk/plonk_test.go
  29. +2
    -2
      verifier/utils/deserialize.go
  30. +78
    -12
      verifier/verifier.go
  31. +91
    -91
      verifier/verifier_test.go

+ 22
- 9
benchmark.go

@ -12,12 +12,14 @@ import (
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/constraint"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/frontend/cs/r1cs"
"github.com/consensys/gnark/profile"
)
type BenchmarkPlonky2VerifierCircuit struct {
proofWithPis common.ProofWithPublicInputs
ProofWithPis common.ProofWithPublicInputs `gnark:",public"`
verifierChip *verifier.VerifierChip
plonky2CircuitName string
@ -25,39 +27,42 @@ type BenchmarkPlonky2VerifierCircuit struct {
func (circuit *BenchmarkPlonky2VerifierCircuit) Define(api frontend.API) error {
circuitDirname := "./verifier/data/" + circuit.plonky2CircuitName + "/"
proofWithPis := utils.DeserializeProofWithPublicInputs(circuitDirname + "proof_with_public_inputs.json")
commonCircuitData := utils.DeserializeCommonCircuitData(circuitDirname + "common_circuit_data.json")
verifierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(circuitDirname + "verifier_only_circuit_data.json")
circuit.verifierChip = verifier.NewVerifierChip(api, commonCircuitData)
circuit.verifierChip.Verify(proofWithPis, verifierOnlyCircuitData, commonCircuitData)
circuit.verifierChip.Verify(circuit.ProofWithPis, verifierOnlyCircuitData, commonCircuitData)
return nil
}
func compileCircuit(plonky2Circuit string) frontend.CompiledConstraintSystem {
func compileCircuit(plonky2Circuit string) constraint.ConstraintSystem {
circuit := BenchmarkPlonky2VerifierCircuit{
plonky2CircuitName: plonky2Circuit,
}
proofWithPis := utils.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json")
circuit.proofWithPis = proofWithPis
circuit.ProofWithPis = proofWithPis
p := profile.Start()
r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit)
if err != nil {
fmt.Println("error in building circuit", err)
os.Exit(1)
}
p.Stop()
fmt.Println(p.NbConstraints())
fmt.Println(p.Top())
return r1cs
}
func createProof(r1cs frontend.CompiledConstraintSystem, plonky2Circuit string) groth16.Proof {
func createProof(r1cs constraint.ConstraintSystem, plonky2Circuit string) groth16.Proof {
proofWithPis := utils.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json")
// Witness
assignment := &BenchmarkPlonky2VerifierCircuit{
proofWithPis: proofWithPis,
ProofWithPis: proofWithPis,
}
fmt.Println("Generating witness", time.Now())
@ -97,6 +102,14 @@ func main() {
}
r1cs := compileCircuit(*plonky2Circuit)
proof := createProof(r1cs, *plonky2Circuit)
fmt.Println(proof.CurveID(), time.Now())
println("r1cs.GetNbCoefficients(): ", r1cs.GetNbCoefficients())
println("r1cs.GetNbConstraints(): ", r1cs.GetNbConstraints())
println("r1cs.GetNbSecretVariables(): ", r1cs.GetNbSecretVariables())
println("r1cs.GetNbPublicVariables(): ", r1cs.GetNbPublicVariables())
println("r1cs.GetNbInternalVariables(): ", r1cs.GetNbInternalVariables())
/*
proof := createProof(r1cs, *plonky2Circuit)
fmt.Println(proof.CurveID(), time.Now())
*/
}

+ 30
- 14
field/goldilocks.go

@ -8,29 +8,32 @@ import (
)
type EmulatedField = emulated.Goldilocks
type F = emulated.Element[EmulatedField]
type F = *emulated.Element[EmulatedField]
type FieldAPI = *emulated.Field[emulated.Goldilocks]
var TEST_CURVE = ecc.BN254
func NewFieldElement(x uint64) F {
return emulated.NewElement[EmulatedField](x)
func NewFieldAPI(api frontend.API) FieldAPI {
fieldAPI, err := emulated.NewField[EmulatedField](api)
if err != nil {
panic(err)
}
return fieldAPI
}
func NewFieldElementFromString(x string) F {
return emulated.NewElement[EmulatedField](x)
func NewFieldConst(x uint64) F {
val := emulated.ValueOf[EmulatedField](x)
return &val
}
func NewFieldAPI(api frontend.API) frontend.API {
field, err := emulated.NewField[EmulatedField](api)
if err != nil {
panic(err)
}
return field
func NewFieldConstFromString(x string) F {
val := emulated.ValueOf[EmulatedField](x)
return &val
}
var ONE_F = NewFieldElement(1)
var ZERO_F = NewFieldElement(0)
var NEG_ONE_F = NewFieldElement(EmulatedField{}.Modulus().Uint64() - 1)
var ONE_F = NewFieldConst(1)
var ZERO_F = NewFieldConst(0)
var NEG_ONE_F = NewFieldConst(EmulatedField{}.Modulus().Uint64() - 1)
var GOLDILOCKS_MULTIPLICATIVE_GROUP_GENERATOR = goldilocks.NewElement(7)
var GOLDILOCKS_TWO_ADICITY = uint64(32)
@ -65,3 +68,16 @@ func TwoAdicSubgroup(nLog uint64) []goldilocks.Element {
return res
}
func IsZero(api frontend.API, fieldAPI *emulated.Field[emulated.Goldilocks], x F) frontend.Variable {
reduced := fieldAPI.Reduce(x)
limbs := reduced.Limbs
isZero := api.IsZero(limbs[0])
for i := 1; i < len(limbs); i++ {
isZero = api.Mul(isZero, api.IsZero(limbs[i]))
}
return isZero
}

+ 26
- 23
field/quadratic_extension.go

@ -1,7 +1,6 @@
package field
import (
"fmt"
"math/bits"
"github.com/consensys/gnark-crypto/field/goldilocks"
@ -14,7 +13,8 @@ type QuadraticExtension = [2]F
type QEAlgebra = [D]QuadraticExtension
type QuadraticExtensionAPI struct {
fieldAPI frontend.API
api frontend.API
fieldAPI FieldAPI
W F
DTH_ROOT F
@ -25,7 +25,7 @@ type QuadraticExtensionAPI struct {
ZERO_QE_ALGEBRA QEAlgebra
}
func NewQuadraticExtensionAPI(fieldAPI frontend.API, degreeBits uint64) *QuadraticExtensionAPI {
func NewQuadraticExtensionAPI(api frontend.API, fieldAPI FieldAPI, degreeBits uint64) *QuadraticExtensionAPI {
// TODO: Should degreeBits be verified that it fits within the field and that degree is within uint64?
var ZERO_QE = QuadraticExtension{ZERO_F, ZERO_F}
@ -37,10 +37,11 @@ func NewQuadraticExtensionAPI(fieldAPI frontend.API, degreeBits uint64) *Quadrat
}
return &QuadraticExtensionAPI{
api: api,
fieldAPI: fieldAPI,
W: NewFieldElement(7),
DTH_ROOT: NewFieldElement(18446744069414584320),
W: NewFieldConst(7),
DTH_ROOT: NewFieldConst(18446744069414584320),
ONE_QE: QuadraticExtension{ONE_F, ZERO_F},
ZERO_QE: ZERO_QE,
@ -54,20 +55,20 @@ func (c *QuadraticExtensionAPI) SquareExtension(a QuadraticExtension) QuadraticE
}
func (c *QuadraticExtensionAPI) MulExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension {
c_0 := c.fieldAPI.Add(c.fieldAPI.Mul(a[0], b[0]).(F), c.fieldAPI.Mul(c.W, a[1], b[1])).(F)
c_1 := c.fieldAPI.Add(c.fieldAPI.Mul(a[0], b[1]).(F), c.fieldAPI.Mul(a[1], b[0])).(F)
c_0 := c.fieldAPI.Add(c.fieldAPI.Mul(a[0], b[0]), c.fieldAPI.Mul(c.fieldAPI.Mul(c.W, a[1]), b[1]))
c_1 := c.fieldAPI.Add(c.fieldAPI.Mul(a[0], b[1]), c.fieldAPI.Mul(a[1], b[0]))
return QuadraticExtension{c_0, c_1}
}
func (c *QuadraticExtensionAPI) AddExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension {
c_0 := c.fieldAPI.Add(a[0], b[0]).(F)
c_1 := c.fieldAPI.Add(a[1], b[1]).(F)
c_0 := c.fieldAPI.Add(a[0], b[0])
c_1 := c.fieldAPI.Add(a[1], b[1])
return QuadraticExtension{c_0, c_1}
}
func (c *QuadraticExtensionAPI) SubExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension {
c_0 := c.fieldAPI.Sub(a[0], b[0]).(F)
c_1 := c.fieldAPI.Sub(a[1], b[1]).(F)
c_0 := c.fieldAPI.Sub(a[0], b[0])
c_1 := c.fieldAPI.Sub(a[1], b[1])
return QuadraticExtension{c_0, c_1}
}
@ -76,26 +77,26 @@ func (c *QuadraticExtensionAPI) DivExtension(a QuadraticExtension, b QuadraticEx
}
func (c *QuadraticExtensionAPI) IsZero(a QuadraticExtension) frontend.Variable {
return c.fieldAPI.Mul(c.fieldAPI.IsZero(a[0]), c.fieldAPI.IsZero(a[1]))
return c.api.Mul(IsZero(c.api, c.fieldAPI, a[0]), IsZero(c.api, c.fieldAPI, a[1]))
}
// TODO: Instead of calculating the inverse within the circuit, can witness the
// inverse and assert that a_inverse * a = 1. Should reduce # of constraints.
func (c *QuadraticExtensionAPI) InverseExtension(a QuadraticExtension) QuadraticExtension {
// First assert that a doesn't have 0 value coefficients
a0_is_zero := c.fieldAPI.IsZero(a[0])
a1_is_zero := c.fieldAPI.IsZero(a[1])
a0_is_zero := IsZero(c.api, c.fieldAPI, a[0])
a1_is_zero := IsZero(c.api, c.fieldAPI, a[1])
// assert that a0_is_zero OR a1_is_zero == false
c.fieldAPI.AssertIsEqual(c.fieldAPI.Mul(a0_is_zero, a1_is_zero).(F), ZERO_F)
c.api.AssertIsEqual(c.api.Mul(a0_is_zero, a1_is_zero), frontend.Variable(0))
a_pow_r_minus_1 := QuadraticExtension{a[0], c.fieldAPI.Mul(a[1], c.DTH_ROOT).(F)}
a_pow_r_minus_1 := QuadraticExtension{a[0], c.fieldAPI.Mul(a[1], c.DTH_ROOT)}
a_pow_r := c.MulExtension(a_pow_r_minus_1, a)
return c.ScalarMulExtension(a_pow_r_minus_1, c.fieldAPI.Inverse(a_pow_r[0]).(F))
return c.ScalarMulExtension(a_pow_r_minus_1, c.fieldAPI.Inverse(a_pow_r[0]))
}
func (c *QuadraticExtensionAPI) ScalarMulExtension(a QuadraticExtension, scalar F) QuadraticExtension {
return QuadraticExtension{c.fieldAPI.Mul(a[0], scalar).(F), c.fieldAPI.Mul(a[1], scalar).(F)}
return QuadraticExtension{c.fieldAPI.Mul(a[0], scalar), c.fieldAPI.Mul(a[1], scalar)}
}
func (c *QuadraticExtensionAPI) FieldToQE(a F) QuadraticExtension {
@ -150,7 +151,7 @@ func (c *QuadraticExtensionAPI) Select(b frontend.Variable, qe0, qe1 QuadraticEx
var retQE QuadraticExtension
for i := 0; i < 2; i++ {
retQE[i] = c.fieldAPI.Select(b, qe0[i], qe1[i]).(F)
retQE[i] = c.fieldAPI.Select(b, qe0[i], qe1[i])
}
return retQE
@ -160,7 +161,7 @@ func (c *QuadraticExtensionAPI) Lookup2(b0 frontend.Variable, b1 frontend.Variab
var retQE QuadraticExtension
for i := 0; i < 2; i++ {
retQE[i] = c.fieldAPI.Lookup2(b0, b1, qe0[i], qe1[i], qe2[i], qe3[i]).(F)
retQE[i] = c.fieldAPI.Lookup2(b0, b1, qe0[i], qe1[i], qe2[i], qe3[i])
}
return retQE
@ -186,6 +187,7 @@ func (c *QuadraticExtensionAPI) InnerProductExtension(constant F, startingAcc Qu
return acc
}
/*
func (c *QuadraticExtensionAPI) Println(a QuadraticExtension) {
fmt.Print("Degree 0 coefficient")
c.fieldAPI.Println(a[0])
@ -193,6 +195,7 @@ func (c *QuadraticExtensionAPI) Println(a QuadraticExtension) {
fmt.Print("Degree 1 coefficient")
c.fieldAPI.Println(a[1])
}
*/
func (c *QuadraticExtensionAPI) MulExtensionAlgebra(a, b QEAlgebra) QEAlgebra {
var inner [D][][2]QuadraticExtension
@ -210,7 +213,7 @@ func (c *QuadraticExtensionAPI) MulExtensionAlgebra(a, b QEAlgebra) QEAlgebra {
var product QEAlgebra
for i := 0; i < D; i++ {
acc := c.InnerProductExtension(NewFieldElement(7), c.ZERO_QE, inner_w[i])
acc := c.InnerProductExtension(c.W, c.ZERO_QE, inner_w[i])
product[i] = c.InnerProductExtension(ONE_F, acc, inner[i])
}
@ -268,10 +271,10 @@ func (c *QuadraticExtensionAPI) PartialInterpolateExtAlgebra(
for i := 0; i < n; i++ {
val := values[i]
x := domain[i]
xField := NewFieldElement(x.Uint64())
xField := NewFieldConst(x.Uint64())
xQE := QuadraticExtension{xField, ZERO_F}
xQEAlgebra := QEAlgebra{xQE, c.ZERO_QE}
weight := QuadraticExtension{NewFieldElement(barycentricWeights[i].Uint64()), ZERO_F}
weight := QuadraticExtension{NewFieldConst(barycentricWeights[i].Uint64()), ZERO_F}
term := c.SubExtensionAlgebra(point, xQEAlgebra)
weightedVal := c.ScalarMulExtensionAlgebra(weight, val)
newEval = c.MulExtensionAlgebra(newEval, term)

+ 24
- 24
field/quadratic_extension_test.go

@ -13,32 +13,32 @@ import (
type TestQuadraticExtensionMulCircuit struct {
qeAPI *QuadraticExtensionAPI
operand1 QuadraticExtension
operand2 QuadraticExtension
expectedResult QuadraticExtension
Operand1 QuadraticExtension
Operand2 QuadraticExtension
ExpectedResult QuadraticExtension
}
func (c *TestQuadraticExtensionMulCircuit) Define(api frontend.API) error {
fieldAPI := NewFieldAPI(api)
degreeBits := 3
c.qeAPI = NewQuadraticExtensionAPI(fieldAPI, uint64(degreeBits))
c.qeAPI = NewQuadraticExtensionAPI(api, fieldAPI, uint64(degreeBits))
actualRes := c.qeAPI.MulExtension(c.operand1, c.operand2)
actualRes := c.qeAPI.MulExtension(c.Operand1, c.Operand2)
fieldAPI.AssertIsEqual(actualRes[0], c.expectedResult[0])
fieldAPI.AssertIsEqual(actualRes[1], c.expectedResult[1])
fieldAPI.AssertIsEqual(actualRes[0], c.ExpectedResult[0])
fieldAPI.AssertIsEqual(actualRes[1], c.ExpectedResult[1])
return nil
}
func TestQuadraticExtensionMul(t *testing.T) {
assert := test.NewAssert(t)
operand1 := QuadraticExtension{NewFieldElement(4994088319481652598), NewFieldElement(16489566008211790727)}
operand2 := QuadraticExtension{NewFieldElement(3797605683985595697), NewFieldElement(13424401189265534004)}
expectedResult := QuadraticExtension{NewFieldElement(15052319864161058789), NewFieldElement(16841416332519902625)}
operand1 := QuadraticExtension{NewFieldConst(4994088319481652598), NewFieldConst(16489566008211790727)}
operand2 := QuadraticExtension{NewFieldConst(3797605683985595697), NewFieldConst(13424401189265534004)}
expectedResult := QuadraticExtension{NewFieldConst(15052319864161058789), NewFieldConst(16841416332519902625)}
circuit := TestQuadraticExtensionMulCircuit{operand1: operand1, operand2: operand2, expectedResult: expectedResult}
witness := TestQuadraticExtensionMulCircuit{operand1: operand1, operand2: operand2, expectedResult: expectedResult}
circuit := TestQuadraticExtensionMulCircuit{Operand1: operand1, Operand2: operand2, ExpectedResult: expectedResult}
witness := TestQuadraticExtensionMulCircuit{Operand1: operand1, Operand2: operand2, ExpectedResult: expectedResult}
err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField())
assert.NoError(err)
}
@ -47,20 +47,20 @@ func TestQuadraticExtensionMul(t *testing.T) {
type TestQuadraticExtensionDivCircuit struct {
qeAPI *QuadraticExtensionAPI
operand1 QuadraticExtension
operand2 QuadraticExtension
expectedResult QuadraticExtension
Operand1 QuadraticExtension
Operand2 QuadraticExtension
ExpectedResult QuadraticExtension
}
func (c *TestQuadraticExtensionDivCircuit) Define(api frontend.API) error {
fieldAPI := NewFieldAPI(api)
degreeBits := 3
c.qeAPI = NewQuadraticExtensionAPI(fieldAPI, uint64(degreeBits))
c.qeAPI = NewQuadraticExtensionAPI(api, fieldAPI, uint64(degreeBits))
actualRes := c.qeAPI.DivExtension(c.operand1, c.operand2)
actualRes := c.qeAPI.DivExtension(c.Operand1, c.Operand2)
fieldAPI.AssertIsEqual(actualRes[0], c.expectedResult[0])
fieldAPI.AssertIsEqual(actualRes[1], c.expectedResult[1])
fieldAPI.AssertIsEqual(actualRes[0], c.ExpectedResult[0])
fieldAPI.AssertIsEqual(actualRes[1], c.ExpectedResult[1])
return nil
}
@ -68,12 +68,12 @@ func (c *TestQuadraticExtensionDivCircuit) Define(api frontend.API) error {
func TestQuadraticExtensionDiv(t *testing.T) {
assert := test.NewAssert(t)
operand1 := QuadraticExtension{NewFieldElement(4994088319481652598), NewFieldElement(16489566008211790727)}
operand2 := QuadraticExtension{NewFieldElement(7166004739148609569), NewFieldElement(14655965871663555016)}
expectedResult := QuadraticExtension{NewFieldElement(15052319864161058789), NewFieldElement(16841416332519902625)}
operand1 := QuadraticExtension{NewFieldConst(4994088319481652598), NewFieldConst(16489566008211790727)}
operand2 := QuadraticExtension{NewFieldConst(7166004739148609569), NewFieldConst(14655965871663555016)}
expectedResult := QuadraticExtension{NewFieldConst(15052319864161058789), NewFieldConst(16841416332519902625)}
circuit := TestQuadraticExtensionDivCircuit{operand1: operand1, operand2: operand2, expectedResult: expectedResult}
witness := TestQuadraticExtensionDivCircuit{operand1: operand1, operand2: operand2, expectedResult: expectedResult}
circuit := TestQuadraticExtensionDivCircuit{Operand1: operand1, Operand2: operand2, ExpectedResult: expectedResult}
witness := TestQuadraticExtensionDivCircuit{Operand1: operand1, Operand2: operand2, ExpectedResult: expectedResult}
err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField())
assert.NoError(err)
}

+ 8
- 12
go.mod

@ -3,31 +3,27 @@ module github.com/succinctlabs/gnark-plonky2-verifier
go 1.19
require (
github.com/consensys/gnark v0.7.2-0.20220921094618-a121a3074ee8
github.com/consensys/gnark-crypto v0.8.1-0.20220819163559-143c75519b0e
github.com/consensys/gnark v0.8.0
github.com/consensys/gnark-crypto v0.9.1
)
require (
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fxamacker/cbor/v2 v2.2.0 // indirect
github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1 // indirect
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/rs/zerolog v1.28.0 // indirect
github.com/stretchr/testify v1.8.0 // indirect
github.com/rs/zerolog v1.29.0 // indirect
github.com/stretchr/testify v1.8.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/exp v0.0.0-20220713135740-79cabaa25d75 // indirect
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect
golang.org/x/sys v0.5.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
)
// For now, use a forked version of gnark so that the emaulated fields are
// mod'ed when printed. See here: https://github.com/kevjue/gnark/commit/0b216679a380b4b8d29f10dd96f34e8a5702463e
replace github.com/consensys/gnark v0.7.2-0.20220921094618-a121a3074ee8 => github.com/kevjue/gnark v0.7.2-0.20221123002814-bcc0d7d32d60

+ 19
- 17
go.sum

@ -2,23 +2,23 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
github.com/consensys/gnark-crypto v0.8.1-0.20220819163559-143c75519b0e h1:FyL5vcbvCIoD20M4Fvy+TXRbXKjT16gq7Uq0QDkyytM=
github.com/consensys/gnark-crypto v0.8.1-0.20220819163559-143c75519b0e/go.mod h1:ZTnSzNlt98CpwYIJyk6q/KVcshYWr3fOXXFrrY8a0QQ=
github.com/consensys/gnark v0.8.0 h1:0bQ2MyDG4oNjMQpNyL8HjrrUSSL3yYJg0Elzo6LzmcU=
github.com/consensys/gnark v0.8.0/go.mod h1:aKmA7dIiLbTm0OV37xTq0z+Bpe4xER8EhRLi6necrm8=
github.com/consensys/gnark-crypto v0.9.1 h1:mru55qKdWl3E035hAoh1jj9d7hVnYY5pfb6tmovSmII=
github.com/consensys/gnark-crypto v0.9.1/go.mod h1:a2DQL4+5ywF6safEeZFEPGRiiGbjzGFRUN2sg06VuU4=
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fxamacker/cbor/v2 v2.2.0 h1:6eXqdDDe588rSYAi1HfZKbx6YYQO4mxQ9eC6xYpU/JQ=
github.com/fxamacker/cbor/v2 v2.2.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1 h1:8pyqKJvrJqUYaKS851Ule26pwWvey6IDMiczaBLDKLQ=
github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1/go.mod h1:gSuNB+gJaOiQKLEZ+q+PK9Mq3SOzhRcw2GsGS/FhYDk=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/kevjue/gnark v0.7.2-0.20221123002814-bcc0d7d32d60 h1:Z7hWN0/Spz1H18rBm9qpqzy0dX1/uWhGSMxMMEaruVY=
github.com/kevjue/gnark v0.7.2-0.20221123002814-bcc0d7d32d60/go.mod h1:iN7/IRE6Eu2QKnTJEsoS48suBV0O5XrM+Nzo1ipp6Zw=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
@ -37,22 +37,24 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w=
github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
golang.org/x/exp v0.0.0-20220713135740-79cabaa25d75 h1:x03zeu7B2B11ySp+daztnwM5oBJ/8wGUSqrwcw9L0RA=
golang.org/x/exp v0.0.0-20220713135740-79cabaa25d75/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w=
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 1471
- 1114
poseidon/constants.go
File diff suppressed because it is too large
View File


+ 5
- 5
poseidon/hash.go

@ -8,11 +8,11 @@ import (
type Hash = [4]field.F
type HashAPI struct {
fieldAPI frontend.API
fieldAPI field.FieldAPI
}
func NewHashAPI(
fieldAPI frontend.API,
fieldAPI field.FieldAPI,
) *HashAPI {
return &HashAPI{
fieldAPI: fieldAPI,
@ -22,7 +22,7 @@ func NewHashAPI(
func (h *HashAPI) SelectHash(bit frontend.Variable, leftHash, rightHash Hash) Hash {
var returnHash Hash
for i := 0; i < 4; i++ {
returnHash[i] = h.fieldAPI.Select(bit, leftHash[i], rightHash[i]).(field.F)
returnHash[i] = h.fieldAPI.Select(bit, leftHash[i], rightHash[i])
}
return returnHash
@ -32,7 +32,7 @@ func (h *HashAPI) Lookup2Hash(b0 frontend.Variable, b1 frontend.Variable, h0, h1
var returnHash Hash
for i := 0; i < 4; i++ {
returnHash[i] = h.fieldAPI.Lookup2(b0, b1, h0[i], h1[i], h2[i], h3[i]).(field.F)
returnHash[i] = h.fieldAPI.Lookup2(b0, b1, h0[i], h1[i], h2[i], h3[i])
}
return returnHash
@ -47,7 +47,7 @@ func (h *HashAPI) AssertIsEqualHash(h1, h2 Hash) {
func Uint64ArrayToHashArray(input [][]uint64) []Hash {
var output []Hash
for i := 0; i < len(input); i++ {
output = append(output, [4]field.F{field.NewFieldElement(input[i][0]), field.NewFieldElement(input[i][1]), field.NewFieldElement(input[i][2]), field.NewFieldElement(input[i][3])})
output = append(output, [4]field.F{field.NewFieldConst(input[i][0]), field.NewFieldConst(input[i][1]), field.NewFieldConst(input[i][2]), field.NewFieldConst(input[i][3])})
}
return output
}

+ 43
- 37
poseidon/poseidon.go

@ -18,11 +18,11 @@ type PoseidonStateExtension = [SPONGE_WIDTH]field.QuadraticExtension
type PoseidonChip struct {
api frontend.API `gnark:"-"`
fieldAPI frontend.API `gnark:"-"`
fieldAPI field.FieldAPI `gnark:"-"`
qeAPI *field.QuadraticExtensionAPI `gnark:"-"`
}
func NewPoseidonChip(api frontend.API, fieldAPI frontend.API, qeAPI *field.QuadraticExtensionAPI) *PoseidonChip {
func NewPoseidonChip(api frontend.API, fieldAPI field.FieldAPI, qeAPI *field.QuadraticExtensionAPI) *PoseidonChip {
return &PoseidonChip{api: api, fieldAPI: fieldAPI, qeAPI: qeAPI}
}
@ -86,7 +86,7 @@ func (c *PoseidonChip) PartialRounds(state PoseidonState, roundCounter *int) Pos
for i := 0; i < N_PARTIAL_ROUNDS; i++ {
state[0] = c.SBoxMonomial(state[0])
state[0] = c.fieldAPI.Add(state[0], FAST_PARTIAL_ROUND_CONSTANTS[i]).(field.F)
state[0] = c.fieldAPI.Add(state[0], FAST_PARTIAL_ROUND_CONSTANTS[i])
state = c.MdsPartialLayerFast(state, i)
}
@ -98,8 +98,8 @@ func (c *PoseidonChip) PartialRounds(state PoseidonState, roundCounter *int) Pos
func (c *PoseidonChip) ConstantLayer(state PoseidonState, roundCounter *int) PoseidonState {
for i := 0; i < 12; i++ {
if i < SPONGE_WIDTH {
roundConstant := field.NewFieldElement(ALL_ROUND_CONSTANTS[i+SPONGE_WIDTH*(*roundCounter)])
state[i] = c.fieldAPI.Add(state[i], roundConstant).(field.F)
roundConstant := ALL_ROUND_CONSTANTS[i+SPONGE_WIDTH*(*roundCounter)]
state[i] = c.fieldAPI.Add(state[i], roundConstant)
}
}
return state
@ -108,7 +108,7 @@ func (c *PoseidonChip) ConstantLayer(state PoseidonState, roundCounter *int) Pos
func (c *PoseidonChip) ConstantLayerExtension(state PoseidonStateExtension, roundCounter *int) PoseidonStateExtension {
for i := 0; i < 12; i++ {
if i < SPONGE_WIDTH {
roundConstant := c.qeAPI.FieldToQE(field.NewFieldElement(ALL_ROUND_CONSTANTS[i+SPONGE_WIDTH*(*roundCounter)]))
roundConstant := c.qeAPI.FieldToQE(ALL_ROUND_CONSTANTS[i+SPONGE_WIDTH*(*roundCounter)])
state[i] = c.qeAPI.AddExtension(state[i], roundConstant)
}
}
@ -119,7 +119,7 @@ func (c *PoseidonChip) SBoxMonomial(x field.F) field.F {
x2 := c.fieldAPI.Mul(x, x)
x4 := c.fieldAPI.Mul(x2, x2)
x3 := c.fieldAPI.Mul(x, x2)
return c.fieldAPI.Mul(x3, x4).(field.F)
return c.fieldAPI.Mul(x3, x4)
}
func (c *PoseidonChip) SBoxMonomialExtension(x field.QuadraticExtension) field.QuadraticExtension {
@ -148,31 +148,31 @@ func (c *PoseidonChip) SBoxLayerExtension(state PoseidonStateExtension) Poseidon
}
func (c *PoseidonChip) MdsRowShf(r int, v [SPONGE_WIDTH]frontend.Variable) frontend.Variable {
res := frontend.Variable(0)
res := ZERO_VAR
for i := 0; i < 12; i++ {
if i < SPONGE_WIDTH {
res1 := c.api.Mul(v[(i+r)%SPONGE_WIDTH], frontend.Variable(MDS_MATRIX_CIRC[i]))
res1 := c.api.Mul(v[(i+r)%SPONGE_WIDTH], MDS_MATRIX_CIRC_VARS[i])
res = c.api.Add(res, res1)
}
}
res = c.api.Add(res, c.api.Mul(v[r], MDS_MATRIX_DIAG[r]))
res = c.api.Add(res, c.api.Mul(v[r], MDS_MATRIX_DIAG_VARS[r]))
return res
}
func (c *PoseidonChip) MdsRowShfExtension(r int, v [SPONGE_WIDTH]field.QuadraticExtension) field.QuadraticExtension {
res := c.qeAPI.FieldToQE(field.NewFieldElement(0))
res := c.qeAPI.FieldToQE(field.ZERO_F)
for i := 0; i < 12; i++ {
if i < SPONGE_WIDTH {
matrixVal := c.qeAPI.FieldToQE(field.NewFieldElement(MDS_MATRIX_CIRC[i]))
matrixVal := c.qeAPI.FieldToQE(MDS_MATRIX_CIRC[i])
res1 := c.qeAPI.MulExtension(v[(i+r)%SPONGE_WIDTH], matrixVal)
res = c.qeAPI.AddExtension(res, res1)
}
}
matrixVal := c.qeAPI.FieldToQE(field.NewFieldElement(MDS_MATRIX_DIAG[r]))
matrixVal := c.qeAPI.FieldToQE(MDS_MATRIX_DIAG[r])
res = c.qeAPI.AddExtension(res, c.qeAPI.MulExtension(v[r], matrixVal))
return res
}
@ -180,19 +180,21 @@ func (c *PoseidonChip) MdsRowShfExtension(r int, v [SPONGE_WIDTH]field.Quadratic
func (c *PoseidonChip) MdsLayer(state_ PoseidonState) PoseidonState {
var result PoseidonState
for i := 0; i < SPONGE_WIDTH; i++ {
result[i] = field.NewFieldElement(0)
result[i] = field.ZERO_F
}
var state [SPONGE_WIDTH]frontend.Variable
for i := 0; i < SPONGE_WIDTH; i++ {
state[i] = c.api.FromBinary(c.fieldAPI.ToBinary(state_[i])...)
reducedState := c.fieldAPI.Reduce(state_[i])
//state[i] = c.api.FromBinary(c.fieldAPI.ToBits(reducedState)...)
state[i] = reducedState.Limbs[0]
}
for r := 0; r < 12; r++ {
if r < SPONGE_WIDTH {
sum := c.MdsRowShf(r, state)
bits := c.api.ToBinary(sum)
result[r] = c.fieldAPI.FromBinary(bits).(field.F)
result[r] = c.fieldAPI.FromBits(bits...)
}
}
@ -215,7 +217,7 @@ func (c *PoseidonChip) MdsLayerExtension(state_ PoseidonStateExtension) Poseidon
func (c *PoseidonChip) PartialFirstConstantLayer(state PoseidonState) PoseidonState {
for i := 0; i < 12; i++ {
if i < SPONGE_WIDTH {
state[i] = c.fieldAPI.Add(state[i], field.NewFieldElement(FAST_PARTIAL_FIRST_ROUND_CONSTANT[i])).(field.F)
state[i] = c.fieldAPI.Add(state[i], FAST_PARTIAL_FIRST_ROUND_CONSTANT[i])
}
}
return state
@ -224,7 +226,7 @@ func (c *PoseidonChip) PartialFirstConstantLayer(state PoseidonState) PoseidonSt
func (c *PoseidonChip) PartialFirstConstantLayerExtension(state PoseidonStateExtension) PoseidonStateExtension {
for i := 0; i < 12; i++ {
if i < SPONGE_WIDTH {
state[i] = c.qeAPI.AddExtension(state[i], c.qeAPI.FieldToQE(field.NewFieldElement(FAST_PARTIAL_FIRST_ROUND_CONSTANT[i])))
state[i] = c.qeAPI.AddExtension(state[i], c.qeAPI.FieldToQE(FAST_PARTIAL_FIRST_ROUND_CONSTANT[i]))
}
}
return state
@ -233,7 +235,7 @@ func (c *PoseidonChip) PartialFirstConstantLayerExtension(state PoseidonStateExt
func (c *PoseidonChip) MdsPartialLayerInit(state PoseidonState) PoseidonState {
var result PoseidonState
for i := 0; i < 12; i++ {
result[i] = field.NewFieldElement(0)
result[i] = field.ZERO_F
}
result[0] = state[0]
@ -242,8 +244,8 @@ func (c *PoseidonChip) MdsPartialLayerInit(state PoseidonState) PoseidonState {
if r < SPONGE_WIDTH {
for d := 1; d < 12; d++ {
if d < SPONGE_WIDTH {
t := field.NewFieldElement(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1])
result[d] = c.fieldAPI.Add(result[d], c.fieldAPI.Mul(state[r], t)).(field.F)
t := FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1]
result[d] = c.fieldAPI.Add(result[d], c.fieldAPI.Mul(state[r], t))
}
}
}
@ -255,7 +257,7 @@ func (c *PoseidonChip) MdsPartialLayerInit(state PoseidonState) PoseidonState {
func (c *PoseidonChip) MdsPartialLayerInitExtension(state PoseidonStateExtension) PoseidonStateExtension {
var result PoseidonStateExtension
for i := 0; i < 12; i++ {
result[i] = c.qeAPI.FieldToQE(field.NewFieldElement(0))
result[i] = c.qeAPI.FieldToQE(field.ZERO_F)
}
result[0] = state[0]
@ -264,7 +266,7 @@ func (c *PoseidonChip) MdsPartialLayerInitExtension(state PoseidonStateExtension
if r < SPONGE_WIDTH {
for d := 1; d < 12; d++ {
if d < SPONGE_WIDTH {
t := c.qeAPI.FieldToQE(field.NewFieldElement(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1]))
t := c.qeAPI.FieldToQE(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1])
result[d] = c.qeAPI.AddExtension(result[d], c.qeAPI.MulExtension(state[r], t))
}
}
@ -275,31 +277,35 @@ func (c *PoseidonChip) MdsPartialLayerInitExtension(state PoseidonStateExtension
}
func (c *PoseidonChip) MdsPartialLayerFast(state PoseidonState, r int) PoseidonState {
dSum := frontend.Variable(0)
dSum := ZERO_VAR
for i := 1; i < 12; i++ {
if i < SPONGE_WIDTH {
t := frontend.Variable(FAST_PARTIAL_ROUND_W_HATS[r][i-1])
si := c.api.FromBinary(c.fieldAPI.ToBinary(state[i])...)
t := FAST_PARTIAL_ROUND_W_HATS_VARS[r][i-1]
reducedState := c.fieldAPI.Reduce(state[i])
//si := c.api.FromBinary(c.fieldAPI.ToBits(reducedState)...)
si := reducedState.Limbs[0]
dSum = c.api.Add(dSum, c.api.Mul(si, t))
}
}
s0 := c.api.FromBinary(c.fieldAPI.ToBinary(state[0])...)
mds0to0 := frontend.Variable(MDS_MATRIX_CIRC[0] + MDS_MATRIX_DIAG[0])
dSum = c.api.Add(dSum, c.api.Mul(s0, mds0to0))
d := c.fieldAPI.FromBinary(c.api.ToBinary(dSum))
reducedState := c.fieldAPI.Reduce(state[0])
//s0 := c.api.FromBinary(c.fieldAPI.ToBits(reducedState)...)
s0 := reducedState.Limbs[0]
dSum = c.api.Add(dSum, c.api.Mul(s0, MDS0TO0_VAR))
d := c.fieldAPI.FromBits(c.api.ToBinary(dSum)...)
//d := c.fieldAPI.NewElement(dSum)
var result PoseidonState
for i := 0; i < SPONGE_WIDTH; i++ {
result[i] = field.NewFieldElement(0)
result[i] = field.ZERO_F
}
result[0] = d.(field.F)
result[0] = d
for i := 1; i < 12; i++ {
if i < SPONGE_WIDTH {
t := field.NewFieldElement(FAST_PARTIAL_ROUND_VS[r][i-1])
result[i] = c.fieldAPI.Add(state[i], c.fieldAPI.Mul(state[0], t)).(field.F)
t := FAST_PARTIAL_ROUND_VS[r][i-1]
result[i] = c.fieldAPI.Add(state[i], c.fieldAPI.Mul(state[0], t))
}
}
@ -308,11 +314,11 @@ func (c *PoseidonChip) MdsPartialLayerFast(state PoseidonState, r int) PoseidonS
func (c *PoseidonChip) MdsPartialLayerFastExtension(state PoseidonStateExtension, r int) PoseidonStateExtension {
s0 := state[0]
mds0to0 := c.qeAPI.FieldToQE(field.NewFieldElement(MDS_MATRIX_CIRC[0] + MDS_MATRIX_DIAG[0]))
mds0to0 := c.qeAPI.FieldToQE(MDS0TO0)
d := c.qeAPI.MulExtension(s0, mds0to0)
for i := 1; i < 12; i++ {
if i < SPONGE_WIDTH {
t := c.qeAPI.FieldToQE(field.NewFieldElement(FAST_PARTIAL_ROUND_W_HATS[r][i-1]))
t := c.qeAPI.FieldToQE(FAST_PARTIAL_ROUND_W_HATS[r][i-1])
d = c.qeAPI.AddExtension(d, c.qeAPI.MulExtension(state[i], t))
}
}
@ -321,7 +327,7 @@ func (c *PoseidonChip) MdsPartialLayerFastExtension(state PoseidonStateExtension
result[0] = d
for i := 1; i < 12; i++ {
if i < SPONGE_WIDTH {
t := c.qeAPI.FieldToQE(field.NewFieldElement(FAST_PARTIAL_ROUND_VS[r][i-1]))
t := c.qeAPI.FieldToQE(FAST_PARTIAL_ROUND_VS[r][i-1])
result[i] = c.qeAPI.AddExtension(c.qeAPI.MulExtension(state[0], t), state[i])
}
}

+ 3
- 3
poseidon/poseidon_test.go

@ -18,11 +18,11 @@ type TestPoseidonCircuit struct {
func (circuit *TestPoseidonCircuit) Define(api frontend.API) error {
goldilocksApi := field.NewFieldAPI(api)
qeAPI := field.NewQuadraticExtensionAPI(goldilocksApi, 3)
qeAPI := field.NewQuadraticExtensionAPI(api, goldilocksApi, 3)
var input PoseidonState
for i := 0; i < 12; i++ {
input[i] = goldilocksApi.FromBinary(api.ToBinary(circuit.In[i], 64)).(field.F)
input[i] = goldilocksApi.FromBits(api.ToBinary(circuit.In[i], 64)...)
}
poseidonChip := NewPoseidonChip(api, goldilocksApi, qeAPI)
@ -31,7 +31,7 @@ func (circuit *TestPoseidonCircuit) Define(api frontend.API) error {
for i := 0; i < 12; i++ {
goldilocksApi.AssertIsEqual(
output[i],
goldilocksApi.FromBinary(api.ToBinary(circuit.Out[i])).(field.F),
goldilocksApi.FromBits(api.ToBinary(circuit.Out[i])...),
)
}

+ 2
- 2
poseidon/public_inputs_hash_test.go

@ -23,7 +23,7 @@ func (circuit *TestPublicInputsHashCircuit) Define(api frontend.API) error {
// BN254 -> Binary(64) -> F
var input [3]field.F
for i := 0; i < 3; i++ {
input[i] = fieldAPI.FromBinary(api.ToBinary(circuit.In[i], 64)).(field.F)
input[i] = fieldAPI.FromBits(api.ToBinary(circuit.In[i], 64)...)
}
poseidonChip := &PoseidonChip{api: api, fieldAPI: fieldAPI}
@ -33,7 +33,7 @@ func (circuit *TestPublicInputsHashCircuit) Define(api frontend.API) error {
for i := 0; i < 4; i++ {
fieldAPI.AssertIsEqual(
output[i],
fieldAPI.FromBinary(api.ToBinary(circuit.Out[i])).(field.F),
fieldAPI.FromBits(api.ToBinary(circuit.Out[i])...),
)
}

+ 3
- 3
utils/utils.go

@ -28,19 +28,19 @@ func StrArrayToFrontendVariableArray(input []string) []frontend.Variable {
func Uint64ArrayToFArray(input []uint64) []field.F {
var output []field.F
for i := 0; i < len(input); i++ {
output = append(output, field.NewFieldElement(input[i]))
output = append(output, field.NewFieldConst(input[i]))
}
return output
}
func Uint64ArrayToQuadraticExtension(input []uint64) field.QuadraticExtension {
return [2]field.F{field.NewFieldElement(input[0]), field.NewFieldElement(input[1])}
return [2]field.F{field.NewFieldConst(input[0]), field.NewFieldConst(input[1])}
}
func Uint64ArrayToQuadraticExtensionArray(input [][]uint64) []field.QuadraticExtension {
var output []field.QuadraticExtension
for i := 0; i < len(input); i++ {
output = append(output, [2]field.F{field.NewFieldElement(input[i][0]), field.NewFieldElement(input[i][1])})
output = append(output, [2]field.F{field.NewFieldConst(input[i][0]), field.NewFieldConst(input[i][1])})
}
return output
}

+ 62
- 19
verifier/common/types.go

@ -7,40 +7,68 @@ import (
type MerkleCap = []poseidon.Hash
func NewMerkleCap(capHeight uint64) MerkleCap {
return make([]poseidon.Hash, 1<<capHeight)
}
type MerkleProof struct {
Siblings []poseidon.Hash
Siblings []poseidon.Hash // Length = CircuitConfig.FriConfig.DegreeBits + CircuitConfig.FriConfig.RateBits - CircuitConfig.FriConfig.CapHeight
}
func NewMerkleProof(merkleProofLen uint64) MerkleProof {
return MerkleProof{Siblings: make([]poseidon.Hash, merkleProofLen)}
}
type EvalProof struct {
Elements []field.F
Elements []field.F // Length = [CommonCircuitData.Constants + CommonCircuitData.NumRoutedWires, CommonCircuitData.NumWires + CommonCircuitData.FriParams.Hiding ? 4 : 0, CommonCircuitData.NumChallenges * (1 + CommonCircuitData.NumPartialProducts) + salt, CommonCircuitData.NumChallenges * CommonCircuitData.QuotientDegreeFactor + salt]
MerkleProof MerkleProof
}
func NewEvalProof(elements []field.F, merkleProof MerkleProof) EvalProof {
return EvalProof{Elements: elements, MerkleProof: merkleProof}
}
type PolynomialCoeffs struct {
Coeffs []field.QuadraticExtension
}
func NewPolynomialCoeffs(numCoeffs uint64) PolynomialCoeffs {
return PolynomialCoeffs{Coeffs: make([]field.QuadraticExtension, numCoeffs)}
}
type OpeningSet struct {
Constants []field.QuadraticExtension
PlonkSigmas []field.QuadraticExtension
Wires []field.QuadraticExtension
PlonkZs []field.QuadraticExtension
PlonkZsNext []field.QuadraticExtension
PartialProducts []field.QuadraticExtension
QuotientPolys []field.QuadraticExtension
Constants []field.QuadraticExtension // Length = CommonCircuitData.Constants
PlonkSigmas []field.QuadraticExtension // Length = CommonCircuitData.NumRoutedWires
Wires []field.QuadraticExtension // Length = CommonCircuitData.NumWires
PlonkZs []field.QuadraticExtension // Length = CommonCircuitData.NumChallenges
PlonkZsNext []field.QuadraticExtension // Length = CommonCircuitData.NumChallenges
PartialProducts []field.QuadraticExtension // Length = CommonCircuitData.NumChallenges * CommonCircuitData.NumPartialProducts
QuotientPolys []field.QuadraticExtension // Length = CommonCircuitData.NumChallenges * CommonCircuitData.QuotientDegreeFactor
}
func NewOpeningSet(numConstants uint64, numRoutedWires uint64, numWires uint64, numChallenges uint64, numPartialProducts uint64, quotientDegreeFactor uint64) OpeningSet {
return OpeningSet{
Constants: make([]field.QuadraticExtension, numConstants),
PlonkSigmas: make([]field.QuadraticExtension, numRoutedWires),
Wires: make([]field.QuadraticExtension, numWires),
PlonkZs: make([]field.QuadraticExtension, numChallenges),
PlonkZsNext: make([]field.QuadraticExtension, numChallenges),
PartialProducts: make([]field.QuadraticExtension, numChallenges*numPartialProducts),
QuotientPolys: make([]field.QuadraticExtension, numChallenges*quotientDegreeFactor),
}
}
type Proof struct {
WiresCap MerkleCap
PlonkZsPartialProductsCap MerkleCap
QuotientPolysCap MerkleCap
WiresCap MerkleCap // length = 2^CircuitConfig.FriConfig.CapHeight
PlonkZsPartialProductsCap MerkleCap // length = 2^CircuitConfig.FriConfig.CapHeight
QuotientPolysCap MerkleCap // length = 2^CircuitConfig.FriConfig.CapHeight
Openings OpeningSet
OpeningProof FriProof
}
type ProofWithPublicInputs struct {
Proof Proof
PublicInputs []field.F
PublicInputs []field.F // Length = CommonCircuitData.NumPublicInputs
}
type ProofChallenges struct {
@ -52,22 +80,37 @@ type ProofChallenges struct {
}
type FriInitialTreeProof struct {
EvalsProofs []EvalProof
EvalsProofs []EvalProof // Length = 4
}
func NewFriInitialTreeProof(evalsProofs []EvalProof) FriInitialTreeProof {
return FriInitialTreeProof{EvalsProofs: evalsProofs}
}
type FriQueryStep struct {
Evals []field.QuadraticExtension
MerkleProof MerkleProof
Evals []field.QuadraticExtension // Length = [2^arityBit for arityBit in CommonCircuitData.FriParams.ReductionArityBits]
MerkleProof MerkleProof // Length = [regularSize - arityBit for arityBit in CommonCircuitData.FriParams.ReductionArityBits]
}
func NewFriQueryStep(arityBit uint64, merkleProofLen uint64) FriQueryStep {
return FriQueryStep{
Evals: make([]field.QuadraticExtension, 1<<arityBit),
MerkleProof: NewMerkleProof(merkleProofLen),
}
}
type FriQueryRound struct {
InitialTreesProof FriInitialTreeProof
Steps []FriQueryStep
Steps []FriQueryStep // Length = Len(CommonCircuitData.FriParams.ReductionArityBits)
}
func NewFriQueryRound(steps []FriQueryStep, initialTreesProof FriInitialTreeProof) FriQueryRound {
return FriQueryRound{InitialTreesProof: initialTreesProof, Steps: steps}
}
type FriProof struct {
CommitPhaseMerkleCaps []MerkleCap
QueryRoundProofs []FriQueryRound
CommitPhaseMerkleCaps []MerkleCap // Length = Len(CommonCircuitData.FriParams.ReductionArityBits)
QueryRoundProofs []FriQueryRound // Length = CommonCircuitData.FriConfig.FriParams.NumQueryRounds
FinalPoly PolynomialCoeffs
PowWitness field.F
}

+ 174
- 0
verifier/data/recursive_very_small/common_circuit_data.json

@ -0,0 +1,174 @@
{
"config": {
"num_wires": 136,
"num_routed_wires": 80,
"num_constants": 2,
"use_base_arithmetic_gate": true,
"security_bits": 100,
"num_challenges": 2,
"zero_knowledge": false,
"max_quotient_degree_factor": 8,
"fri_config": {
"rate_bits": 3,
"cap_height": 4,
"proof_of_work_bits": 16,
"reduction_strategy": {
"ConstantArityBits": [
4,
5
]
},
"num_query_rounds": 1
}
},
"fri_params": {
"config": {
"rate_bits": 3,
"cap_height": 4,
"proof_of_work_bits": 16,
"reduction_strategy": {
"ConstantArityBits": [
4,
5
]
},
"num_query_rounds": 1
},
"hiding": false,
"degree_bits": 9,
"reduction_arity_bits": [
4
]
},
"gates": [
"NoopGate",
"ConstantGate { num_consts: 2 }",
"PublicInputGate",
"BaseSumGate { num_limbs: 63 } + Base: 2",
"ReducingExtensionGate { num_coeffs: 33 }",
"ReducingGate { num_coeffs: 44 }",
"ArithmeticExtensionGate { num_ops: 10 }",
"ArithmeticGate { num_ops: 20 }",
"MulExtensionGate { num_ops: 13 }",
"RandomAccessGate { bits: 4, num_copies: 4, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>",
"CosetInterpolationGate { subgroup_bits: 4, degree: 6, barycentric_weights: [17293822565076172801, 18374686475376656385, 18446744069413535745, 281474976645120, 17592186044416, 256, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 1048576, 18446462594437939201, 18446726477228539905, 18446744069414584065, 68719476720, 4294967296], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>",
"PoseidonGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>"
],
"selectors_info": {
"selector_indices": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1,
2,
2
],
"groups": [
{
"start": 0,
"end": 6
},
{
"start": 6,
"end": 10
},
{
"start": 10,
"end": 12
}
]
},
"quotient_degree_factor": 8,
"num_gate_constraints": 123,
"num_constants": 5,
"num_public_inputs": 0,
"k_is": [
1,
7,
49,
343,
2401,
16807,
117649,
823543,
5764801,
40353607,
282475249,
1977326743,
13841287201,
96889010407,
678223072849,
4747561509943,
33232930569601,
232630513987207,
1628413597910449,
11398895185373143,
79792266297612001,
558545864083284007,
3909821048582988049,
8922003270666332022,
7113790686420571191,
12903046666114829695,
16534350385145470581,
5059988279530788141,
16973173887300932666,
8131752794619022736,
1582037354089406189,
11074261478625843323,
3732854072722565977,
7683234439643377518,
16889152938674473984,
7543606154233811962,
15911754940807515092,
701820169165099718,
4912741184155698026,
15942444219675301861,
916645121239607101,
6416515848677249707,
8022122801911579307,
814627405137302186,
5702391835961115302,
3023254712898638472,
2716038920875884983,
565528376716610560,
3958698637016273920,
9264146389699333119,
9508792519651578870,
11221315429317299127,
4762231727562756605,
14888878023524711914,
11988425817600061793,
10132004445542095267,
15583798910550913906,
16852872026783475737,
7289639770996824233,
14133990258148600989,
6704211459967285318,
10035992080941828584,
14911712358349047125,
12148266161370408270,
11250886851934520606,
4969231685883306958,
16337877731768564385,
3684679705892444769,
7346013871832529062,
14528608963998534792,
9466542400916821939,
10925564598174000610,
2691975909559666986,
397087297503084581,
2779611082521592067,
1010533508236560148,
7073734557655921036,
12622653764762278610,
14571600075677612986,
9767480182670369297
],
"num_partial_products": 9
}

+ 2373
- 0
verifier/data/recursive_very_small/proof_with_public_inputs.json
File diff suppressed because it is too large
View File


+ 140
- 0
verifier/data/recursive_very_small/verifier_only_circuit_data.json

@ -0,0 +1,140 @@
{
"constants_sigmas_cap": [
{
"elements": [
18341772251201060973,
8863499337164177585,
3680903997187631396,
12765086892713286422
]
},
{
"elements": [
10011842595440383490,
16803433616479820503,
5116105297375993895,
1284372878762986134
]
},
{
"elements": [
9771429197922126084,
11795709479898502019,
9760789605311014828,
14587465303757273799
]
},
{
"elements": [
14268034713225276697,
18296479136879705605,
10850612887933280806,
9639487702530117083
]
},
{
"elements": [
9754005887238773284,
5374369974939340944,
4959182047845142644,
1120709750910555570
]
},
{
"elements": [
7250035629074136036,
15739653461985901088,
14987756440121950753,
9158371711408827053
]
},
{
"elements": [
13216298745969283339,
16888689116176782846,
12982122889871085039,
5211135798140140360
]
},
{
"elements": [
1504326644701451030,
8409612476357826852,
7563553194601621378,
11995034742915891064
]
},
{
"elements": [
5488329807694506217,
18091194776727670160,
17052473172701400255,
16236156822718879559
]
},
{
"elements": [
17715347985838125739,
3615805299049017601,
8585175301607696636,
1968868157246799025
]
},
{
"elements": [
13447598860253889564,
6631647170626609560,
2112142850806037543,
14266806193129176172
]
},
{
"elements": [
2730627694247012781,
17236598033654074636,
4452557557605684638,
468430371172463963
]
},
{
"elements": [
6798850231787296859,
16600632819568012939,
11299208732485603538,
15684010143706607232
]
},
{
"elements": [
3144604974895131192,
4061404887662630886,
5007128585099235364,
16758955485500576037
]
},
{
"elements": [
4096461731986790461,
12546978492628150144,
18147834661139732319,
4737766556076016924
]
},
{
"elements": [
14221961188679542125,
17198447421299265716,
4429176582749668482,
3028817214334434508
]
}
],
"circuit_digest": {
"elements": [
10592544746408303090,
6263847280826784938,
13362953309332334276,
1690911406899164489
]
}
}

+ 16
- 15
verifier/internal/fri/fri.go

@ -15,7 +15,7 @@ import (
type FriChip struct {
api frontend.API `gnark:"-"`
fieldAPI frontend.API `gnark:"-"`
fieldAPI field.FieldAPI `gnark:"-"`
qeAPI *field.QuadraticExtensionAPI `gnark:"-"`
hashAPI *poseidon.HashAPI `gnark:"-"`
@ -26,7 +26,7 @@ type FriChip struct {
func NewFriChip(
api frontend.API,
fieldAPI frontend.API,
fieldAPI field.FieldAPI,
qeAPI *field.QuadraticExtensionAPI,
hashAPI *poseidon.HashAPI,
poseidonChip *poseidon.PoseidonChip,
@ -47,7 +47,8 @@ func (f *FriChip) assertLeadingZeros(powWitness field.F, friConfig common.FriCon
// Note that this is assuming that the Goldilocks field is being used. Specfically that the
// field is 64 bits long
maxPowWitness := uint64(math.Pow(2, float64(64-friConfig.ProofOfWorkBits))) - 1
f.fieldAPI.AssertIsLessOrEqual(powWitness, field.NewFieldElement(maxPowWitness))
reducedPOWWitness := f.fieldAPI.Reduce(powWitness)
f.fieldAPI.AssertIsLessOrEqual(reducedPOWWitness, field.NewFieldConst(maxPowWitness))
}
func (f *FriChip) fromOpeningsAndAlpha(openings *FriOpenings, alpha field.QuadraticExtension) []field.QuadraticExtension {
@ -200,16 +201,16 @@ func (f *FriChip) expFromBitsConstBase(
basePow := goldilocks.NewElement(0)
basePow.Exp(base, big.NewInt(pow))
basePowElement := field.NewFieldElement(basePow.Uint64() - 1)
basePowElement := field.NewFieldConst(basePow.Uint64() - 1)
product = f.fieldAPI.Add(
f.fieldAPI.Mul(
basePowElement,
product,
bit,
),
f.fieldAPI.Mul(
basePowElement,
product),
f.fieldAPI.NewElement(bit)),
product,
).(field.F)
)
}
return product
@ -222,7 +223,7 @@ func (f *FriChip) calculateSubgroupX(
// Compute x from its index
// `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain.
// TODO - Make these as global values
g := field.NewFieldElement(field.GOLDILOCKS_MULTIPLICATIVE_GROUP_GENERATOR.Uint64())
g := field.NewFieldConst(field.GOLDILOCKS_MULTIPLICATIVE_GROUP_GENERATOR.Uint64())
base := field.GoldilocksPrimitiveRootOfUnity(nLog)
// Create a reverse list of xIndexBits
@ -233,7 +234,7 @@ func (f *FriChip) calculateSubgroupX(
product := f.expFromBitsConstBase(base, xIndexBitsRev)
return f.fieldAPI.Mul(g, product).(field.F)
return f.fieldAPI.Mul(g, product)
}
func (f *FriChip) friCombineInitial(
@ -376,13 +377,13 @@ func (f *FriChip) computeEvaluation(
revXIndexWithinCosetBits[len(xIndexWithinCosetBits)-1-i] = xIndexWithinCosetBits[i]
}
start := f.expFromBitsConstBase(gInv, revXIndexWithinCosetBits)
cosetStart := f.fieldAPI.Mul(start, x).(field.F)
cosetStart := f.fieldAPI.Mul(start, x)
xPoints := make([]field.QuadraticExtension, len(evals))
yPoints := permutedEvals
// TODO: Make g_F a constant
g_F := f.qeAPI.FieldToQE(field.NewFieldElement(g.Uint64()))
g_F := f.qeAPI.FieldToQE(field.NewFieldConst(g.Uint64()))
xPoints[0] = f.qeAPI.FieldToQE(cosetStart)
for i := 1; i < len(evals); i++ {
xPoints[i] = f.qeAPI.MulExtension(xPoints[i-1], g_F)
@ -421,7 +422,7 @@ func (f *FriChip) verifyQueryRound(
roundProof *common.FriQueryRound,
) {
f.assertNoncanonicalIndicesOK()
xIndexBits := f.fieldAPI.ToBinary(xIndex, int(nLog))
xIndexBits := f.fieldAPI.ToBits(xIndex)
capIndexBits := xIndexBits[len(xIndexBits)-int(f.friParams.Config.CapHeight):]
f.verifyInitialProof(xIndexBits, &roundProof.InitialTreesProof, initialMerkleCaps, capIndexBits)
@ -506,7 +507,7 @@ func (f *FriChip) verifyQueryRound(
// Update the point x to x^arity.
for j := uint64(0); j < arityBits; j++ {
subgroupX = f.fieldAPI.Mul(subgroupX, subgroupX).(field.F)
subgroupX = f.fieldAPI.Mul(subgroupX, subgroupX)
}
xIndexBits = cosetIndexBits

+ 152
- 95
verifier/internal/fri/fri_test.go

@ -17,11 +17,11 @@ type TestFriCircuit struct {
commonCircuitDataFilename string `gnark:"-"`
verifierOnlyCircuitDataFilename string `gnark:"-"`
plonkZeta field.QuadraticExtension
friAlpha field.QuadraticExtension
friBetas []field.QuadraticExtension
friPOWResponse field.F
friQueryIndices []field.F
PlonkZeta field.QuadraticExtension
FriAlpha field.QuadraticExtension
FriBetas []field.QuadraticExtension
FriPOWResponse field.F
FriQueryIndices []field.F
}
func (circuit *TestFriCircuit) Define(api frontend.API) error {
@ -30,16 +30,16 @@ func (circuit *TestFriCircuit) Define(api frontend.API) error {
verifierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(circuit.verifierOnlyCircuitDataFilename)
fieldAPI := field.NewFieldAPI(api)
qeAPI := field.NewQuadraticExtensionAPI(fieldAPI, commonCircuitData.DegreeBits)
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI, commonCircuitData.DegreeBits)
hashAPI := poseidon.NewHashAPI(fieldAPI)
poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI, qeAPI)
friChip := fri.NewFriChip(api, fieldAPI, qeAPI, hashAPI, poseidonChip, &commonCircuitData.FriParams)
friChallenges := common.FriChallenges{
FriAlpha: circuit.friAlpha,
FriBetas: circuit.friBetas,
FriPowResponse: circuit.friPOWResponse,
FriQueryIndices: circuit.friQueryIndices,
FriAlpha: circuit.FriAlpha,
FriBetas: circuit.FriBetas,
FriPowResponse: circuit.FriPOWResponse,
FriQueryIndices: circuit.FriQueryIndices,
}
initialMerkleCaps := []common.MerkleCap{
@ -50,7 +50,7 @@ func (circuit *TestFriCircuit) Define(api frontend.API) error {
}
friChip.VerifyFriProof(
fri.GetFriInstance(&commonCircuitData, qeAPI, circuit.plonkZeta, commonCircuitData.DegreeBits),
fri.GetFriInstance(&commonCircuitData, qeAPI, circuit.PlonkZeta, commonCircuitData.DegreeBits),
fri.ToFriOpenings(proofWithPis.Proof.Openings),
&friChallenges,
initialMerkleCaps,
@ -68,45 +68,45 @@ func TestFibonacciFriProof(t *testing.T) {
proofWithPIsFilename: "./data/fibonacci/proof_with_public_inputs.json",
commonCircuitDataFilename: "./data/fibonacci/common_circuit_data.json",
verifierOnlyCircuitDataFilename: "./data/fibonacci/verifier_only_circuit_data.json",
plonkZeta: field.QuadraticExtension{
field.NewFieldElementFromString("14887793628029982930"),
field.NewFieldElementFromString("1136137158284059037"),
PlonkZeta: field.QuadraticExtension{
field.NewFieldConstFromString("14887793628029982930"),
field.NewFieldConstFromString("1136137158284059037"),
},
friAlpha: field.QuadraticExtension{
field.NewFieldElementFromString("14641715242626918707"),
field.NewFieldElementFromString("10574243340537902930"),
FriAlpha: field.QuadraticExtension{
field.NewFieldConstFromString("14641715242626918707"),
field.NewFieldConstFromString("10574243340537902930"),
},
friBetas: []field.QuadraticExtension{},
friPOWResponse: field.NewFieldElement(82451580476419),
friQueryIndices: []field.F{
field.NewFieldElement(6790812084677375942),
field.NewFieldElement(12394212020331474798),
field.NewFieldElement(16457600747000998582),
field.NewFieldElement(1543271328932331916),
field.NewFieldElement(12115726870906958644),
field.NewFieldElement(6775897107605342797),
field.NewFieldElement(15989401564746021030),
field.NewFieldElement(10691676456016926845),
field.NewFieldElement(1632499470630032007),
field.NewFieldElement(1317292355445098328),
field.NewFieldElement(18391440812534384252),
field.NewFieldElement(17321705613231354333),
field.NewFieldElement(6176487551308859603),
field.NewFieldElement(7119835651572002873),
field.NewFieldElement(3903019169623116693),
field.NewFieldElement(4886491111111487546),
field.NewFieldElement(4087641893164620518),
field.NewFieldElement(13801643080324181364),
field.NewFieldElement(16993775312274189321),
field.NewFieldElement(9268202926222765679),
field.NewFieldElement(10683001302406181735),
field.NewFieldElement(13359465725531647963),
field.NewFieldElement(4523327590105620849),
field.NewFieldElement(4883588003760409588),
field.NewFieldElement(187699146998097671),
field.NewFieldElement(14489263557623716717),
field.NewFieldElement(11748359318238148146),
field.NewFieldElement(13636347200053048758),
FriBetas: []field.QuadraticExtension{},
FriPOWResponse: field.NewFieldConst(82451580476419),
FriQueryIndices: []field.F{
field.NewFieldConst(6790812084677375942),
field.NewFieldConst(12394212020331474798),
field.NewFieldConst(16457600747000998582),
field.NewFieldConst(1543271328932331916),
field.NewFieldConst(12115726870906958644),
field.NewFieldConst(6775897107605342797),
field.NewFieldConst(15989401564746021030),
field.NewFieldConst(10691676456016926845),
field.NewFieldConst(1632499470630032007),
field.NewFieldConst(1317292355445098328),
field.NewFieldConst(18391440812534384252),
field.NewFieldConst(17321705613231354333),
field.NewFieldConst(6176487551308859603),
field.NewFieldConst(7119835651572002873),
field.NewFieldConst(3903019169623116693),
field.NewFieldConst(4886491111111487546),
field.NewFieldConst(4087641893164620518),
field.NewFieldConst(13801643080324181364),
field.NewFieldConst(16993775312274189321),
field.NewFieldConst(9268202926222765679),
field.NewFieldConst(10683001302406181735),
field.NewFieldConst(13359465725531647963),
field.NewFieldConst(4523327590105620849),
field.NewFieldConst(4883588003760409588),
field.NewFieldConst(187699146998097671),
field.NewFieldConst(14489263557623716717),
field.NewFieldConst(11748359318238148146),
field.NewFieldConst(13636347200053048758),
},
}
witness := TestFriCircuit{}
@ -122,64 +122,121 @@ func TestDummyFriProof(t *testing.T) {
testCase := func() {
circuit := TestFriCircuit{
proofWithPIsFilename: "./data/dummy_2^14_gates/proof_with_public_inputs.json",
commonCircuitDataFilename: "./data/dummy_2^14_gates/common_circuit_data.json",
verifierOnlyCircuitDataFilename: "./data/dummy_2^14_gates/verifier_only_circuit_data.json",
plonkZeta: field.QuadraticExtension{
field.NewFieldElementFromString("17377750363769967882"),
field.NewFieldElementFromString("11921191651424768462"),
proofWithPIsFilename: "../../data/dummy_2^14_gates/proof_with_public_inputs.json",
commonCircuitDataFilename: "../../data/dummy_2^14_gates/common_circuit_data.json",
verifierOnlyCircuitDataFilename: "../../data/dummy_2^14_gates/verifier_only_circuit_data.json",
PlonkZeta: field.QuadraticExtension{
field.NewFieldConstFromString("17377750363769967882"),
field.NewFieldConstFromString("11921191651424768462"),
},
friAlpha: field.QuadraticExtension{
field.NewFieldElementFromString("16721004555774385479"),
field.NewFieldElementFromString("10688151135543754663"),
FriAlpha: field.QuadraticExtension{
field.NewFieldConstFromString("16721004555774385479"),
field.NewFieldConstFromString("10688151135543754663"),
},
friBetas: []field.QuadraticExtension{
FriBetas: []field.QuadraticExtension{
{
field.NewFieldElementFromString("3312441922957827805"),
field.NewFieldElementFromString("15128092514958289671"),
field.NewFieldConstFromString("3312441922957827805"),
field.NewFieldConstFromString("15128092514958289671"),
},
{
field.NewFieldElementFromString("13630530769060141802"),
field.NewFieldElementFromString("14559883974933163008"),
field.NewFieldConstFromString("13630530769060141802"),
field.NewFieldConstFromString("14559883974933163008"),
},
{
field.NewFieldElementFromString("16146508250083930687"),
field.NewFieldElementFromString("5176346568444408396"),
field.NewFieldConstFromString("16146508250083930687"),
field.NewFieldConstFromString("5176346568444408396"),
},
},
friPOWResponse: field.NewFieldElement(4389),
friQueryIndices: []field.F{
field.NewFieldElementFromString("16334967868590615051"),
field.NewFieldElementFromString("2911473540496037915"),
field.NewFieldElementFromString("14887216056886344225"),
field.NewFieldElementFromString("7808811227805914295"),
field.NewFieldElementFromString("2018594961417375749"),
field.NewFieldElementFromString("3733368398777208435"),
field.NewFieldElementFromString("2623035669037055104"),
field.NewFieldElementFromString("299243030573481514"),
field.NewFieldElementFromString("7189789717962704433"),
field.NewFieldElementFromString("14566344026886816268"),
field.NewFieldElementFromString("12555390069003437453"),
field.NewFieldElementFromString("17225508403199418233"),
field.NewFieldElementFromString("5088797913879903292"),
field.NewFieldElementFromString("9715691392773433023"),
field.NewFieldElementFromString("7565836764713256165"),
field.NewFieldElementFromString("1500143546029322929"),
field.NewFieldElementFromString("1245802417104422080"),
field.NewFieldElementFromString("6831959786661245110"),
field.NewFieldElementFromString("17271054758535453780"),
field.NewFieldElementFromString("6225460404576395409"),
field.NewFieldElementFromString("15932661092896277351"),
field.NewFieldElementFromString("12452534049198240575"),
field.NewFieldElementFromString("4225199666055520177"),
field.NewFieldElementFromString("13235091290587791090"),
field.NewFieldElementFromString("2562357622728700774"),
field.NewFieldElementFromString("17676678042980201498"),
field.NewFieldElementFromString("5837067135702409874"),
field.NewFieldElementFromString("11238419549114325157"),
FriPOWResponse: field.NewFieldConst(4389),
FriQueryIndices: []field.F{
field.NewFieldConstFromString("16334967868590615051"),
field.NewFieldConstFromString("2911473540496037915"),
field.NewFieldConstFromString("14887216056886344225"),
field.NewFieldConstFromString("7808811227805914295"),
field.NewFieldConstFromString("2018594961417375749"),
field.NewFieldConstFromString("3733368398777208435"),
field.NewFieldConstFromString("2623035669037055104"),
field.NewFieldConstFromString("299243030573481514"),
field.NewFieldConstFromString("7189789717962704433"),
field.NewFieldConstFromString("14566344026886816268"),
field.NewFieldConstFromString("12555390069003437453"),
field.NewFieldConstFromString("17225508403199418233"),
field.NewFieldConstFromString("5088797913879903292"),
field.NewFieldConstFromString("9715691392773433023"),
field.NewFieldConstFromString("7565836764713256165"),
field.NewFieldConstFromString("1500143546029322929"),
field.NewFieldConstFromString("1245802417104422080"),
field.NewFieldConstFromString("6831959786661245110"),
field.NewFieldConstFromString("17271054758535453780"),
field.NewFieldConstFromString("6225460404576395409"),
field.NewFieldConstFromString("15932661092896277351"),
field.NewFieldConstFromString("12452534049198240575"),
field.NewFieldConstFromString("4225199666055520177"),
field.NewFieldConstFromString("13235091290587791090"),
field.NewFieldConstFromString("2562357622728700774"),
field.NewFieldConstFromString("17676678042980201498"),
field.NewFieldConstFromString("5837067135702409874"),
field.NewFieldConstFromString("11238419549114325157"),
},
}
witness := TestFriCircuit{
proofWithPIsFilename: "../../data/dummy_2^14_gates/proof_with_public_inputs.json",
commonCircuitDataFilename: "../../data/dummy_2^14_gates/common_circuit_data.json",
verifierOnlyCircuitDataFilename: ".../../data/dummy_2^14_gates/verifier_only_circuit_data.json",
PlonkZeta: field.QuadraticExtension{
field.NewFieldConstFromString("17377750363769967882"),
field.NewFieldConstFromString("11921191651424768462"),
},
FriAlpha: field.QuadraticExtension{
field.NewFieldConstFromString("16721004555774385479"),
field.NewFieldConstFromString("10688151135543754663"),
},
FriBetas: []field.QuadraticExtension{
{
field.NewFieldConstFromString("3312441922957827805"),
field.NewFieldConstFromString("15128092514958289671"),
},
{
field.NewFieldConstFromString("13630530769060141802"),
field.NewFieldConstFromString("14559883974933163008"),
},
{
field.NewFieldConstFromString("16146508250083930687"),
field.NewFieldConstFromString("5176346568444408396"),
},
},
FriPOWResponse: field.NewFieldConst(4389),
FriQueryIndices: []field.F{
field.NewFieldConstFromString("16334967868590615051"),
field.NewFieldConstFromString("2911473540496037915"),
field.NewFieldConstFromString("14887216056886344225"),
field.NewFieldConstFromString("7808811227805914295"),
field.NewFieldConstFromString("2018594961417375749"),
field.NewFieldConstFromString("3733368398777208435"),
field.NewFieldConstFromString("2623035669037055104"),
field.NewFieldConstFromString("299243030573481514"),
field.NewFieldConstFromString("7189789717962704433"),
field.NewFieldConstFromString("14566344026886816268"),
field.NewFieldConstFromString("12555390069003437453"),
field.NewFieldConstFromString("17225508403199418233"),
field.NewFieldConstFromString("5088797913879903292"),
field.NewFieldConstFromString("9715691392773433023"),
field.NewFieldConstFromString("7565836764713256165"),
field.NewFieldConstFromString("1500143546029322929"),
field.NewFieldConstFromString("1245802417104422080"),
field.NewFieldConstFromString("6831959786661245110"),
field.NewFieldConstFromString("17271054758535453780"),
field.NewFieldConstFromString("6225460404576395409"),
field.NewFieldConstFromString("15932661092896277351"),
field.NewFieldConstFromString("12452534049198240575"),
field.NewFieldConstFromString("4225199666055520177"),
field.NewFieldConstFromString("13235091290587791090"),
field.NewFieldConstFromString("2562357622728700774"),
field.NewFieldConstFromString("17676678042980201498"),
field.NewFieldConstFromString("5837067135702409874"),
field.NewFieldConstFromString("11238419549114325157"),
},
}
witness := TestFriCircuit{}
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
assert.NoError(err)
}

+ 1
- 1
verifier/internal/fri/fri_utils.go

@ -185,7 +185,7 @@ func GetFriInstance(c *common.CommonCircuitData, qeAPI *field.QuadraticExtension
}
g := field.GoldilocksPrimitiveRootOfUnity(degreeBits)
zetaNext := qeAPI.MulExtension(qeAPI.FieldToQE(field.NewFieldElement(g.Uint64())), zeta)
zetaNext := qeAPI.MulExtension(qeAPI.FieldToQE(field.NewFieldConst(g.Uint64())), zeta)
zetaNextBath := FriBatchInfo{
Point: zetaNext,

+ 2
- 2
verifier/internal/gates/base_sum_gate.go

@ -71,7 +71,7 @@ func (g *BaseSumGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExt
limbs[i] = vars.localWires[limbIdx]
}
base_qe := qeAPI.FieldToQE(field.NewFieldElement(g.base))
base_qe := qeAPI.FieldToQE(field.NewFieldConst(g.base))
computedSum := qeAPI.ReduceWithPowers(
limbs,
base_qe,
@ -82,7 +82,7 @@ func (g *BaseSumGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExt
for _, limb := range limbs {
acc := qeAPI.ONE_QE
for i := uint64(0); i < g.base; i++ {
difference := qeAPI.SubExtension(limb, qeAPI.FieldToQE(field.NewFieldElement(i)))
difference := qeAPI.SubExtension(limb, qeAPI.FieldToQE(field.NewFieldConst(i)))
acc = qeAPI.MulExtension(acc, difference)
}
constraints = append(constraints, acc)

+ 2
- 2
verifier/internal/gates/evaluate_gates.go

@ -45,11 +45,11 @@ func (g *EvaluateGatesChip) computeFilter(
continue
}
product = g.qeAPI.MulExtension(product, g.qeAPI.SubExtension(g.qeAPI.FieldToQE(field.NewFieldElement(i)), s))
product = g.qeAPI.MulExtension(product, g.qeAPI.SubExtension(g.qeAPI.FieldToQE(field.NewFieldConst(i)), s))
}
if manySelector {
product = g.qeAPI.MulExtension(product, g.qeAPI.SubExtension(g.qeAPI.FieldToQE(field.NewFieldElement(UNUSED_SELECTOR)), s))
product = g.qeAPI.MulExtension(product, g.qeAPI.SubExtension(g.qeAPI.FieldToQE(field.NewFieldConst(UNUSED_SELECTOR)), s))
}
return product

+ 664
- 664
verifier/internal/gates/gate_test.go
File diff suppressed because it is too large
View File


+ 1
- 1
verifier/internal/gates/poseidon_gate.go

@ -147,7 +147,7 @@ func (g *PoseidonGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticEx
sBoxIn := vars.localWires[g.WirePartialSBox(r)]
constraints = append(constraints, qeAPI.SubExtension(state[0], sBoxIn))
state[0] = poseidonChip.SBoxMonomialExtension(sBoxIn)
state[0] = qeAPI.AddExtension(state[0], qeAPI.FieldToQE(field.NewFieldElement(poseidon.FAST_PARTIAL_ROUND_CONSTANTS[r])))
state[0] = qeAPI.AddExtension(state[0], qeAPI.FieldToQE(poseidon.FAST_PARTIAL_ROUND_CONSTANTS[r]))
state = poseidonChip.MdsPartialLayerFastExtension(state, int(r))
}
sBoxIn := vars.localWires[g.WirePartialSBox(poseidon.N_PARTIAL_ROUNDS-1)]

+ 1
- 1
verifier/internal/gates/random_access_gate.go

@ -115,7 +115,7 @@ func (g *RandomAccessGate) WireBit(i uint64, copy uint64) uint64 {
}
func (g *RandomAccessGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
two := field.QuadraticExtension{field.NewFieldElement(2), field.NewFieldElement(0)}
two := field.QuadraticExtension{field.NewFieldConst(2), field.NewFieldConst(0)}
constraints := []field.QuadraticExtension{}
for copy := uint64(0); copy < g.numCopies; copy++ {

+ 3
- 3
verifier/internal/plonk/challenger.go

@ -11,15 +11,15 @@ import (
)
type ChallengerChip struct {
api frontend.API `gnark:"-"`
field frontend.API `gnark:"-"`
api frontend.API `gnark:"-"`
field field.FieldAPI `gnark:"-"`
poseidonChip *poseidon.PoseidonChip
spongeState [poseidon.SPONGE_WIDTH]field.F
inputBuffer []field.F
outputBuffer []field.F
}
func NewChallengerChip(api frontend.API, fieldAPI frontend.API, poseidonChip *poseidon.PoseidonChip) *ChallengerChip {
func NewChallengerChip(api frontend.API, fieldAPI field.FieldAPI, poseidonChip *poseidon.PoseidonChip) *ChallengerChip {
var spongeState [poseidon.SPONGE_WIDTH]field.F
var inputBuffer []field.F
var outputBuffer []field.F

+ 19
- 19
verifier/internal/plonk/challenger_test.go

@ -21,38 +21,38 @@ type TestChallengerCircuit struct {
func (circuit *TestChallengerCircuit) Define(api frontend.API) error {
fieldAPI := field.NewFieldAPI(api)
degreeBits := 3
qeAPI := field.NewQuadraticExtensionAPI(fieldAPI, uint64(degreeBits))
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI, uint64(degreeBits))
poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI, qeAPI)
challengerChip := NewChallengerChip(api, fieldAPI, poseidonChip)
var circuitDigest [4]field.F
for i := 0; i < len(circuitDigest); i++ {
circuitDigest[i] = fieldAPI.FromBinary(api.ToBinary(circuit.CircuitDigest[i], 64)).(field.F)
circuitDigest[i] = fieldAPI.FromBits(api.ToBinary(circuit.CircuitDigest[i], 64)...)
}
var publicInputs [3]field.F
for i := 0; i < len(publicInputs); i++ {
publicInputs[i] = fieldAPI.FromBinary(api.ToBinary(circuit.PublicInputs[i], 64)).(field.F)
publicInputs[i] = fieldAPI.FromBits(api.ToBinary(circuit.PublicInputs[i], 64)...)
}
var wiresCap [16][4]field.F
for i := 0; i < len(wiresCap); i++ {
for j := 0; j < len(wiresCap[0]); j++ {
wiresCap[i][j] = fieldAPI.FromBinary(api.ToBinary(circuit.WiresCap[i][j], 64)).(field.F)
wiresCap[i][j] = fieldAPI.FromBits(api.ToBinary(circuit.WiresCap[i][j], 64)...)
}
}
var plonkZsPartialProductsCap [16][4]field.F
for i := 0; i < len(plonkZsPartialProductsCap); i++ {
for j := 0; j < len(plonkZsPartialProductsCap[0]); j++ {
plonkZsPartialProductsCap[i][j] = fieldAPI.FromBinary(api.ToBinary(circuit.PlonkZsPartialProductsCap[i][j], 64)).(field.F)
plonkZsPartialProductsCap[i][j] = fieldAPI.FromBits(api.ToBinary(circuit.PlonkZsPartialProductsCap[i][j], 64)...)
}
}
var quotientPolysCap [16][4]field.F
for i := 0; i < len(quotientPolysCap); i++ {
for j := 0; j < len(quotientPolysCap[0]); j++ {
quotientPolysCap[i][j] = fieldAPI.FromBinary(api.ToBinary(circuit.QuotientPolysCap[i][j], 64)).(field.F)
quotientPolysCap[i][j] = fieldAPI.FromBits(api.ToBinary(circuit.QuotientPolysCap[i][j], 64)...)
}
}
@ -66,10 +66,10 @@ func (circuit *TestChallengerCircuit) Define(api frontend.API) error {
plonkGammas := challengerChip.GetNChallenges(numChallenges)
expectedPublicInputHash := [4]field.F{
field.NewFieldElementFromString("8416658900775745054"),
field.NewFieldElementFromString("12574228347150446423"),
field.NewFieldElementFromString("9629056739760131473"),
field.NewFieldElementFromString("3119289788404190010"),
field.NewFieldConstFromString("8416658900775745054"),
field.NewFieldConstFromString("12574228347150446423"),
field.NewFieldConstFromString("9629056739760131473"),
field.NewFieldConstFromString("3119289788404190010"),
}
for i := 0; i < 4; i++ {
@ -77,13 +77,13 @@ func (circuit *TestChallengerCircuit) Define(api frontend.API) error {
}
expectedPlonkBetas := [2]field.F{
field.NewFieldElementFromString("4678728155650926271"),
field.NewFieldElementFromString("13611962404289024887"),
field.NewFieldConstFromString("4678728155650926271"),
field.NewFieldConstFromString("13611962404289024887"),
}
expectedPlonkGammas := [2]frontend.Variable{
field.NewFieldElementFromString("13237663823305715949"),
field.NewFieldElementFromString("15389314098328235145"),
expectedPlonkGammas := [2]field.F{
field.NewFieldConstFromString("13237663823305715949"),
field.NewFieldConstFromString("15389314098328235145"),
}
for i := 0; i < 2; i++ {
@ -95,8 +95,8 @@ func (circuit *TestChallengerCircuit) Define(api frontend.API) error {
plonkAlphas := challengerChip.GetNChallenges(numChallenges)
expectedPlonkAlphas := [2]field.F{
field.NewFieldElementFromString("14505919539124304197"),
field.NewFieldElementFromString("1695455639263736117"),
field.NewFieldConstFromString("14505919539124304197"),
field.NewFieldConstFromString("1695455639263736117"),
}
for i := 0; i < 2; i++ {
@ -107,8 +107,8 @@ func (circuit *TestChallengerCircuit) Define(api frontend.API) error {
plonkZeta := challengerChip.GetExtensionChallenge()
expectedPlonkZeta := field.QuadraticExtension{
field.NewFieldElementFromString("14887793628029982930"),
field.NewFieldElementFromString("1136137158284059037"),
field.NewFieldConstFromString("14887793628029982930"),
field.NewFieldConstFromString("1136137158284059037"),
}
for i := 0; i < 2; i++ {

+ 3
- 3
verifier/internal/plonk/plonk.go

@ -38,9 +38,9 @@ func NewPlonkChip(api frontend.API, qeAPI *field.QuadraticExtensionAPI, commonDa
commonData: commonData,
DEGREE: field.NewFieldElement(1 << commonData.DegreeBits),
DEGREE_BITS_F: field.NewFieldElement(commonData.DegreeBits),
DEGREE_QE: field.QuadraticExtension{field.NewFieldElement(1 << commonData.DegreeBits), field.ZERO_F},
DEGREE: field.NewFieldConst(1 << commonData.DegreeBits),
DEGREE_BITS_F: field.NewFieldConst(commonData.DegreeBits),
DEGREE_QE: field.QuadraticExtension{field.NewFieldConst(1 << commonData.DegreeBits), field.ZERO_F},
evaluateGatesChip: evaluateGatesChip,
}

+ 1
- 1
verifier/internal/plonk/plonk_test.go

@ -27,7 +27,7 @@ func (circuit *TestPlonkCircuit) Define(api frontend.API) error {
proofChallenges := verifierChip.GetChallenges(proofWithPis, publicInputsHash, commonCircuitData, verifierOnlyCircuitData)
fieldAPI := field.NewFieldAPI(api)
qeAPI := field.NewQuadraticExtensionAPI(fieldAPI, commonCircuitData.DegreeBits)
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI, commonCircuitData.DegreeBits)
plonkChip := plonk.NewPlonkChip(
api,
qeAPI,

+ 2
- 2
verifier/utils/deserialize.go

@ -229,7 +229,7 @@ func DeserializeFriProof(openingProofRaw struct {
PowWitness uint64
}) common.FriProof {
var openingProof common.FriProof
openingProof.PowWitness = field.NewFieldElement(openingProofRaw.PowWitness)
openingProof.PowWitness = field.NewFieldConst(openingProofRaw.PowWitness)
openingProof.FinalPoly.Coeffs = utils.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs)
openingProof.CommitPhaseMerkleCaps = make([]common.MerkleCap, len(openingProofRaw.CommitPhaseMerkleCaps))
@ -328,7 +328,7 @@ func DeserializeProofChallenges(path string) common.ProofChallenges {
proofChallenges.PlonkZeta = utils.Uint64ArrayToQuadraticExtension(raw.PlonkZeta)
proofChallenges.FriChallenges.FriAlpha = utils.Uint64ArrayToQuadraticExtension(raw.FriChallenges.FriAlpha)
proofChallenges.FriChallenges.FriBetas = utils.Uint64ArrayToQuadraticExtensionArray(raw.FriChallenges.FriBetas)
proofChallenges.FriChallenges.FriPowResponse = field.NewFieldElement(raw.FriChallenges.FriPowResponse)
proofChallenges.FriChallenges.FriPowResponse = field.NewFieldConst(raw.FriChallenges.FriPowResponse)
proofChallenges.FriChallenges.FriQueryIndices = utils.Uint64ArrayToFArray(raw.FriChallenges.FriQueryIndices)
return proofChallenges

+ 78
- 12
verifier/verifier.go

@ -11,7 +11,7 @@ import (
type VerifierChip struct {
api frontend.API `gnark:"-"`
fieldAPI frontend.API `gnark:"-"`
fieldAPI field.FieldAPI `gnark:"-"`
qeAPI *field.QuadraticExtensionAPI `gnark:"-"`
poseidonChip *poseidon.PoseidonChip
plonkChip *plonk.PlonkChip
@ -21,7 +21,7 @@ type VerifierChip struct {
func NewVerifierChip(api frontend.API, commonCircuitData common.CommonCircuitData) *VerifierChip {
fieldAPI := field.NewFieldAPI(api)
qeAPI := field.NewQuadraticExtensionAPI(fieldAPI, commonCircuitData.DegreeBits)
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI, commonCircuitData.DegreeBits)
hashAPI := poseidon.NewHashAPI(fieldAPI)
poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI, qeAPI)
@ -83,9 +83,75 @@ func (c *VerifierChip) GetChallenges(
}
}
func (c *VerifierChip) Verify(proofWithPis common.ProofWithPublicInputs, verifierData common.VerifierOnlyCircuitData, commonData common.CommonCircuitData) {
// TODO: Verify shape of the proof?
/*
func (c *VerifierChip) generateProofInput(commonData common.CommonCircuitData) common.ProofWithPublicInputs {
// Generate the parts of the witness that is for the plonky2 proof input
capHeight := commonData.Config.FriConfig.CapHeight
friCommitPhaseMerkleCaps := []common.MerkleCap{}
for i := 0; i < len(commonData.FriParams.ReductionArityBits); i++ {
friCommitPhaseMerkleCaps = append(friCommitPhaseMerkleCaps, common.NewMerkleCap(capHeight))
}
salt := commonData.SaltSize()
numLeavesPerOracle := []uint{
commonData.NumPreprocessedPolys(),
commonData.Config.NumWires + salt,
commonData.NumZsPartialProductsPolys() + salt,
commonData.NumQuotientPolys() + salt,
}
friQueryRoundProofs := []common.FriQueryRound{}
for i := uint64(0); i < commonData.FriParams.Config.NumQueryRounds; i++ {
evalProofs := []common.EvalProof{}
merkleProofLen := commonData.FriParams.LDEBits() - capHeight
for _, numLeaves := range numLeavesPerOracle {
leaves := make([]field.F, numLeaves)
merkleProof := common.NewMerkleProof(merkleProofLen)
evalProofs = append(evalProofs, common.NewEvalProof(leaves, merkleProof))
}
initialTreesProof := common.NewFriInitialTreeProof(evalProofs)
steps := []common.FriQueryStep{}
for _, arityBit := range commonData.FriParams.ReductionArityBits {
if merkleProofLen < arityBit {
panic("merkleProofLen < arityBits")
}
steps = append(steps, common.NewFriQueryStep(arityBit, merkleProofLen))
}
friQueryRoundProofs = append(friQueryRoundProofs, common.NewFriQueryRound(steps, initialTreesProof))
}
proofInput := common.ProofWithPublicInputs{
Proof: common.Proof{
WiresCap: common.NewMerkleCap(capHeight),
PlonkZsPartialProductsCap: common.NewMerkleCap(capHeight),
QuotientPolysCap: common.NewMerkleCap(capHeight),
Openings: common.NewOpeningSet(
commonData.Config.NumConstants,
commonData.Config.NumRoutedWires,
commonData.Config.NumWires,
commonData.Config.NumChallenges,
commonData.NumPartialProducts,
commonData.QuotientDegreeFactor,
),
OpeningProof: common.FriProof{
CommitPhaseMerkleCaps: friCommitPhaseMerkleCaps,
QueryRoundProofs: friQueryRoundProofs,
FinalPoly: common.NewPolynomialCoeffs(commonData.FriParams.FinalPolyLen()),
},
},
PublicInputs: make([]field.F, commonData.NumPublicInputs),
}
return proofInput
}
*/
func (c *VerifierChip) Verify(proofWithPis common.ProofWithPublicInputs, verifierData common.VerifierOnlyCircuitData, commonData common.CommonCircuitData) {
// Generate the parts of the witness that is for the plonky2 proof input
publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs)
proofChallenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData, verifierData)
@ -100,21 +166,21 @@ func (c *VerifierChip) Verify(proofWithPis common.ProofWithPublicInputs, verifie
// Seems like there is a bug in the emulated field code.
// Add ZERO to all of the fri challenges values to reduce them.
proofChallenges.PlonkZeta[0] = c.fieldAPI.Add(proofChallenges.PlonkZeta[0], field.ZERO_F).(field.F)
proofChallenges.PlonkZeta[1] = c.fieldAPI.Add(proofChallenges.PlonkZeta[1], field.ZERO_F).(field.F)
proofChallenges.PlonkZeta[0] = c.fieldAPI.Add(proofChallenges.PlonkZeta[0], field.ZERO_F)
proofChallenges.PlonkZeta[1] = c.fieldAPI.Add(proofChallenges.PlonkZeta[1], field.ZERO_F)
proofChallenges.FriChallenges.FriAlpha[0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[0], field.ZERO_F).(field.F)
proofChallenges.FriChallenges.FriAlpha[1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[1], field.ZERO_F).(field.F)
proofChallenges.FriChallenges.FriAlpha[0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[0], field.ZERO_F)
proofChallenges.FriChallenges.FriAlpha[1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[1], field.ZERO_F)
for i := 0; i < len(proofChallenges.FriChallenges.FriBetas); i++ {
proofChallenges.FriChallenges.FriBetas[i][0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][0], field.ZERO_F).(field.F)
proofChallenges.FriChallenges.FriBetas[i][1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][1], field.ZERO_F).(field.F)
proofChallenges.FriChallenges.FriBetas[i][0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][0], field.ZERO_F)
proofChallenges.FriChallenges.FriBetas[i][1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][1], field.ZERO_F)
}
proofChallenges.FriChallenges.FriPowResponse = c.fieldAPI.Add(proofChallenges.FriChallenges.FriPowResponse, field.ZERO_F).(field.F)
proofChallenges.FriChallenges.FriPowResponse = c.fieldAPI.Add(proofChallenges.FriChallenges.FriPowResponse, field.ZERO_F)
for i := 0; i < len(proofChallenges.FriChallenges.FriQueryIndices); i++ {
proofChallenges.FriChallenges.FriQueryIndices[i] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriQueryIndices[i], field.ZERO_F).(field.F)
proofChallenges.FriChallenges.FriQueryIndices[i] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriQueryIndices[i], field.ZERO_F)
}
c.friChip.VerifyFriProof(

+ 91
- 91
verifier/verifier_test.go

@ -81,7 +81,7 @@ func (c *TestVerifierChallengesCircuit) GetChallengesSanityCheck(
}
// This test is commented out because pow_witness is randomized between runs of the prover.
// expectedPowResponse := field.NewFieldElementFromString("92909863298412")
// expectedPowResponse := field.NewFieldConstFromString("92909863298412")
// c.field.AssertIsEqual(proofChallenges.FriChallenges.FriPowResponse, expectedPowResponse)
if len(proofChallenges.FriChallenges.FriQueryIndices) != int(c.numFriQueries) {
@ -118,68 +118,68 @@ func TestFibonacciVerifierWitness(t *testing.T) {
t: t,
expectedPublicInputsHash: poseidon.Hash{
field.NewFieldElementFromString("8416658900775745054"),
field.NewFieldElementFromString("12574228347150446423"),
field.NewFieldElementFromString("9629056739760131473"),
field.NewFieldElementFromString("3119289788404190010"),
field.NewFieldConstFromString("8416658900775745054"),
field.NewFieldConstFromString("12574228347150446423"),
field.NewFieldConstFromString("9629056739760131473"),
field.NewFieldConstFromString("3119289788404190010"),
},
expectedPlonkBetas: []field.F{
field.NewFieldElementFromString("4678728155650926271"),
field.NewFieldElementFromString("13611962404289024887"),
field.NewFieldConstFromString("4678728155650926271"),
field.NewFieldConstFromString("13611962404289024887"),
},
expectedPlonkGammas: []field.F{
field.NewFieldElementFromString("13237663823305715949"),
field.NewFieldElementFromString("15389314098328235145"),
field.NewFieldConstFromString("13237663823305715949"),
field.NewFieldConstFromString("15389314098328235145"),
},
expectedPlonkAlphas: []field.F{
field.NewFieldElementFromString("14505919539124304197"),
field.NewFieldElementFromString("1695455639263736117"),
field.NewFieldConstFromString("14505919539124304197"),
field.NewFieldConstFromString("1695455639263736117"),
},
expectedPlonkZeta: field.QuadraticExtension{
field.NewFieldElementFromString("14887793628029982930"),
field.NewFieldElementFromString("1136137158284059037"),
field.NewFieldConstFromString("14887793628029982930"),
field.NewFieldConstFromString("1136137158284059037"),
},
expectedFriAlpha: field.QuadraticExtension{
field.NewFieldElementFromString("14641715242626918707"),
field.NewFieldElementFromString("10574243340537902930"),
field.NewFieldConstFromString("14641715242626918707"),
field.NewFieldConstFromString("10574243340537902930"),
},
expectedFriBetas: []field.QuadraticExtension{},
expectedFriQueryIndices: []field.F{
field.NewFieldElement(6790812084677375942),
field.NewFieldElement(12394212020331474798),
field.NewFieldElement(16457600747000998582),
field.NewFieldElement(1543271328932331916),
field.NewFieldElement(12115726870906958644),
field.NewFieldElement(6775897107605342797),
field.NewFieldElement(15989401564746021030),
field.NewFieldElement(10691676456016926845),
field.NewFieldElement(1632499470630032007),
field.NewFieldElement(1317292355445098328),
field.NewFieldElement(18391440812534384252),
field.NewFieldElement(17321705613231354333),
field.NewFieldElement(6176487551308859603),
field.NewFieldElement(7119835651572002873),
field.NewFieldElement(3903019169623116693),
field.NewFieldElement(4886491111111487546),
field.NewFieldElement(4087641893164620518),
field.NewFieldElement(13801643080324181364),
field.NewFieldElement(16993775312274189321),
field.NewFieldElement(9268202926222765679),
field.NewFieldElement(10683001302406181735),
field.NewFieldElement(13359465725531647963),
field.NewFieldElement(4523327590105620849),
field.NewFieldElement(4883588003760409588),
field.NewFieldElement(187699146998097671),
field.NewFieldElement(14489263557623716717),
field.NewFieldElement(11748359318238148146),
field.NewFieldElement(13636347200053048758),
field.NewFieldConst(6790812084677375942),
field.NewFieldConst(12394212020331474798),
field.NewFieldConst(16457600747000998582),
field.NewFieldConst(1543271328932331916),
field.NewFieldConst(12115726870906958644),
field.NewFieldConst(6775897107605342797),
field.NewFieldConst(15989401564746021030),
field.NewFieldConst(10691676456016926845),
field.NewFieldConst(1632499470630032007),
field.NewFieldConst(1317292355445098328),
field.NewFieldConst(18391440812534384252),
field.NewFieldConst(17321705613231354333),
field.NewFieldConst(6176487551308859603),
field.NewFieldConst(7119835651572002873),
field.NewFieldConst(3903019169623116693),
field.NewFieldConst(4886491111111487546),
field.NewFieldConst(4087641893164620518),
field.NewFieldConst(13801643080324181364),
field.NewFieldConst(16993775312274189321),
field.NewFieldConst(9268202926222765679),
field.NewFieldConst(10683001302406181735),
field.NewFieldConst(13359465725531647963),
field.NewFieldConst(4523327590105620849),
field.NewFieldConst(4883588003760409588),
field.NewFieldConst(187699146998097671),
field.NewFieldConst(14489263557623716717),
field.NewFieldConst(11748359318238148146),
field.NewFieldConst(13636347200053048758),
},
}
witness := TestVerifierChallengesCircuit{}
@ -201,81 +201,81 @@ func TestDummyVerifierWitness(t *testing.T) {
t: t,
expectedPublicInputsHash: poseidon.Hash{
field.NewFieldElementFromString("0"),
field.NewFieldElementFromString("0"),
field.NewFieldElementFromString("0"),
field.NewFieldElementFromString("0"),
field.NewFieldConstFromString("0"),
field.NewFieldConstFromString("0"),
field.NewFieldConstFromString("0"),
field.NewFieldConstFromString("0"),
},
expectedPlonkBetas: []field.F{
field.NewFieldElementFromString("11216469004148781751"),
field.NewFieldElementFromString("6201977337075152249"),
field.NewFieldConstFromString("11216469004148781751"),
field.NewFieldConstFromString("6201977337075152249"),
},
expectedPlonkGammas: []field.F{
field.NewFieldElementFromString("8369751006669847974"),
field.NewFieldElementFromString("3610024170884289835"),
field.NewFieldConstFromString("8369751006669847974"),
field.NewFieldConstFromString("3610024170884289835"),
},
expectedPlonkAlphas: []field.F{
field.NewFieldElementFromString("970160439138448145"),
field.NewFieldElementFromString("2402201283787401921"),
field.NewFieldConstFromString("970160439138448145"),
field.NewFieldConstFromString("2402201283787401921"),
},
expectedPlonkZeta: field.QuadraticExtension{
field.NewFieldElementFromString("17377750363769967882"),
field.NewFieldElementFromString("11921191651424768462"),
field.NewFieldConstFromString("17377750363769967882"),
field.NewFieldConstFromString("11921191651424768462"),
},
expectedFriAlpha: field.QuadraticExtension{
field.NewFieldElementFromString("16721004555774385479"),
field.NewFieldElementFromString("10688151135543754663"),
field.NewFieldConstFromString("16721004555774385479"),
field.NewFieldConstFromString("10688151135543754663"),
},
expectedFriBetas: []field.QuadraticExtension{
{
field.NewFieldElementFromString("3312441922957827805"),
field.NewFieldElementFromString("15128092514958289671"),
field.NewFieldConstFromString("3312441922957827805"),
field.NewFieldConstFromString("15128092514958289671"),
},
{
field.NewFieldElementFromString("13630530769060141802"),
field.NewFieldElementFromString("14559883974933163008"),
field.NewFieldConstFromString("13630530769060141802"),
field.NewFieldConstFromString("14559883974933163008"),
},
{
field.NewFieldElementFromString("16146508250083930687"),
field.NewFieldElementFromString("5176346568444408396"),
field.NewFieldConstFromString("16146508250083930687"),
field.NewFieldConstFromString("5176346568444408396"),
},
},
expectedFriQueryIndices: []field.F{
field.NewFieldElement(16334967868590615051),
field.NewFieldElement(2911473540496037915),
field.NewFieldElement(14887216056886344225),
field.NewFieldElement(7808811227805914295),
field.NewFieldElement(2018594961417375749),
field.NewFieldElement(3733368398777208435),
field.NewFieldElement(2623035669037055104),
field.NewFieldElement(299243030573481514),
field.NewFieldElement(7189789717962704433),
field.NewFieldElement(14566344026886816268),
field.NewFieldElement(12555390069003437453),
field.NewFieldElement(17225508403199418233),
field.NewFieldElement(5088797913879903292),
field.NewFieldElement(9715691392773433023),
field.NewFieldElement(7565836764713256165),
field.NewFieldElement(1500143546029322929),
field.NewFieldElement(1245802417104422080),
field.NewFieldElement(6831959786661245110),
field.NewFieldElement(17271054758535453780),
field.NewFieldElement(6225460404576395409),
field.NewFieldElement(15932661092896277351),
field.NewFieldElement(12452534049198240575),
field.NewFieldElement(4225199666055520177),
field.NewFieldElement(13235091290587791090),
field.NewFieldElement(2562357622728700774),
field.NewFieldElement(17676678042980201498),
field.NewFieldElement(5837067135702409874),
field.NewFieldElement(11238419549114325157),
field.NewFieldConst(16334967868590615051),
field.NewFieldConst(2911473540496037915),
field.NewFieldConst(14887216056886344225),
field.NewFieldConst(7808811227805914295),
field.NewFieldConst(2018594961417375749),
field.NewFieldConst(3733368398777208435),
field.NewFieldConst(2623035669037055104),
field.NewFieldConst(299243030573481514),
field.NewFieldConst(7189789717962704433),
field.NewFieldConst(14566344026886816268),
field.NewFieldConst(12555390069003437453),
field.NewFieldConst(17225508403199418233),
field.NewFieldConst(5088797913879903292),
field.NewFieldConst(9715691392773433023),
field.NewFieldConst(7565836764713256165),
field.NewFieldConst(1500143546029322929),
field.NewFieldConst(1245802417104422080),
field.NewFieldConst(6831959786661245110),
field.NewFieldConst(17271054758535453780),
field.NewFieldConst(6225460404576395409),
field.NewFieldConst(15932661092896277351),
field.NewFieldConst(12452534049198240575),
field.NewFieldConst(4225199666055520177),
field.NewFieldConst(13235091290587791090),
field.NewFieldConst(2562357622728700774),
field.NewFieldConst(17676678042980201498),
field.NewFieldConst(5837067135702409874),
field.NewFieldConst(11238419549114325157),
},
}
witness := TestVerifierChallengesCircuit{} // No real witness as the test circuit's Define function will inject in the witness

Loading…
Cancel
Save