mirror of
https://github.com/arnaucube/gnark-plonky2-verifier.git
synced 2026-01-12 09:01:32 +01:00
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
This commit is contained in:
@@ -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 NewFieldElementFromString(x string) F {
|
||||
return emulated.NewElement[EmulatedField](x)
|
||||
}
|
||||
|
||||
func NewFieldAPI(api frontend.API) frontend.API {
|
||||
field, err := emulated.NewField[EmulatedField](api)
|
||||
func NewFieldAPI(api frontend.API) FieldAPI {
|
||||
fieldAPI, err := emulated.NewField[EmulatedField](api)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return field
|
||||
return fieldAPI
|
||||
}
|
||||
|
||||
var ONE_F = NewFieldElement(1)
|
||||
var ZERO_F = NewFieldElement(0)
|
||||
var NEG_ONE_F = NewFieldElement(EmulatedField{}.Modulus().Uint64() - 1)
|
||||
func NewFieldConst(x uint64) F {
|
||||
val := emulated.ValueOf[EmulatedField](x)
|
||||
return &val
|
||||
}
|
||||
|
||||
func NewFieldConstFromString(x string) F {
|
||||
val := emulated.ValueOf[EmulatedField](x)
|
||||
return &val
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user