* gl * stage 1 optimizations * working optimized poseidon * Fix posedion tests * in progress gate type refactor * working gates * working e2e * hm' * hm2 * debug saga continues * more debugging cry * more debug * it finally works * optimizations * more optimizations * new changes * more optimizations * more cleanup * some refactoring * new files * flattening of packages * working commit * more refactor * more flattening * more flattening * more more refactor * more optimizations * more optimizations * more optimizations * plonk benchmark * plonk * fix r1cs * resolve kevin's comments * Update goldilocks/base.go Co-authored-by: Kevin Jue <kjue235@gmail.com> * Update goldilocks/base.go Co-authored-by: Kevin Jue <kjue235@gmail.com> * Update goldilocks/base.go Co-authored-by: Kevin Jue <kjue235@gmail.com> * Update goldilocks/quadratic_extension.go Co-authored-by: Kevin Jue <kjue235@gmail.com> * fix: resolve kevin's confusion --------- Co-authored-by: Kevin Jue <kjue235@gmail.com>main
@ -0,0 +1,187 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"bytes" |
|||
"flag" |
|||
"fmt" |
|||
"math/big" |
|||
"os" |
|||
"time" |
|||
|
|||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/types" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier" |
|||
|
|||
"github.com/consensys/gnark-crypto/ecc" |
|||
"github.com/consensys/gnark/backend/plonk" |
|||
"github.com/consensys/gnark/constraint" |
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/consensys/gnark/frontend/cs/scs" |
|||
"github.com/consensys/gnark/profile" |
|||
"github.com/consensys/gnark/test" |
|||
) |
|||
|
|||
type BenchmarkPlonky2VerifierCircuitPlonk struct { |
|||
Proof types.Proof |
|||
PublicInputs []gl.Variable `gnark:",public"` |
|||
|
|||
verifierChip *verifier.VerifierChip `gnark:"-"` |
|||
plonky2CircuitName string `gnark:"-"` |
|||
} |
|||
|
|||
func (circuit *BenchmarkPlonky2VerifierCircuitPlonk) Define(api frontend.API) error { |
|||
circuitDirname := "./verifier/data/" + circuit.plonky2CircuitName + "/" |
|||
commonCircuitData := verifier.DeserializeCommonCircuitData(circuitDirname + "common_circuit_data.json") |
|||
verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuitDirname + "verifier_only_circuit_data.json") |
|||
|
|||
circuit.verifierChip = verifier.NewVerifierChip(api, commonCircuitData) |
|||
|
|||
circuit.verifierChip.Verify(circuit.Proof, circuit.PublicInputs, verifierOnlyCircuitData, commonCircuitData) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func compileCircuitPlonk(plonky2Circuit string, profileCircuit bool, serialize bool, outputSolidity bool) (constraint.ConstraintSystem, plonk.ProvingKey, plonk.VerifyingKey) { |
|||
circuit := BenchmarkPlonky2VerifierCircuitPlonk{ |
|||
plonky2CircuitName: plonky2Circuit, |
|||
} |
|||
proofWithPis := verifier.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json") |
|||
circuit.Proof = proofWithPis.Proof |
|||
circuit.PublicInputs = proofWithPis.PublicInputs |
|||
|
|||
var p *profile.Profile |
|||
if profileCircuit { |
|||
p = profile.Start() |
|||
} |
|||
r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), scs.NewBuilder, &circuit) |
|||
if err != nil { |
|||
fmt.Println("error in building circuit", err) |
|||
os.Exit(1) |
|||
} |
|||
|
|||
if profileCircuit { |
|||
p.Stop() |
|||
p.Top() |
|||
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()) |
|||
} |
|||
|
|||
// Don't serialize the circuit for now, since it takes up too much memory
|
|||
/* |
|||
if serialize { |
|||
fR1CS, _ := os.Create("circuit") |
|||
r1cs.WriteTo(fR1CS) |
|||
fR1CS.Close() |
|||
} |
|||
*/ |
|||
|
|||
srs, err := test.NewKZGSRS(r1cs) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
fmt.Println("Running circuit setup", time.Now()) |
|||
pk, vk, err := plonk.Setup(r1cs, srs) |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
os.Exit(1) |
|||
} |
|||
|
|||
if serialize { |
|||
fPK, _ := os.Create("proving.key") |
|||
pk.WriteTo(fPK) |
|||
fPK.Close() |
|||
|
|||
fVK, _ := os.Create("verifying.key") |
|||
vk.WriteTo(fVK) |
|||
fVK.Close() |
|||
} |
|||
|
|||
if outputSolidity { |
|||
fSolidity, _ := os.Create("proof.sol") |
|||
err = vk.ExportSolidity(fSolidity) |
|||
} |
|||
|
|||
return r1cs, pk, vk |
|||
} |
|||
|
|||
func createProofPlonk(plonky2Circuit string, r1cs constraint.ConstraintSystem, pk plonk.ProvingKey, vk plonk.VerifyingKey, serialize bool) plonk.Proof { |
|||
proofWithPis := verifier.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json") |
|||
|
|||
// Witness
|
|||
assignment := &BenchmarkPlonky2VerifierCircuitPlonk{ |
|||
Proof: proofWithPis.Proof, |
|||
PublicInputs: proofWithPis.PublicInputs, |
|||
} |
|||
|
|||
fmt.Println("Generating witness", time.Now()) |
|||
witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) |
|||
publicWitness, _ := witness.Public() |
|||
|
|||
fmt.Println("Creating proof", time.Now()) |
|||
proof, err := plonk.Prove(r1cs, pk, witness) |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
os.Exit(1) |
|||
} |
|||
fmt.Println("Verifying proof", time.Now()) |
|||
err = plonk.Verify(proof, vk, publicWitness) |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
os.Exit(1) |
|||
} |
|||
|
|||
const fpSize = 4 * 8 |
|||
var buf bytes.Buffer |
|||
proof.WriteRawTo(&buf) |
|||
proofBytes := buf.Bytes() |
|||
|
|||
var ( |
|||
a [2]*big.Int |
|||
b [2][2]*big.Int |
|||
c [2]*big.Int |
|||
) |
|||
|
|||
// proof.Ar, proof.Bs, proof.Krs
|
|||
a[0] = new(big.Int).SetBytes(proofBytes[fpSize*0 : fpSize*1]) |
|||
a[1] = new(big.Int).SetBytes(proofBytes[fpSize*1 : fpSize*2]) |
|||
b[0][0] = new(big.Int).SetBytes(proofBytes[fpSize*2 : fpSize*3]) |
|||
b[0][1] = new(big.Int).SetBytes(proofBytes[fpSize*3 : fpSize*4]) |
|||
b[1][0] = new(big.Int).SetBytes(proofBytes[fpSize*4 : fpSize*5]) |
|||
b[1][1] = new(big.Int).SetBytes(proofBytes[fpSize*5 : fpSize*6]) |
|||
c[0] = new(big.Int).SetBytes(proofBytes[fpSize*6 : fpSize*7]) |
|||
c[1] = new(big.Int).SetBytes(proofBytes[fpSize*7 : fpSize*8]) |
|||
|
|||
println("a[0] is ", a[0].String()) |
|||
println("a[1] is ", a[1].String()) |
|||
|
|||
println("b[0][0] is ", b[0][0].String()) |
|||
println("b[0][1] is ", b[0][1].String()) |
|||
println("b[1][0] is ", b[1][0].String()) |
|||
println("b[1][1] is ", b[1][1].String()) |
|||
|
|||
println("c[0] is ", c[0].String()) |
|||
println("c[1] is ", c[1].String()) |
|||
|
|||
return proof |
|||
} |
|||
|
|||
func main() { |
|||
plonky2Circuit := flag.String("plonky2-circuit", "", "plonky2 circuit to benchmark") |
|||
profileCircuit := flag.Bool("profile", false, "profile the circuit") |
|||
serialize := flag.Bool("serialize", false, "serialize the circuit") |
|||
outputSolidity := flag.Bool("solidity", false, "output solidity code for the circuit") |
|||
|
|||
flag.Parse() |
|||
|
|||
if plonky2Circuit == nil || *plonky2Circuit == "" { |
|||
fmt.Println("Please provide a plonky2 circuit to benchmark") |
|||
os.Exit(1) |
|||
} |
|||
|
|||
r1cs, pk, vk := compileCircuitPlonk(*plonky2Circuit, *profileCircuit, *serialize, *outputSolidity) |
|||
createProofPlonk(*plonky2Circuit, r1cs, pk, vk, *serialize) |
|||
} |
|||
@ -0,0 +1,166 @@ |
|||
package challenger |
|||
|
|||
import ( |
|||
"fmt" |
|||
|
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/fri" |
|||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/types" |
|||
) |
|||
|
|||
type Chip struct { |
|||
api frontend.API `gnark:"-"` |
|||
poseidonChip *poseidon.GoldilocksChip |
|||
poseidonBN254Chip *poseidon.BN254Chip |
|||
spongeState [poseidon.SPONGE_WIDTH]gl.Variable |
|||
inputBuffer []gl.Variable |
|||
outputBuffer []gl.Variable |
|||
} |
|||
|
|||
func NewChip(api frontend.API) *Chip { |
|||
var spongeState [poseidon.SPONGE_WIDTH]gl.Variable |
|||
var inputBuffer []gl.Variable |
|||
var outputBuffer []gl.Variable |
|||
for i := 0; i < poseidon.SPONGE_WIDTH; i++ { |
|||
spongeState[i] = gl.Zero() |
|||
} |
|||
poseidonChip := poseidon.NewGoldilocksChip(api) |
|||
poseidonBN254Chip := poseidon.NewBN254Chip(api) |
|||
return &Chip{ |
|||
api: api, |
|||
poseidonChip: poseidonChip, |
|||
poseidonBN254Chip: poseidonBN254Chip, |
|||
spongeState: spongeState, |
|||
inputBuffer: inputBuffer, |
|||
outputBuffer: outputBuffer, |
|||
} |
|||
} |
|||
|
|||
func (c *Chip) ObserveElement(element gl.Variable) { |
|||
c.outputBuffer = clearBuffer(c.outputBuffer) |
|||
c.inputBuffer = append(c.inputBuffer, element) |
|||
if len(c.inputBuffer) == poseidon.SPONGE_RATE { |
|||
c.duplexing() |
|||
} |
|||
} |
|||
|
|||
func (c *Chip) ObserveElements(elements []gl.Variable) { |
|||
for i := 0; i < len(elements); i++ { |
|||
c.ObserveElement(elements[i]) |
|||
} |
|||
} |
|||
|
|||
func (c *Chip) ObserveHash(hash poseidon.GoldilocksHashOut) { |
|||
elements := c.poseidonChip.ToVec(hash) |
|||
c.ObserveElements(elements) |
|||
} |
|||
|
|||
func (c *Chip) ObserveBN254Hash(hash poseidon.BN254HashOut) { |
|||
elements := c.poseidonBN254Chip.ToVec(hash) |
|||
c.ObserveElements(elements) |
|||
} |
|||
|
|||
func (c *Chip) ObserveCap(cap []poseidon.BN254HashOut) { |
|||
for i := 0; i < len(cap); i++ { |
|||
c.ObserveBN254Hash(cap[i]) |
|||
} |
|||
} |
|||
|
|||
func (c *Chip) ObserveExtensionElement(element gl.QuadraticExtensionVariable) { |
|||
c.ObserveElements(element[:]) |
|||
} |
|||
|
|||
func (c *Chip) ObserveExtensionElements(elements []gl.QuadraticExtensionVariable) { |
|||
for i := 0; i < len(elements); i++ { |
|||
c.ObserveExtensionElement(elements[i]) |
|||
} |
|||
} |
|||
|
|||
func (c *Chip) ObserveOpenings(openings fri.Openings) { |
|||
for i := 0; i < len(openings.Batches); i++ { |
|||
c.ObserveExtensionElements(openings.Batches[i].Values) |
|||
} |
|||
} |
|||
|
|||
func (c *Chip) GetChallenge() gl.Variable { |
|||
if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 { |
|||
c.duplexing() |
|||
} |
|||
|
|||
challenge := c.outputBuffer[len(c.outputBuffer)-1] |
|||
c.outputBuffer = c.outputBuffer[:len(c.outputBuffer)-1] |
|||
|
|||
return challenge |
|||
} |
|||
|
|||
func (c *Chip) GetNChallenges(n uint64) []gl.Variable { |
|||
challenges := make([]gl.Variable, n) |
|||
for i := uint64(0); i < n; i++ { |
|||
challenges[i] = c.GetChallenge() |
|||
} |
|||
return challenges |
|||
} |
|||
|
|||
func (c *Chip) GetExtensionChallenge() gl.QuadraticExtensionVariable { |
|||
values := c.GetNChallenges(2) |
|||
return gl.QuadraticExtensionVariable{values[0], values[1]} |
|||
} |
|||
|
|||
func (c *Chip) GetHash() poseidon.GoldilocksHashOut { |
|||
return [4]gl.Variable{c.GetChallenge(), c.GetChallenge(), c.GetChallenge(), c.GetChallenge()} |
|||
} |
|||
|
|||
func (c *Chip) GetFriChallenges( |
|||
commitPhaseMerkleCaps []types.FriMerkleCap, |
|||
finalPoly types.PolynomialCoeffs, |
|||
powWitness gl.Variable, |
|||
degreeBits uint64, |
|||
config types.FriConfig, |
|||
) types.FriChallenges { |
|||
numFriQueries := config.NumQueryRounds |
|||
friAlpha := c.GetExtensionChallenge() |
|||
|
|||
var friBetas []gl.QuadraticExtensionVariable |
|||
for i := 0; i < len(commitPhaseMerkleCaps); i++ { |
|||
c.ObserveCap(commitPhaseMerkleCaps[i]) |
|||
friBetas = append(friBetas, c.GetExtensionChallenge()) |
|||
} |
|||
|
|||
c.ObserveExtensionElements(finalPoly.Coeffs) |
|||
c.ObserveElement(powWitness) |
|||
|
|||
friPowResponse := c.GetChallenge() |
|||
friQueryIndices := c.GetNChallenges(numFriQueries) |
|||
|
|||
return types.FriChallenges{ |
|||
FriAlpha: friAlpha, |
|||
FriBetas: friBetas, |
|||
FriPowResponse: friPowResponse, |
|||
FriQueryIndices: friQueryIndices, |
|||
} |
|||
} |
|||
|
|||
func clearBuffer(buffer []gl.Variable) []gl.Variable { |
|||
return make([]gl.Variable, 0) |
|||
} |
|||
|
|||
func (c *Chip) duplexing() { |
|||
if len(c.inputBuffer) > poseidon.SPONGE_RATE { |
|||
fmt.Println(len(c.inputBuffer)) |
|||
panic("something went wrong") |
|||
} |
|||
|
|||
glApi := gl.NewChip(c.api) |
|||
|
|||
for i := 0; i < len(c.inputBuffer); i++ { |
|||
c.spongeState[i] = glApi.Reduce(c.inputBuffer[i]) |
|||
} |
|||
c.inputBuffer = clearBuffer(c.inputBuffer) |
|||
c.spongeState = c.poseidonChip.Poseidon(c.spongeState) |
|||
clearBuffer(c.outputBuffer) |
|||
for i := 0; i < poseidon.SPONGE_RATE; i++ { |
|||
c.outputBuffer = append(c.outputBuffer, c.spongeState[i]) |
|||
} |
|||
} |
|||
@ -1,183 +0,0 @@ |
|||
package field |
|||
|
|||
import ( |
|||
"fmt" |
|||
"math/big" |
|||
|
|||
"github.com/consensys/gnark-crypto/ecc" |
|||
"github.com/consensys/gnark-crypto/field/goldilocks" |
|||
"github.com/consensys/gnark/constraint/solver" |
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/consensys/gnark/std/math/bits" |
|||
"github.com/consensys/gnark/std/math/emulated" |
|||
) |
|||
|
|||
type EmulatedField = emulated.Goldilocks |
|||
type F = *emulated.Element[EmulatedField] |
|||
type FieldAPI = *emulated.Field[emulated.Goldilocks] |
|||
|
|||
var TEST_CURVE = ecc.BN254 |
|||
|
|||
func NewFieldAPI(api frontend.API) FieldAPI { |
|||
fieldAPI, err := emulated.NewField[EmulatedField](api) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
return fieldAPI |
|||
} |
|||
|
|||
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) |
|||
var GOLDILOCKS_POWER_OF_TWO_GENERATOR = goldilocks.NewElement(1753635133440165772) |
|||
var GOLDILOCKS_MODULUS = EmulatedField{}.Modulus() |
|||
|
|||
func GoldilocksPrimitiveRootOfUnity(nLog uint64) goldilocks.Element { |
|||
if nLog > GOLDILOCKS_TWO_ADICITY { |
|||
panic("nLog is greater than GOLDILOCKS_TWO_ADICITY") |
|||
} |
|||
|
|||
res := goldilocks.NewElement(GOLDILOCKS_POWER_OF_TWO_GENERATOR.Uint64()) |
|||
for i := 0; i < int(GOLDILOCKS_TWO_ADICITY-nLog); i++ { |
|||
res.Square(&res) |
|||
} |
|||
|
|||
return res |
|||
} |
|||
|
|||
func TwoAdicSubgroup(nLog uint64) []goldilocks.Element { |
|||
if nLog > GOLDILOCKS_TWO_ADICITY { |
|||
panic("nLog is greater than GOLDILOCKS_TWO_ADICITY") |
|||
} |
|||
|
|||
var res []goldilocks.Element |
|||
rootOfUnity := GoldilocksPrimitiveRootOfUnity(nLog) |
|||
res = append(res, goldilocks.NewElement(1)) |
|||
|
|||
for i := 0; i < (1 << nLog); i++ { |
|||
lastElement := res[len(res)-1] |
|||
res = append(res, *lastElement.Mul(&lastElement, &rootOfUnity)) |
|||
} |
|||
|
|||
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 |
|||
|
|||
} |
|||
|
|||
func init() { |
|||
// register hints
|
|||
solver.RegisterHint(GoldilocksMulAddHint) |
|||
} |
|||
|
|||
func GoldilocksRangeCheck(api frontend.API, x frontend.Variable) { |
|||
// Goldilocks' modulus is 2^64 - 2^32 + 1,
|
|||
// which is "1111111111111111111111111111111100000000000000000000000000000001' in big endian binary
|
|||
// This function will first verify that x is at most 64 bits wide.
|
|||
// Then it checks that if the bits[0:31] (in big-endian) are all 1, then bits[32:64] are all zero
|
|||
|
|||
// First decompose x into 64 bits. The bits will be in little-endian order.
|
|||
bits := bits.ToBinary(api, x, bits.WithNbDigits(64)) |
|||
|
|||
// Those bits should compose back to x
|
|||
reconstructedX := frontend.Variable(0) |
|||
c := uint64(1) |
|||
for i := 0; i < 64; i++ { |
|||
reconstructedX = api.Add(reconstructedX, api.Mul(bits[i], c)) |
|||
c = c << 1 |
|||
api.AssertIsBoolean(bits[i]) |
|||
} |
|||
api.AssertIsEqual(x, reconstructedX) |
|||
|
|||
mostSigBits32Sum := frontend.Variable(0) |
|||
for i := 32; i < 64; i++ { |
|||
mostSigBits32Sum = api.Add(mostSigBits32Sum, bits[i]) |
|||
} |
|||
|
|||
leastSigBits32Sum := frontend.Variable(0) |
|||
for i := 0; i < 32; i++ { |
|||
leastSigBits32Sum = api.Add(leastSigBits32Sum, bits[i]) |
|||
} |
|||
|
|||
// If mostSigBits32Sum < 32, then we know that x < (2^63 + ... + 2^32 + 0 * 2^31 + ... + 0 * 2^0), which equals to 2^64 - 2^32
|
|||
// So in that case, we don't need to do any more checks.
|
|||
// If mostSigBits32Sum == 32, then we need to check that x == 2^64 - 2^32 (max GL value)
|
|||
shouldCheck := api.IsZero(api.Sub(mostSigBits32Sum, 32)) |
|||
api.AssertIsEqual( |
|||
api.Select( |
|||
shouldCheck, |
|||
leastSigBits32Sum, |
|||
frontend.Variable(0), |
|||
), |
|||
frontend.Variable(0), |
|||
) |
|||
} |
|||
|
|||
// Calculates operands[0] * operands[1] + operands[2]
|
|||
// This function assumes that all operands are within goldilocks, and will panic otherwise
|
|||
// It will ensure that the result is within goldilocks
|
|||
func GoldilocksMulAdd(api frontend.API, operand1, operand2, operand3 frontend.Variable) frontend.Variable { |
|||
result, err := api.Compiler().NewHint(GoldilocksMulAddHint, 2, operand1, operand2, operand3) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
quotient := result[0] |
|||
remainder := result[1] |
|||
|
|||
// Verify the calculated value
|
|||
lhs := api.Mul(operand1, operand2) |
|||
lhs = api.Add(lhs, operand3) |
|||
rhs := api.Add(api.Mul(quotient, GOLDILOCKS_MODULUS), remainder) |
|||
api.AssertIsEqual(lhs, rhs) |
|||
|
|||
GoldilocksRangeCheck(api, quotient) |
|||
GoldilocksRangeCheck(api, remainder) |
|||
|
|||
return remainder |
|||
} |
|||
|
|||
func GoldilocksMulAddHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { |
|||
if len(inputs) != 3 { |
|||
panic("GoldilocksMulAddHint expects 3 input operands") |
|||
} |
|||
|
|||
for _, operand := range inputs { |
|||
if operand.Cmp(GOLDILOCKS_MODULUS) >= 0 { |
|||
panic(fmt.Sprintf("%s is not in the field", operand.String())) |
|||
} |
|||
} |
|||
|
|||
product := new(big.Int).Mul(inputs[0], inputs[1]) |
|||
sum := new(big.Int).Add(product, inputs[2]) |
|||
quotient := new(big.Int).Div(sum, GOLDILOCKS_MODULUS) |
|||
remainder := new(big.Int).Rem(sum, GOLDILOCKS_MODULUS) |
|||
|
|||
results[0] = quotient |
|||
results[1] = remainder |
|||
|
|||
return nil |
|||
} |
|||
@ -1,289 +0,0 @@ |
|||
package field |
|||
|
|||
import ( |
|||
"math/bits" |
|||
|
|||
"github.com/consensys/gnark-crypto/field/goldilocks" |
|||
"github.com/consensys/gnark/frontend" |
|||
) |
|||
|
|||
const D = 2 |
|||
|
|||
type QuadraticExtension = [2]F |
|||
type QEAlgebra = [D]QuadraticExtension |
|||
|
|||
type QuadraticExtensionAPI struct { |
|||
api frontend.API |
|||
fieldAPI FieldAPI |
|||
|
|||
W F |
|||
DTH_ROOT F |
|||
|
|||
ONE_QE QuadraticExtension |
|||
ZERO_QE QuadraticExtension |
|||
|
|||
ZERO_QE_ALGEBRA QEAlgebra |
|||
} |
|||
|
|||
func NewQuadraticExtensionAPI(api frontend.API, fieldAPI FieldAPI) *QuadraticExtensionAPI { |
|||
var ZERO_QE = QuadraticExtension{ZERO_F, ZERO_F} |
|||
|
|||
var ZERO_QE_ALGEBRA QEAlgebra |
|||
|
|||
for i := 0; i < D; i++ { |
|||
ZERO_QE_ALGEBRA[i] = ZERO_QE |
|||
} |
|||
|
|||
return &QuadraticExtensionAPI{ |
|||
api: api, |
|||
fieldAPI: fieldAPI, |
|||
|
|||
W: NewFieldConst(7), |
|||
DTH_ROOT: NewFieldConst(18446744069414584320), |
|||
|
|||
ONE_QE: QuadraticExtension{ONE_F, ZERO_F}, |
|||
ZERO_QE: ZERO_QE, |
|||
|
|||
ZERO_QE_ALGEBRA: ZERO_QE_ALGEBRA, |
|||
} |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) SquareExtension(a QuadraticExtension) QuadraticExtension { |
|||
return c.MulExtension(a, a) |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) MulExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension { |
|||
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]) |
|||
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]) |
|||
c_1 := c.fieldAPI.Sub(a[1], b[1]) |
|||
return QuadraticExtension{c_0, c_1} |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) DivExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension { |
|||
return c.MulExtension(a, c.InverseExtension(b)) |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) IsZero(a QuadraticExtension) frontend.Variable { |
|||
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 := 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.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)} |
|||
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])) |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) ScalarMulExtension(a QuadraticExtension, scalar F) QuadraticExtension { |
|||
return QuadraticExtension{c.fieldAPI.Mul(a[0], scalar), c.fieldAPI.Mul(a[1], scalar)} |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) VarToQE(a frontend.Variable) QuadraticExtension { |
|||
return c.FieldToQE(c.fieldAPI.NewElement(a)) |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) FieldToQE(a F) QuadraticExtension { |
|||
return QuadraticExtension{a, ZERO_F} |
|||
} |
|||
|
|||
// / Exponentiate `base` to the power of a known `exponent`.
|
|||
func (c *QuadraticExtensionAPI) ExpU64Extension(a QuadraticExtension, exponent uint64) QuadraticExtension { |
|||
switch exponent { |
|||
case 0: |
|||
return c.ONE_QE |
|||
case 1: |
|||
return a |
|||
case 2: |
|||
return c.SquareExtension(a) |
|||
default: |
|||
} |
|||
|
|||
current := a |
|||
product := c.ONE_QE |
|||
|
|||
for i := 0; i < bits.Len64(exponent); i++ { |
|||
if i != 0 { |
|||
current = c.SquareExtension(current) |
|||
} |
|||
|
|||
if (exponent >> i & 1) != 0 { |
|||
product = c.MulExtension(product, current) |
|||
} |
|||
} |
|||
|
|||
return product |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) ReduceWithPowers(terms []QuadraticExtension, scalar QuadraticExtension) QuadraticExtension { |
|||
sum := c.ZERO_QE |
|||
|
|||
for i := len(terms) - 1; i >= 0; i-- { |
|||
sum = c.AddExtension( |
|||
c.MulExtension( |
|||
sum, |
|||
scalar, |
|||
), |
|||
terms[i], |
|||
) |
|||
} |
|||
|
|||
return sum |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) Select(b frontend.Variable, qe0, qe1 QuadraticExtension) QuadraticExtension { |
|||
var retQE QuadraticExtension |
|||
|
|||
for i := 0; i < 2; i++ { |
|||
retQE[i] = c.fieldAPI.Select(b, qe0[i], qe1[i]) |
|||
} |
|||
|
|||
return retQE |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) Lookup2(b0 frontend.Variable, b1 frontend.Variable, qe0, qe1, qe2, qe3 QuadraticExtension) QuadraticExtension { |
|||
var retQE QuadraticExtension |
|||
|
|||
for i := 0; i < 2; i++ { |
|||
retQE[i] = c.fieldAPI.Lookup2(b0, b1, qe0[i], qe1[i], qe2[i], qe3[i]) |
|||
} |
|||
|
|||
return retQE |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) AssertIsEqual(a, b QuadraticExtension) { |
|||
for i := 0; i < 2; i++ { |
|||
c.fieldAPI.AssertIsEqual(a[i], b[i]) |
|||
} |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) InnerProductExtension(constant F, startingAcc QuadraticExtension, pairs [][2]QuadraticExtension) QuadraticExtension { |
|||
acc := startingAcc |
|||
|
|||
for i := 0; i < len(pairs); i++ { |
|||
a := pairs[i][0] |
|||
b := pairs[i][1] |
|||
mul := c.ScalarMulExtension(a, constant) |
|||
mul = c.MulExtension(mul, b) |
|||
acc = c.AddExtension(acc, mul) |
|||
} |
|||
|
|||
return acc |
|||
} |
|||
|
|||
/* |
|||
func (c *QuadraticExtensionAPI) Println(a QuadraticExtension) { |
|||
fmt.Print("Degree 0 coefficient") |
|||
c.fieldAPI.Println(a[0]) |
|||
|
|||
fmt.Print("Degree 1 coefficient") |
|||
c.fieldAPI.Println(a[1]) |
|||
} |
|||
*/ |
|||
|
|||
func (c *QuadraticExtensionAPI) MulExtensionAlgebra(a, b QEAlgebra) QEAlgebra { |
|||
var inner [D][][2]QuadraticExtension |
|||
var inner_w [D][][2]QuadraticExtension |
|||
for i := 0; i < D; i++ { |
|||
for j := 0; j < D-i; j++ { |
|||
idx := (i + j) % D |
|||
inner[idx] = append(inner[idx], [2]QuadraticExtension{a[i], b[j]}) |
|||
} |
|||
for j := D - i; j < D; j++ { |
|||
idx := (i + j) % D |
|||
inner_w[idx] = append(inner_w[idx], [2]QuadraticExtension{a[i], b[j]}) |
|||
} |
|||
} |
|||
|
|||
var product QEAlgebra |
|||
for i := 0; i < D; i++ { |
|||
acc := c.InnerProductExtension(c.W, c.ZERO_QE, inner_w[i]) |
|||
product[i] = c.InnerProductExtension(ONE_F, acc, inner[i]) |
|||
} |
|||
|
|||
return product |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) ScalarMulExtensionAlgebra(a QuadraticExtension, b QEAlgebra) QEAlgebra { |
|||
var product QEAlgebra |
|||
for i := 0; i < D; i++ { |
|||
product[i] = c.MulExtension(a, b[i]) |
|||
} |
|||
|
|||
return product |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) AddExtensionAlgebra(a, b QEAlgebra) QEAlgebra { |
|||
var sum QEAlgebra |
|||
for i := 0; i < D; i++ { |
|||
sum[i] = c.AddExtension(a[i], b[i]) |
|||
} |
|||
|
|||
return sum |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) SubExtensionAlgebra(a, b QEAlgebra) QEAlgebra { |
|||
var diff QEAlgebra |
|||
for i := 0; i < D; i++ { |
|||
diff[i] = c.SubExtension(a[i], b[i]) |
|||
} |
|||
|
|||
return diff |
|||
} |
|||
|
|||
func (c *QuadraticExtensionAPI) PartialInterpolateExtAlgebra( |
|||
domain []goldilocks.Element, |
|||
values []QEAlgebra, |
|||
barycentricWeights []goldilocks.Element, |
|||
point QEAlgebra, |
|||
initialEval QEAlgebra, |
|||
initialPartialProd QEAlgebra, |
|||
) (QEAlgebra, QEAlgebra) { |
|||
n := len(values) |
|||
if n == 0 { |
|||
panic("Cannot interpolate with no values") |
|||
} |
|||
if n != len(domain) { |
|||
panic("Domain and values must have the same length") |
|||
} |
|||
if n != len(barycentricWeights) { |
|||
panic("Domain and barycentric weights must have the same length") |
|||
} |
|||
|
|||
newEval := initialEval |
|||
newPartialProd := initialPartialProd |
|||
for i := 0; i < n; i++ { |
|||
val := values[i] |
|||
x := domain[i] |
|||
xField := NewFieldConst(x.Uint64()) |
|||
xQE := QuadraticExtension{xField, ZERO_F} |
|||
xQEAlgebra := QEAlgebra{xQE, c.ZERO_QE} |
|||
weight := QuadraticExtension{NewFieldConst(barycentricWeights[i].Uint64()), ZERO_F} |
|||
term := c.SubExtensionAlgebra(point, xQEAlgebra) |
|||
weightedVal := c.ScalarMulExtensionAlgebra(weight, val) |
|||
newEval = c.MulExtensionAlgebra(newEval, term) |
|||
tmp := c.MulExtensionAlgebra(weightedVal, newPartialProd) |
|||
newEval = c.AddExtensionAlgebra(newEval, tmp) |
|||
newPartialProd = c.MulExtensionAlgebra(newPartialProd, term) |
|||
} |
|||
|
|||
return newEval, newPartialProd |
|||
} |
|||
@ -1,77 +0,0 @@ |
|||
package field |
|||
|
|||
import ( |
|||
"testing" |
|||
|
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/consensys/gnark/test" |
|||
) |
|||
|
|||
// TODO: ADD MORE TEST CASES!!!
|
|||
|
|||
// Test for quadratic extension multiplication
|
|||
type TestQuadraticExtensionMulCircuit struct { |
|||
qeAPI *QuadraticExtensionAPI |
|||
|
|||
Operand1 QuadraticExtension |
|||
Operand2 QuadraticExtension |
|||
ExpectedResult QuadraticExtension |
|||
} |
|||
|
|||
func (c *TestQuadraticExtensionMulCircuit) Define(api frontend.API) error { |
|||
fieldAPI := NewFieldAPI(api) |
|||
c.qeAPI = NewQuadraticExtensionAPI(api, fieldAPI) |
|||
|
|||
actualRes := c.qeAPI.MulExtension(c.Operand1, c.Operand2) |
|||
|
|||
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{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} |
|||
err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField()) |
|||
assert.NoError(err) |
|||
} |
|||
|
|||
// Test for quadratic extension division
|
|||
type TestQuadraticExtensionDivCircuit struct { |
|||
qeAPI *QuadraticExtensionAPI |
|||
|
|||
Operand1 QuadraticExtension |
|||
Operand2 QuadraticExtension |
|||
ExpectedResult QuadraticExtension |
|||
} |
|||
|
|||
func (c *TestQuadraticExtensionDivCircuit) Define(api frontend.API) error { |
|||
fieldAPI := NewFieldAPI(api) |
|||
c.qeAPI = NewQuadraticExtensionAPI(api, fieldAPI) |
|||
|
|||
actualRes := c.qeAPI.DivExtension(c.Operand1, c.Operand2) |
|||
|
|||
fieldAPI.AssertIsEqual(actualRes[0], c.ExpectedResult[0]) |
|||
fieldAPI.AssertIsEqual(actualRes[1], c.ExpectedResult[1]) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func TestQuadraticExtensionDiv(t *testing.T) { |
|||
assert := test.NewAssert(t) |
|||
|
|||
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} |
|||
err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField()) |
|||
assert.NoError(err) |
|||
} |
|||
@ -0,0 +1,126 @@ |
|||
package fri_test |
|||
|
|||
import ( |
|||
"testing" |
|||
|
|||
"github.com/consensys/gnark-crypto/ecc" |
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/consensys/gnark/test" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/challenger" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/fri" |
|||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/types" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier" |
|||
) |
|||
|
|||
type TestFriCircuit struct { |
|||
proofWithPIsFilename string `gnark:"-"` |
|||
commonCircuitDataFilename string `gnark:"-"` |
|||
verifierOnlyCircuitDataFilename string `gnark:"-"` |
|||
} |
|||
|
|||
func (circuit *TestFriCircuit) Define(api frontend.API) error { |
|||
proofWithPis := verifier.DeserializeProofWithPublicInputs(circuit.proofWithPIsFilename) |
|||
commonCircuitData := verifier.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename) |
|||
verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuit.verifierOnlyCircuitDataFilename) |
|||
|
|||
glApi := gl.NewChip(api) |
|||
poseidonChip := poseidon.NewGoldilocksChip(api) |
|||
friChip := fri.NewChip(api, &commonCircuitData.FriParams) |
|||
challengerChip := challenger.NewChip(api) |
|||
|
|||
challengerChip.ObserveBN254Hash(verifierOnlyCircuitData.CircuitDigest) |
|||
challengerChip.ObserveHash(poseidonChip.HashNoPad(proofWithPis.PublicInputs)) |
|||
challengerChip.ObserveCap(proofWithPis.Proof.WiresCap) |
|||
plonkBetas := challengerChip.GetNChallenges(commonCircuitData.Config.NumChallenges) // For plonk betas
|
|||
glApi.AssertIsEqual(plonkBetas[0], gl.NewVariable("17615363392879944733")) |
|||
plonkGammas := challengerChip.GetNChallenges(commonCircuitData.Config.NumChallenges) // For plonk gammas
|
|||
glApi.AssertIsEqual(plonkGammas[0], gl.NewVariable("15174493176564484303")) |
|||
|
|||
challengerChip.ObserveCap(proofWithPis.Proof.PlonkZsPartialProductsCap) |
|||
plonkAlphas := challengerChip.GetNChallenges(commonCircuitData.Config.NumChallenges) // For plonk alphas
|
|||
glApi.AssertIsEqual(plonkAlphas[0], gl.NewVariable("9276470834414745550")) |
|||
|
|||
challengerChip.ObserveCap(proofWithPis.Proof.QuotientPolysCap) |
|||
plonkZeta := challengerChip.GetExtensionChallenge() |
|||
glApi.AssertIsEqual(plonkZeta[0], gl.NewVariable("3892795992421241388")) |
|||
|
|||
challengerChip.ObserveOpenings(fri.ToOpenings(proofWithPis.Proof.Openings)) |
|||
|
|||
friChallenges := challengerChip.GetFriChallenges( |
|||
proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps, |
|||
proofWithPis.Proof.OpeningProof.FinalPoly, |
|||
proofWithPis.Proof.OpeningProof.PowWitness, |
|||
commonCircuitData.DegreeBits, |
|||
commonCircuitData.Config.FriConfig, |
|||
) |
|||
|
|||
api.AssertIsEqual(friChallenges.FriAlpha[0].Limb, 885535811531859621) |
|||
|
|||
api.AssertIsEqual(friChallenges.FriBetas[0][0].Limb, 5231781384587895507) |
|||
|
|||
api.AssertIsEqual(friChallenges.FriPowResponse.Limb, 70715523064019) |
|||
|
|||
// glApi.AssertIsEqual(friChallenges.FriQueryIndices[0], gl.NewVariableFromConst(11890500485816111017))
|
|||
var x uint64 |
|||
x = 11890500485816111017 |
|||
api.AssertIsEqual(friChallenges.FriQueryIndices[0].Limb, x) |
|||
|
|||
initialMerkleCaps := []types.FriMerkleCap{ |
|||
verifierOnlyCircuitData.ConstantSigmasCap, |
|||
proofWithPis.Proof.WiresCap, |
|||
proofWithPis.Proof.PlonkZsPartialProductsCap, |
|||
proofWithPis.Proof.QuotientPolysCap, |
|||
} |
|||
|
|||
// Seems like there is a bug in the emulated field code.
|
|||
// Add ZERO to all of the fri challenges values to reduce them.
|
|||
plonkZeta[0] = glApi.Add(plonkZeta[0], gl.Zero()) |
|||
plonkZeta[1] = glApi.Add(plonkZeta[1], gl.Zero()) |
|||
|
|||
friChallenges.FriAlpha[0] = glApi.Add(friChallenges.FriAlpha[0], gl.Zero()) |
|||
friChallenges.FriAlpha[1] = glApi.Add(friChallenges.FriAlpha[1], gl.Zero()) |
|||
|
|||
for i := 0; i < len(friChallenges.FriBetas); i++ { |
|||
friChallenges.FriBetas[i][0] = glApi.Add(friChallenges.FriBetas[i][0], gl.Zero()) |
|||
friChallenges.FriBetas[i][1] = glApi.Add(friChallenges.FriBetas[i][1], gl.Zero()) |
|||
} |
|||
|
|||
friChallenges.FriPowResponse = glApi.Add(friChallenges.FriPowResponse, gl.Zero()) |
|||
|
|||
for i := 0; i < len(friChallenges.FriQueryIndices); i++ { |
|||
friChallenges.FriQueryIndices[i] = glApi.Add(friChallenges.FriQueryIndices[i], gl.Zero()) |
|||
} |
|||
|
|||
friChip.VerifyFriProof( |
|||
fri.GetInstance(&commonCircuitData, glApi, plonkZeta, commonCircuitData.DegreeBits), |
|||
fri.ToOpenings(proofWithPis.Proof.Openings), |
|||
&friChallenges, |
|||
initialMerkleCaps, |
|||
&proofWithPis.Proof.OpeningProof, |
|||
) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func TestDecodeBlockFriVerification(t *testing.T) { |
|||
assert := test.NewAssert(t) |
|||
|
|||
testCase := func() { |
|||
circuit := TestFriCircuit{ |
|||
proofWithPIsFilename: "../../data/decode_block/proof_with_public_inputs.json", |
|||
commonCircuitDataFilename: "../../data/decode_block//common_circuit_data.json", |
|||
verifierOnlyCircuitDataFilename: "../../data/decode_block//verifier_only_circuit_data.json", |
|||
} |
|||
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", |
|||
} |
|||
err := test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField()) |
|||
assert.NoError(err) |
|||
} |
|||
|
|||
testCase() |
|||
} |
|||
@ -0,0 +1,362 @@ |
|||
// This package implements efficient Golidlocks arithmetic operations within Gnark. We do not use
|
|||
// the emulated field arithmetic API, because it is too slow for our purposes. Instead, we use
|
|||
// an efficient reduction method that leverages the fact that the modulus is a simple
|
|||
// linear combination of powers of two.
|
|||
package goldilocks |
|||
|
|||
// In general, methods whose name do not contain `NoReduce` can be used without any extra mental
|
|||
// overhead. These methods act exactly as you would expect a normal field would operate.
|
|||
//
|
|||
// However, if you want to aggressively optimize the number of constraints in your circuit, it can
|
|||
// be very beneficial to use the no reduction methods and keep track of the maximum number of bits
|
|||
// your computation uses.
|
|||
|
|||
import ( |
|||
"fmt" |
|||
"math/big" |
|||
|
|||
"github.com/consensys/gnark-crypto/field/goldilocks" |
|||
"github.com/consensys/gnark/constraint/solver" |
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/consensys/gnark/std/math/bits" |
|||
"github.com/consensys/gnark/std/math/emulated" |
|||
) |
|||
|
|||
// The multiplicative group generator of the field.
|
|||
var MULTIPLICATIVE_GROUP_GENERATOR goldilocks.Element = goldilocks.NewElement(7) |
|||
|
|||
// The two adicity of the field.
|
|||
var TWO_ADICITY uint64 = 32 |
|||
|
|||
// The power of two generator of the field.
|
|||
var POWER_OF_TWO_GENERATOR goldilocks.Element = goldilocks.NewElement(1753635133440165772) |
|||
|
|||
// The modulus of the field.
|
|||
var MODULUS *big.Int = emulated.Goldilocks{}.Modulus() |
|||
|
|||
// The threshold maximum number of bits at which we must reduce the element.
|
|||
var REDUCE_NB_BITS_THRESHOLD uint8 = 254 - 64 |
|||
|
|||
// The number of bits to use for range checks on inner products of field elements.
|
|||
var RANGE_CHECK_NB_BITS int = 140 |
|||
|
|||
// Registers the hint functions with the solver.
|
|||
func init() { |
|||
solver.RegisterHint(MulAddHint) |
|||
solver.RegisterHint(ReduceHint) |
|||
solver.RegisterHint(InverseHint) |
|||
} |
|||
|
|||
// A type alias used to represent Goldilocks field elements.
|
|||
type Variable struct { |
|||
Limb frontend.Variable |
|||
} |
|||
|
|||
// Creates a new Goldilocks field element from an existing variable. Assumes that the element is
|
|||
// already reduced.
|
|||
func NewVariable(x frontend.Variable) Variable { |
|||
return Variable{Limb: x} |
|||
} |
|||
|
|||
// The zero element in the Golidlocks field.
|
|||
func Zero() Variable { |
|||
return NewVariable(0) |
|||
} |
|||
|
|||
// The one element in the Goldilocks field.
|
|||
func One() Variable { |
|||
return NewVariable(1) |
|||
} |
|||
|
|||
// The negative one element in the Goldilocks field.
|
|||
func NegOne() Variable { |
|||
return NewVariable(MODULUS.Uint64() - 1) |
|||
} |
|||
|
|||
// The chip used for Goldilocks field operations.
|
|||
type Chip struct { |
|||
api frontend.API |
|||
} |
|||
|
|||
// Creates a new Goldilocks chip.
|
|||
func NewChip(api frontend.API) *Chip { |
|||
return &Chip{api: api} |
|||
} |
|||
|
|||
// Adds two field elements such that x + y = z within the Golidlocks field.
|
|||
func (p *Chip) Add(a Variable, b Variable) Variable { |
|||
return p.MulAdd(a, NewVariable(1), b) |
|||
} |
|||
|
|||
// Adds two field elements such that x + y = z within the Golidlocks field without reducing.
|
|||
func (p *Chip) AddNoReduce(a Variable, b Variable) Variable { |
|||
return NewVariable(p.api.Add(a.Limb, b.Limb)) |
|||
} |
|||
|
|||
// Subtracts two field elements such that x + y = z within the Golidlocks field.
|
|||
func (p *Chip) Sub(a Variable, b Variable) Variable { |
|||
return p.MulAdd(b, NewVariable(MODULUS.Uint64()-1), a) |
|||
} |
|||
|
|||
// Subtracts two field elements such that x + y = z within the Golidlocks field without reducing.
|
|||
func (p *Chip) SubNoReduce(a Variable, b Variable) Variable { |
|||
return NewVariable(p.api.Add(a.Limb, p.api.Mul(b.Limb, MODULUS.Uint64()-1))) |
|||
} |
|||
|
|||
// Multiplies two field elements such that x * y = z within the Golidlocks field.
|
|||
func (p *Chip) Mul(a Variable, b Variable) Variable { |
|||
return p.MulAdd(a, b, Zero()) |
|||
} |
|||
|
|||
// Multiplies two field elements such that x * y = z within the Golidlocks field without reducing.
|
|||
func (p *Chip) MulNoReduce(a Variable, b Variable) Variable { |
|||
return NewVariable(p.api.Mul(a.Limb, b.Limb)) |
|||
} |
|||
|
|||
// Multiplies two field elements and adds a field element such that x * y + z = c within the
|
|||
// Golidlocks field.
|
|||
func (p *Chip) MulAdd(a Variable, b Variable, c Variable) Variable { |
|||
result, err := p.api.Compiler().NewHint(MulAddHint, 2, a.Limb, b.Limb, c.Limb) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
quotient := NewVariable(result[0]) |
|||
remainder := NewVariable(result[1]) |
|||
|
|||
lhs := p.api.Mul(a.Limb, b.Limb) |
|||
lhs = p.api.Add(lhs, c.Limb) |
|||
rhs := p.api.Add(p.api.Mul(quotient.Limb, MODULUS), remainder.Limb) |
|||
p.api.AssertIsEqual(lhs, rhs) |
|||
|
|||
p.RangeCheck(quotient) |
|||
p.RangeCheck(remainder) |
|||
return remainder |
|||
} |
|||
|
|||
// Multiplies two field elements and adds a field element such that x * y + z = c within the
|
|||
// Golidlocks field without reducing.
|
|||
func (p *Chip) MulAddNoReduce(a Variable, b Variable, c Variable) Variable { |
|||
return p.AddNoReduce(p.MulNoReduce(a, b), c) |
|||
} |
|||
|
|||
// The hint used to compute MulAdd.
|
|||
func MulAddHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { |
|||
if len(inputs) != 3 { |
|||
panic("MulAddHint expects 3 input operands") |
|||
} |
|||
|
|||
for _, operand := range inputs { |
|||
if operand.Cmp(MODULUS) >= 0 { |
|||
panic(fmt.Sprintf("%s is not in the field", operand.String())) |
|||
} |
|||
} |
|||
|
|||
product := new(big.Int).Mul(inputs[0], inputs[1]) |
|||
sum := new(big.Int).Add(product, inputs[2]) |
|||
quotient := new(big.Int).Div(sum, MODULUS) |
|||
remainder := new(big.Int).Rem(sum, MODULUS) |
|||
|
|||
results[0] = quotient |
|||
results[1] = remainder |
|||
|
|||
return nil |
|||
} |
|||
|
|||
// Reduces a field element x such that x % MODULUS = y.
|
|||
func (p *Chip) Reduce(x Variable) Variable { |
|||
// Witness a `quotient` and `remainder` such that:
|
|||
//
|
|||
// MODULUS * quotient + remainder = x
|
|||
//
|
|||
// Must check that offset \in [0, MODULUS) and carry \in [0, 2^RANGE_CHECK_NB_BITS) to ensure
|
|||
// that this computation does not overflow. We use 2^RANGE_CHECK_NB_BITS to reduce the cost of the range check
|
|||
//
|
|||
// In other words, we assume that we at most compute a a dot product with dimension at most RANGE_CHECK_NB_BITS - 128.
|
|||
|
|||
result, err := p.api.Compiler().NewHint(ReduceHint, 2, x.Limb) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
quotient := result[0] |
|||
rangeCheckNbBits := RANGE_CHECK_NB_BITS |
|||
p.api.ToBinary(quotient, rangeCheckNbBits) |
|||
|
|||
remainder := NewVariable(result[1]) |
|||
p.RangeCheck(remainder) |
|||
return remainder |
|||
} |
|||
|
|||
// Reduces a field element x such that x % MODULUS = y.
|
|||
func (p *Chip) ReduceWithMaxBits(x Variable, maxNbBits uint64) Variable { |
|||
// Witness a `quotient` and `remainder` such that:
|
|||
//
|
|||
// MODULUS * quotient + remainder = x
|
|||
//
|
|||
// Must check that remainder \in [0, MODULUS) and quotient \in [0, 2^maxNbBits) to ensure that this
|
|||
// computation does not overflow.
|
|||
|
|||
result, err := p.api.Compiler().NewHint(ReduceHint, 2, x.Limb) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
quotient := result[0] |
|||
p.api.ToBinary(quotient, int(maxNbBits)) |
|||
|
|||
remainder := NewVariable(result[1]) |
|||
p.RangeCheck(remainder) |
|||
return remainder |
|||
} |
|||
|
|||
// The hint used to compute Reduce.
|
|||
func ReduceHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { |
|||
if len(inputs) != 1 { |
|||
panic("ReduceHint expects 1 input operand") |
|||
} |
|||
input := inputs[0] |
|||
quotient := new(big.Int).Div(input, MODULUS) |
|||
remainder := new(big.Int).Rem(input, MODULUS) |
|||
results[0] = quotient |
|||
results[1] = remainder |
|||
return nil |
|||
} |
|||
|
|||
// Computes the inverse of a field element x such that x * x^-1 = 1.
|
|||
func (p *Chip) Inverse(x Variable) Variable { |
|||
result, err := p.api.Compiler().NewHint(InverseHint, 1, x.Limb) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
inverse := NewVariable(result[0]) |
|||
product := p.Mul(inverse, x) |
|||
p.api.AssertIsEqual(product.Limb, frontend.Variable(1)) |
|||
return inverse |
|||
} |
|||
|
|||
// The hint used to compute Inverse.
|
|||
func InverseHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { |
|||
if len(inputs) != 1 { |
|||
panic("InverseHint expects 1 input operand") |
|||
} |
|||
|
|||
input := inputs[0] |
|||
if input.Cmp(MODULUS) == 0 || input.Cmp(MODULUS) == 1 { |
|||
panic("Input is not in the field") |
|||
} |
|||
|
|||
inputGl := goldilocks.NewElement(input.Uint64()) |
|||
resultGl := goldilocks.NewElement(0) |
|||
resultGl.Inverse(&inputGl) |
|||
|
|||
result := big.NewInt(0) |
|||
results[0] = resultGl.BigInt(result) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
// Computes a field element raised to some power.
|
|||
func (p *Chip) Exp(x Variable, k *big.Int) Variable { |
|||
if k.IsUint64() && k.Uint64() == 0 { |
|||
return One() |
|||
} |
|||
|
|||
e := k |
|||
if k.Sign() == -1 { |
|||
panic("Unsupported negative exponent. Need to implement inversion.") |
|||
} |
|||
|
|||
z := x |
|||
for i := e.BitLen() - 2; i >= 0; i-- { |
|||
z = p.Mul(z, z) |
|||
if e.Bit(i) == 1 { |
|||
z = p.Mul(z, x) |
|||
} |
|||
} |
|||
|
|||
return z |
|||
} |
|||
|
|||
// Range checks a field element x to be less than the Golidlocks modulus 2 ^ 64 - 2 ^ 32 + 1.
|
|||
func (p *Chip) RangeCheck(x Variable) { |
|||
// The Goldilocks' modulus is 2^64 - 2^32 + 1, which is:
|
|||
//
|
|||
// 1111111111111111111111111111111100000000000000000000000000000001
|
|||
//
|
|||
// in big endian binary. This function will first verify that x is at most 64 bits wide. Then it
|
|||
// checks that if the bits[0:31] (in big-endian) are all 1, then bits[32:64] are all zero.
|
|||
|
|||
// First decompose x into 64 bits. The bits will be in little-endian order.
|
|||
bits := bits.ToBinary(p.api, x.Limb, bits.WithNbDigits(64)) |
|||
|
|||
// Those bits should compose back to x.
|
|||
reconstructedX := frontend.Variable(0) |
|||
c := uint64(1) |
|||
for i := 0; i < 64; i++ { |
|||
reconstructedX = p.api.Add(reconstructedX, p.api.Mul(bits[i], c)) |
|||
c = c << 1 |
|||
p.api.AssertIsBoolean(bits[i]) |
|||
} |
|||
p.api.AssertIsEqual(x.Limb, reconstructedX) |
|||
|
|||
mostSigBits32Sum := frontend.Variable(0) |
|||
for i := 32; i < 64; i++ { |
|||
mostSigBits32Sum = p.api.Add(mostSigBits32Sum, bits[i]) |
|||
} |
|||
|
|||
leastSigBits32Sum := frontend.Variable(0) |
|||
for i := 0; i < 32; i++ { |
|||
leastSigBits32Sum = p.api.Add(leastSigBits32Sum, bits[i]) |
|||
} |
|||
|
|||
// If mostSigBits32Sum < 32, then we know that:
|
|||
//
|
|||
// x < (2^63 + ... + 2^32 + 0 * 2^31 + ... + 0 * 2^0)
|
|||
//
|
|||
// which equals to 2^64 - 2^32. So in that case, we don't need to do any more checks. If
|
|||
// mostSigBits32Sum == 32, then we need to check that x == 2^64 - 2^32 (max GL value).
|
|||
shouldCheck := p.api.IsZero(p.api.Sub(mostSigBits32Sum, 32)) |
|||
p.api.AssertIsEqual( |
|||
p.api.Select( |
|||
shouldCheck, |
|||
leastSigBits32Sum, |
|||
frontend.Variable(0), |
|||
), |
|||
frontend.Variable(0), |
|||
) |
|||
} |
|||
|
|||
func (p *Chip) AssertIsEqual(x, y Variable) { |
|||
p.api.AssertIsEqual(x.Limb, y.Limb) |
|||
} |
|||
|
|||
// Computes the n'th primitive root of unity for the Goldilocks field.
|
|||
func PrimitiveRootOfUnity(nLog uint64) goldilocks.Element { |
|||
if nLog > TWO_ADICITY { |
|||
panic("nLog is greater than TWO_ADICITY") |
|||
} |
|||
res := goldilocks.NewElement(POWER_OF_TWO_GENERATOR.Uint64()) |
|||
for i := 0; i < int(TWO_ADICITY-nLog); i++ { |
|||
res.Square(&res) |
|||
} |
|||
return res |
|||
} |
|||
|
|||
func TwoAdicSubgroup(nLog uint64) []goldilocks.Element { |
|||
if nLog > TWO_ADICITY { |
|||
panic("nLog is greater than GOLDILOCKS_TWO_ADICITY") |
|||
} |
|||
|
|||
var res []goldilocks.Element |
|||
rootOfUnity := PrimitiveRootOfUnity(nLog) |
|||
res = append(res, goldilocks.NewElement(1)) |
|||
|
|||
for i := 0; i < (1 << nLog); i++ { |
|||
lastElement := res[len(res)-1] |
|||
res = append(res, *lastElement.Mul(&lastElement, &rootOfUnity)) |
|||
} |
|||
|
|||
return res |
|||
} |
|||
@ -0,0 +1,234 @@ |
|||
package goldilocks |
|||
|
|||
import ( |
|||
"math/bits" |
|||
|
|||
"github.com/consensys/gnark/frontend" |
|||
) |
|||
|
|||
const W uint64 = 7 |
|||
const DTH_ROOT uint64 = 18446744069414584320 |
|||
|
|||
type QuadraticExtensionVariable [2]Variable |
|||
|
|||
func NewQuadraticExtensionVariable(x Variable, y Variable) QuadraticExtensionVariable { |
|||
return QuadraticExtensionVariable{x, y} |
|||
} |
|||
|
|||
func (p Variable) ToQuadraticExtension() QuadraticExtensionVariable { |
|||
return NewQuadraticExtensionVariable(p, Zero()) |
|||
} |
|||
|
|||
func ZeroExtension() QuadraticExtensionVariable { |
|||
return Zero().ToQuadraticExtension() |
|||
} |
|||
|
|||
func OneExtension() QuadraticExtensionVariable { |
|||
return One().ToQuadraticExtension() |
|||
} |
|||
|
|||
// Adds two quadratic extension variables in the Goldilocks field.
|
|||
func (p *Chip) AddExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { |
|||
c0 := p.Add(a[0], b[0]) |
|||
c1 := p.Add(a[1], b[1]) |
|||
return NewQuadraticExtensionVariable(c0, c1) |
|||
} |
|||
|
|||
// Adds two quadratic extension variables in the Goldilocks field without reducing.
|
|||
func (p *Chip) AddExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { |
|||
c0 := p.AddNoReduce(a[0], b[0]) |
|||
c1 := p.AddNoReduce(a[1], b[1]) |
|||
return NewQuadraticExtensionVariable(c0, c1) |
|||
} |
|||
|
|||
// Subtracts two quadratic extension variables in the Goldilocks field.
|
|||
func (p *Chip) SubExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { |
|||
c0 := p.Sub(a[0], b[0]) |
|||
c1 := p.Sub(a[1], b[1]) |
|||
return NewQuadraticExtensionVariable(c0, c1) |
|||
} |
|||
|
|||
// Subtracts two quadratic extension variables in the Goldilocks field without reducing.
|
|||
func (p *Chip) SubExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { |
|||
c0 := p.SubNoReduce(a[0], b[0]) |
|||
c1 := p.SubNoReduce(a[1], b[1]) |
|||
return NewQuadraticExtensionVariable(c0, c1) |
|||
} |
|||
|
|||
// Multiplies quadratic extension variable in the Goldilocks field.
|
|||
func (p *Chip) MulExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { |
|||
product := p.MulExtensionNoReduce(a, b) |
|||
product[0] = p.Reduce(product[0]) |
|||
product[1] = p.Reduce(product[1]) |
|||
return product |
|||
} |
|||
|
|||
// Multiplies quadratic extension variable in the Goldilocks field without reducing.
|
|||
func (p *Chip) MulExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { |
|||
c0o0 := p.MulNoReduce(a[0], b[0]) |
|||
c0o1 := p.MulNoReduce(p.MulNoReduce(NewVariable(7), a[1]), b[1]) |
|||
c0 := p.AddNoReduce(c0o0, c0o1) |
|||
c1 := p.AddNoReduce(p.MulNoReduce(a[0], b[1]), p.MulNoReduce(a[1], b[0])) |
|||
return NewQuadraticExtensionVariable(c0, c1) |
|||
} |
|||
|
|||
// Multiplies two operands a and b and adds to c in the Goldilocks extension field. a * b + c must
|
|||
// be less than RANGE_CHECK_NB_BITS bits.
|
|||
func (p *Chip) MulAddExtension(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { |
|||
product := p.MulExtensionNoReduce(a, b) |
|||
sum := p.AddExtensionNoReduce(product, c) |
|||
sum[0] = p.Reduce(sum[0]) |
|||
sum[1] = p.Reduce(sum[1]) |
|||
return sum |
|||
} |
|||
|
|||
func (p *Chip) MulAddExtensionNoReduce(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { |
|||
product := p.MulExtensionNoReduce(a, b) |
|||
sum := p.AddExtensionNoReduce(product, c) |
|||
return sum |
|||
} |
|||
|
|||
// Multiplies two operands a and b and subtracts to c in the Goldilocks extension field. a * b - c must
|
|||
// be less than RANGE_CHECK_NB_BITS bits.
|
|||
func (p *Chip) SubMulExtension(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { |
|||
difference := p.SubExtensionNoReduce(a, b) |
|||
product := p.MulExtensionNoReduce(difference, c) |
|||
product[0] = p.Reduce(product[0]) |
|||
product[1] = p.Reduce(product[1]) |
|||
return product |
|||
} |
|||
|
|||
// Multiplies quadratic extension variable in the Goldilocks field by a scalar.
|
|||
func (p *Chip) ScalarMulExtension( |
|||
a QuadraticExtensionVariable, |
|||
b Variable, |
|||
) QuadraticExtensionVariable { |
|||
return NewQuadraticExtensionVariable( |
|||
p.Mul(a[0], b), |
|||
p.Mul(a[1], b), |
|||
) |
|||
} |
|||
|
|||
// Computes an inner product over quadratic extension variable vectors in the Goldilocks field.
|
|||
func (p *Chip) InnerProductExtension( |
|||
constant Variable, |
|||
startingAcc QuadraticExtensionVariable, |
|||
pairs [][2]QuadraticExtensionVariable, |
|||
) QuadraticExtensionVariable { |
|||
acc := startingAcc |
|||
for i := 0; i < len(pairs); i++ { |
|||
a := pairs[i][0] |
|||
b := pairs[i][1] |
|||
mul := p.ScalarMulExtension(a, constant) |
|||
acc = p.MulAddExtensionNoReduce(mul, b, acc) |
|||
} |
|||
return p.ReduceExtension(acc) |
|||
} |
|||
|
|||
// Computes the inverse of a quadratic extension variable in the Goldilocks field.
|
|||
func (p *Chip) InverseExtension(a QuadraticExtensionVariable) QuadraticExtensionVariable { |
|||
a0IsZero := p.api.IsZero(a[0].Limb) |
|||
a1IsZero := p.api.IsZero(a[1].Limb) |
|||
p.api.AssertIsEqual(p.api.Mul(a0IsZero, a1IsZero), frontend.Variable(0)) |
|||
aPowRMinus1 := QuadraticExtensionVariable{ |
|||
a[0], |
|||
p.Mul(a[1], NewVariable(DTH_ROOT)), |
|||
} |
|||
aPowR := p.MulExtension(aPowRMinus1, a) |
|||
return p.ScalarMulExtension(aPowRMinus1, p.Inverse(aPowR[0])) |
|||
} |
|||
|
|||
// Divides two quadratic extension variables in the Goldilocks field.
|
|||
func (p *Chip) DivExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { |
|||
return p.MulExtension(a, p.InverseExtension(b)) |
|||
} |
|||
|
|||
// Exponentiates a quadratic extension variable to some exponent in the Golidlocks field.
|
|||
func (p *Chip) ExpExtension( |
|||
a QuadraticExtensionVariable, |
|||
exponent uint64, |
|||
) QuadraticExtensionVariable { |
|||
switch exponent { |
|||
case 0: |
|||
return OneExtension() |
|||
case 1: |
|||
return a |
|||
case 2: |
|||
return p.MulExtension(a, a) |
|||
default: |
|||
} |
|||
|
|||
current := a |
|||
product := OneExtension() |
|||
|
|||
for i := 0; i < bits.Len64(exponent); i++ { |
|||
if i != 0 { |
|||
current = p.MulExtension(current, current) |
|||
} |
|||
if (exponent >> i & 1) != 0 { |
|||
product = p.MulExtension(product, current) |
|||
} |
|||
} |
|||
|
|||
return product |
|||
} |
|||
|
|||
func (p *Chip) ReduceExtension(x QuadraticExtensionVariable) QuadraticExtensionVariable { |
|||
return NewQuadraticExtensionVariable(p.Reduce(x[0]), p.Reduce(x[1])) |
|||
} |
|||
|
|||
// Reduces a list of extension field terms with a scalar power in the Goldilocks field.
|
|||
func (p *Chip) ReduceWithPowers( |
|||
terms []QuadraticExtensionVariable, |
|||
scalar QuadraticExtensionVariable, |
|||
) QuadraticExtensionVariable { |
|||
sum := ZeroExtension() |
|||
for i := len(terms) - 1; i >= 0; i-- { |
|||
sum = p.AddExtensionNoReduce( |
|||
p.MulExtensionNoReduce( |
|||
sum, |
|||
scalar, |
|||
), |
|||
terms[i], |
|||
) |
|||
sum = p.ReduceExtension(sum) |
|||
} |
|||
return sum |
|||
} |
|||
|
|||
// Outputs whether the quadratic extension variable is zero.
|
|||
func (p *Chip) IsZero(x QuadraticExtensionVariable) frontend.Variable { |
|||
x0IsZero := p.api.IsZero(x[0].Limb) |
|||
x1IsZero := p.api.IsZero(x[1].Limb) |
|||
return p.api.Mul(x0IsZero, x1IsZero) |
|||
} |
|||
|
|||
// Lookup is similar to select, but returns the first variable if the bit is zero and vice-versa.
|
|||
func (p *Chip) Lookup( |
|||
b frontend.Variable, |
|||
x, y QuadraticExtensionVariable, |
|||
) QuadraticExtensionVariable { |
|||
c0 := p.api.Select(b, y[0].Limb, x[0].Limb) |
|||
c1 := p.api.Select(b, y[1].Limb, x[1].Limb) |
|||
return NewQuadraticExtensionVariable(NewVariable(c0), NewVariable(c1)) |
|||
} |
|||
|
|||
// Lookup2 is similar to select2, but returns the first variable if the bit is zero and vice-versa.
|
|||
func (p *Chip) Lookup2( |
|||
b0 frontend.Variable, |
|||
b1 frontend.Variable, |
|||
qe0, qe1, qe2, qe3 QuadraticExtensionVariable, |
|||
) QuadraticExtensionVariable { |
|||
c0 := p.Lookup(b0, qe0, qe1) |
|||
c1 := p.Lookup(b0, qe2, qe3) |
|||
return p.Lookup(b1, c0, c1) |
|||
} |
|||
|
|||
// Asserts that two quadratic extension variables are equal.
|
|||
func (p *Chip) AssertIsEqualExtension( |
|||
a QuadraticExtensionVariable, |
|||
b QuadraticExtensionVariable, |
|||
) { |
|||
p.AssertIsEqual(a[0], b[0]) |
|||
p.AssertIsEqual(a[1], b[1]) |
|||
} |
|||
@ -0,0 +1,125 @@ |
|||
package goldilocks |
|||
|
|||
import "github.com/consensys/gnark-crypto/field/goldilocks" |
|||
|
|||
const D = 2 |
|||
|
|||
type QuadraticExtensionAlgebraVariable = [D]QuadraticExtensionVariable |
|||
|
|||
func NewQuadraticExtensionAlgebraVariable( |
|||
a QuadraticExtensionVariable, |
|||
b QuadraticExtensionVariable, |
|||
) QuadraticExtensionAlgebraVariable { |
|||
return QuadraticExtensionAlgebraVariable{a, b} |
|||
} |
|||
|
|||
func (p QuadraticExtensionVariable) ToQuadraticExtensionAlgebra() QuadraticExtensionAlgebraVariable { |
|||
return [2]QuadraticExtensionVariable{p, ZeroExtension()} |
|||
} |
|||
|
|||
func ZeroExtensionAlgebra() QuadraticExtensionAlgebraVariable { |
|||
return ZeroExtension().ToQuadraticExtensionAlgebra() |
|||
} |
|||
|
|||
func OneExtensionAlgebra() QuadraticExtensionAlgebraVariable { |
|||
return OneExtension().ToQuadraticExtensionAlgebra() |
|||
} |
|||
|
|||
func (p *Chip) AddExtensionAlgebra( |
|||
a QuadraticExtensionAlgebraVariable, |
|||
b QuadraticExtensionAlgebraVariable, |
|||
) QuadraticExtensionAlgebraVariable { |
|||
var sum QuadraticExtensionAlgebraVariable |
|||
for i := 0; i < D; i++ { |
|||
sum[i] = p.AddExtension(a[i], b[i]) |
|||
} |
|||
return sum |
|||
} |
|||
|
|||
func (p *Chip) SubExtensionAlgebra( |
|||
a QuadraticExtensionAlgebraVariable, |
|||
b QuadraticExtensionAlgebraVariable, |
|||
) QuadraticExtensionAlgebraVariable { |
|||
var diff QuadraticExtensionAlgebraVariable |
|||
for i := 0; i < D; i++ { |
|||
diff[i] = p.SubExtension(a[i], b[i]) |
|||
} |
|||
return diff |
|||
} |
|||
|
|||
func (p Chip) MulExtensionAlgebra( |
|||
a QuadraticExtensionAlgebraVariable, |
|||
b QuadraticExtensionAlgebraVariable, |
|||
) QuadraticExtensionAlgebraVariable { |
|||
var inner [D][]QuadraticExtensionAlgebraVariable |
|||
var innerW [D][]QuadraticExtensionAlgebraVariable |
|||
|
|||
for i := 0; i < D; i++ { |
|||
for j := 0; j < D-i; j++ { |
|||
idx := (i + j) % D |
|||
inner[idx] = append(inner[idx], QuadraticExtensionAlgebraVariable{a[i], b[j]}) |
|||
} |
|||
for j := D - i; j < D; j++ { |
|||
idx := (i + j) % D |
|||
innerW[idx] = append(innerW[idx], QuadraticExtensionAlgebraVariable{a[i], b[j]}) |
|||
} |
|||
} |
|||
|
|||
var product QuadraticExtensionAlgebraVariable |
|||
for i := 0; i < D; i++ { |
|||
acc := p.InnerProductExtension(NewVariable(W), ZeroExtension(), innerW[i]) |
|||
product[i] = p.InnerProductExtension(One(), acc, inner[i]) |
|||
} |
|||
|
|||
return product |
|||
} |
|||
|
|||
func (p *Chip) ScalarMulExtensionAlgebra( |
|||
a QuadraticExtensionVariable, |
|||
b QuadraticExtensionAlgebraVariable, |
|||
) QuadraticExtensionAlgebraVariable { |
|||
var product QuadraticExtensionAlgebraVariable |
|||
for i := 0; i < D; i++ { |
|||
product[i] = p.MulExtension(a, b[i]) |
|||
} |
|||
return product |
|||
} |
|||
|
|||
func (p *Chip) PartialInterpolateExtAlgebra( |
|||
domain []goldilocks.Element, |
|||
values []QuadraticExtensionAlgebraVariable, |
|||
barycentricWeights []goldilocks.Element, |
|||
point QuadraticExtensionAlgebraVariable, |
|||
initialEval QuadraticExtensionAlgebraVariable, |
|||
initialPartialProd QuadraticExtensionAlgebraVariable, |
|||
) (QuadraticExtensionAlgebraVariable, QuadraticExtensionAlgebraVariable) { |
|||
n := len(values) |
|||
if n == 0 { |
|||
panic("Cannot interpolate with no values") |
|||
} |
|||
if n != len(domain) { |
|||
panic("Domain and values must have the same length") |
|||
} |
|||
if n != len(barycentricWeights) { |
|||
panic("Domain and barycentric weights must have the same length") |
|||
} |
|||
|
|||
newEval := initialEval |
|||
newPartialProd := initialPartialProd |
|||
for i := 0; i < n; i++ { |
|||
val := values[i] |
|||
x := domain[i] |
|||
xField := NewVariable(x) |
|||
xQE := xField.ToQuadraticExtension() |
|||
xQEAlgebra := xQE.ToQuadraticExtensionAlgebra() |
|||
weight := NewVariable(barycentricWeights[i].Uint64()).ToQuadraticExtension() |
|||
term := p.SubExtensionAlgebra(point, xQEAlgebra) |
|||
weightedVal := p.ScalarMulExtensionAlgebra(weight, val) |
|||
newEval = p.MulExtensionAlgebra(newEval, term) |
|||
tmp := p.MulExtensionAlgebra(weightedVal, newPartialProd) |
|||
newEval = p.AddExtensionAlgebra(newEval, tmp) |
|||
newPartialProd = p.MulExtensionAlgebra(newPartialProd, term) |
|||
} |
|||
|
|||
return newEval, newPartialProd |
|||
} |
|||
@ -0,0 +1 @@ |
|||
package goldilocks |
|||
@ -0,0 +1,94 @@ |
|||
package goldilocks |
|||
|
|||
import ( |
|||
"testing" |
|||
|
|||
"github.com/consensys/gnark-crypto/ecc" |
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/consensys/gnark/test" |
|||
) |
|||
|
|||
type TestQuadraticExtensionMulCircuit struct { |
|||
Operand1 QuadraticExtensionVariable |
|||
Operand2 QuadraticExtensionVariable |
|||
ExpectedResult QuadraticExtensionVariable |
|||
} |
|||
|
|||
func (c *TestQuadraticExtensionMulCircuit) Define(api frontend.API) error { |
|||
glApi := NewChip(api) |
|||
actualRes := glApi.MulExtension(c.Operand1, c.Operand2) |
|||
glApi.AssertIsEqual(actualRes[0], c.ExpectedResult[0]) |
|||
glApi.AssertIsEqual(actualRes[1], c.ExpectedResult[1]) |
|||
return nil |
|||
} |
|||
|
|||
func TestQuadraticExtensionMul4(t *testing.T) { |
|||
assert := test.NewAssert(t) |
|||
operand1 := QuadraticExtensionVariable{ |
|||
NewVariable("4994088319481652598"), |
|||
NewVariable("16489566008211790727"), |
|||
} |
|||
operand2 := QuadraticExtensionVariable{ |
|||
NewVariable("3797605683985595697"), |
|||
NewVariable("13424401189265534004"), |
|||
} |
|||
expectedResult := QuadraticExtensionVariable{ |
|||
NewVariable("15052319864161058789"), |
|||
NewVariable("16841416332519902625"), |
|||
} |
|||
circuit := TestQuadraticExtensionMulCircuit{ |
|||
Operand1: operand1, |
|||
Operand2: operand2, |
|||
ExpectedResult: expectedResult, |
|||
} |
|||
witness := TestQuadraticExtensionMulCircuit{ |
|||
Operand1: operand1, |
|||
Operand2: operand2, |
|||
ExpectedResult: expectedResult, |
|||
} |
|||
err := test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField()) |
|||
assert.NoError(err) |
|||
} |
|||
|
|||
// Test for quadratic extension division
|
|||
type TestQuadraticExtensionDivCircuit struct { |
|||
Operand1 QuadraticExtensionVariable |
|||
Operand2 QuadraticExtensionVariable |
|||
ExpectedResult QuadraticExtensionVariable |
|||
} |
|||
|
|||
func (c *TestQuadraticExtensionDivCircuit) Define(api frontend.API) error { |
|||
glAPI := NewChip(api) |
|||
actualRes := glAPI.DivExtension(c.Operand1, c.Operand2) |
|||
glAPI.AssertIsEqual(actualRes[0], c.ExpectedResult[0]) |
|||
glAPI.AssertIsEqual(actualRes[1], c.ExpectedResult[1]) |
|||
return nil |
|||
} |
|||
|
|||
func TestQuadraticExtensionDiv(t *testing.T) { |
|||
assert := test.NewAssert(t) |
|||
operand1 := QuadraticExtensionVariable{ |
|||
NewVariable("4994088319481652598"), |
|||
NewVariable("16489566008211790727"), |
|||
} |
|||
operand2 := QuadraticExtensionVariable{ |
|||
NewVariable("7166004739148609569"), |
|||
NewVariable("14655965871663555016"), |
|||
} |
|||
expectedResult := QuadraticExtensionVariable{ |
|||
NewVariable("15052319864161058789"), |
|||
NewVariable("16841416332519902625"), |
|||
} |
|||
circuit := TestQuadraticExtensionDivCircuit{ |
|||
Operand1: operand1, |
|||
Operand2: operand2, |
|||
ExpectedResult: expectedResult, |
|||
} |
|||
witness := TestQuadraticExtensionDivCircuit{ |
|||
Operand1: operand1, |
|||
Operand2: operand2, |
|||
ExpectedResult: expectedResult, |
|||
} |
|||
err := test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField()) |
|||
assert.NoError(err) |
|||
} |
|||
@ -0,0 +1,768 @@ |
|||
package gates_test |
|||
|
|||
import ( |
|||
"errors" |
|||
"testing" |
|||
|
|||
"github.com/consensys/gnark-crypto/ecc" |
|||
"github.com/consensys/gnark-crypto/field/goldilocks" |
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/consensys/gnark/test" |
|||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier" |
|||
) |
|||
|
|||
// From recursive_step circuit
|
|||
var localConstants = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("4962976205186800892"), gl.NewVariable("6982360466972099197")}, |
|||
{gl.NewVariable("3587364333101709084"), gl.NewVariable("17496916837371484700")}, |
|||
{gl.NewVariable("17287374881609559799"), gl.NewVariable("3152841633956965234")}, |
|||
{gl.NewVariable("8531030241248616826"), gl.NewVariable("7753678118587211959")}, |
|||
{gl.NewVariable("7622109056373824903"), gl.NewVariable("6523636236475969621")}, |
|||
} |
|||
|
|||
var localWires = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("5101665081776077058"), gl.NewVariable("13601771238484783081")}, |
|||
{gl.NewVariable("13763997788502656587"), gl.NewVariable("6068443864169526207")}, |
|||
{gl.NewVariable("10492880302699453810"), gl.NewVariable("11304418575668616669")}, |
|||
{gl.NewVariable("2175168501339052813"), gl.NewVariable("3658211467579027796")}, |
|||
{gl.NewVariable("11342710587435471757"), gl.NewVariable("658078906333318768")}, |
|||
{gl.NewVariable("16590262768413671742"), gl.NewVariable("4678191900868819358")}, |
|||
{gl.NewVariable("18412513594273328173"), gl.NewVariable("3981245463942959904")}, |
|||
{gl.NewVariable("18150166316938544267"), gl.NewVariable("6968565044901838140")}, |
|||
{gl.NewVariable("1048835939602984673"), gl.NewVariable("3511920575130606798")}, |
|||
{gl.NewVariable("13693300152826538654"), gl.NewVariable("5872314861500881782")}, |
|||
{gl.NewVariable("6394696263219721312"), gl.NewVariable("92364988976021720")}, |
|||
{gl.NewVariable("468193345380249942"), gl.NewVariable("4951036536117371576")}, |
|||
{gl.NewVariable("9660006729985637684"), gl.NewVariable("14762789799642492635")}, |
|||
{gl.NewVariable("10091149087332313493"), gl.NewVariable("13279468039286967053")}, |
|||
{gl.NewVariable("12007469191150580744"), gl.NewVariable("2495445179052731885")}, |
|||
{gl.NewVariable("14225726459587943147"), gl.NewVariable("13484648741862607201")}, |
|||
{gl.NewVariable("15365400400136175672"), gl.NewVariable("12227857303059870833")}, |
|||
{gl.NewVariable("1717742269682481687"), gl.NewVariable("14319701537357602192")}, |
|||
{gl.NewVariable("2130805637557027375"), gl.NewVariable("9674794597783493233")}, |
|||
{gl.NewVariable("4200526016516623452"), gl.NewVariable("1757832412907480092")}, |
|||
{gl.NewVariable("4159226258922372229"), gl.NewVariable("2121976810680943769")}, |
|||
{gl.NewVariable("2887943290582259162"), gl.NewVariable("10337505797799617185")}, |
|||
{gl.NewVariable("14760843822980496189"), gl.NewVariable("16331301823872182680")}, |
|||
{gl.NewVariable("14715580754822129725"), gl.NewVariable("13761736659446638375")}, |
|||
{gl.NewVariable("6925818640561435525"), gl.NewVariable("14142327999826777974")}, |
|||
{gl.NewVariable("14048060513252076245"), gl.NewVariable("14860933194240516940")}, |
|||
{gl.NewVariable("3928889853630846436"), gl.NewVariable("16211791673476822740")}, |
|||
{gl.NewVariable("15980387576926781891"), gl.NewVariable("6238947314711778055")}, |
|||
{gl.NewVariable("15694939331980119296"), gl.NewVariable("8708301222382733590")}, |
|||
{gl.NewVariable("192757930858294268"), gl.NewVariable("5400388905722847256")}, |
|||
{gl.NewVariable("17614358883814855964"), gl.NewVariable("11499208634388453518")}, |
|||
{gl.NewVariable("9523994443422431577"), gl.NewVariable("6835394446482946098")}, |
|||
{gl.NewVariable("10096606893378243201"), gl.NewVariable("8982086840326369907")}, |
|||
{gl.NewVariable("7328922720001507777"), gl.NewVariable("17298728994563323488")}, |
|||
{gl.NewVariable("7038859554184407337"), gl.NewVariable("6498153778103681368")}, |
|||
{gl.NewVariable("10610651604960433540"), gl.NewVariable("18240735600936975661")}, |
|||
{gl.NewVariable("4310901749476028644"), gl.NewVariable("17813866938235850894")}, |
|||
{gl.NewVariable("12456949458361594924"), gl.NewVariable("16541357680870686003")}, |
|||
{gl.NewVariable("13986559680062429806"), gl.NewVariable("14210541290696888125")}, |
|||
{gl.NewVariable("10299578396192380820"), gl.NewVariable("18011235767871391546")}, |
|||
{gl.NewVariable("747566550336808782"), gl.NewVariable("5892109075601553099")}, |
|||
{gl.NewVariable("11613383633841665100"), gl.NewVariable("3562006923196410047")}, |
|||
{gl.NewVariable("14971867523312360339"), gl.NewVariable("9835080574905235511")}, |
|||
{gl.NewVariable("5487884847548072736"), gl.NewVariable("17112808386797082519")}, |
|||
{gl.NewVariable("1687420180518659740"), gl.NewVariable("14003627304711288225")}, |
|||
{gl.NewVariable("6760442482244819429"), gl.NewVariable("15796493945480647537")}, |
|||
{gl.NewVariable("2639939427088481105"), gl.NewVariable("16213109089273184951")}, |
|||
{gl.NewVariable("6186345082501710713"), gl.NewVariable("2529053005908871239")}, |
|||
{gl.NewVariable("16270115914931256348"), gl.NewVariable("2789355919627681645")}, |
|||
{gl.NewVariable("4586999018177783314"), gl.NewVariable("2427837399215959725")}, |
|||
{gl.NewVariable("18143358622388343317"), gl.NewVariable("2145167333845152043")}, |
|||
{gl.NewVariable("20367062449222124"), gl.NewVariable("14939961527015734373")}, |
|||
{gl.NewVariable("16851694158642043266"), gl.NewVariable("5250789952541240163")}, |
|||
{gl.NewVariable("273375074794411822"), gl.NewVariable("16211897175907793903")}, |
|||
{gl.NewVariable("8905927930385832568"), gl.NewVariable("6540262589846603524")}, |
|||
{gl.NewVariable("9283781971254844102"), gl.NewVariable("15115068064900745758")}, |
|||
{gl.NewVariable("16002987404851668189"), gl.NewVariable("15226686847545140008")}, |
|||
{gl.NewVariable("17201679792194997813"), gl.NewVariable("589849108691638964")}, |
|||
{gl.NewVariable("13270753269614250355"), gl.NewVariable("13858862497673084592")}, |
|||
{gl.NewVariable("3679908279346826560"), gl.NewVariable("10125726541855725943")}, |
|||
{gl.NewVariable("9493227554592600240"), gl.NewVariable("13229107531594530196")}, |
|||
{gl.NewVariable("10072423214517113799"), gl.NewVariable("1877804054697703518")}, |
|||
{gl.NewVariable("9351494680554520560"), gl.NewVariable("12930187723253788505")}, |
|||
{gl.NewVariable("9537056082833040850"), gl.NewVariable("3947445714701039423")}, |
|||
{gl.NewVariable("978662253133020143"), gl.NewVariable("17432233037279205717")}, |
|||
{gl.NewVariable("13408331971471826902"), gl.NewVariable("8338873650278204671")}, |
|||
{gl.NewVariable("10455530172494355126"), gl.NewVariable("14614842120953588617")}, |
|||
{gl.NewVariable("3066054670984065145"), gl.NewVariable("11061840675948823020")}, |
|||
{gl.NewVariable("1215442291812236170"), gl.NewVariable("6970679356502977963")}, |
|||
{gl.NewVariable("16254140688845356393"), gl.NewVariable("16413217415268481315")}, |
|||
{gl.NewVariable("5571707217813279614"), gl.NewVariable("2506082641312169038")}, |
|||
{gl.NewVariable("18179591596294163519"), gl.NewVariable("16131760445397495720")}, |
|||
{gl.NewVariable("9500821197677833979"), gl.NewVariable("14137570623214003877")}, |
|||
{gl.NewVariable("18159279414894480072"), gl.NewVariable("316120438770524969")}, |
|||
{gl.NewVariable("18164288455905080997"), gl.NewVariable("12889510574086616078")}, |
|||
{gl.NewVariable("7158952489901063870"), gl.NewVariable("8855957421923524202")}, |
|||
{gl.NewVariable("11785615172910130564"), gl.NewVariable("13242859272114186921")}, |
|||
{gl.NewVariable("7978627011292316159"), gl.NewVariable("12030929068833787030")}, |
|||
{gl.NewVariable("5676253512795062173"), gl.NewVariable("9401396509276686822")}, |
|||
{gl.NewVariable("13934555872940874542"), gl.NewVariable("12262482935570269103")}, |
|||
{gl.NewVariable("17018864997992880664"), gl.NewVariable("8399037137658253821")}, |
|||
{gl.NewVariable("1846702834278938262"), gl.NewVariable("13210394651984411322")}, |
|||
{gl.NewVariable("18406563809882201846"), gl.NewVariable("15807625126691296911")}, |
|||
{gl.NewVariable("16192554501791210701"), gl.NewVariable("15105514277710825451")}, |
|||
{gl.NewVariable("16115514979166385045"), gl.NewVariable("5618092869410987045")}, |
|||
{gl.NewVariable("9816852940756124129"), gl.NewVariable("1617435612712694609")}, |
|||
{gl.NewVariable("15012743324956680415"), gl.NewVariable("11098953448520716956")}, |
|||
{gl.NewVariable("7370750057902285338"), gl.NewVariable("15456123684241865136")}, |
|||
{gl.NewVariable("14924801177398773859"), gl.NewVariable("1116868612459919368")}, |
|||
{gl.NewVariable("509701279674911901"), gl.NewVariable("8606220700917290973")}, |
|||
{gl.NewVariable("256371784527067555"), gl.NewVariable("18023759020251995084")}, |
|||
{gl.NewVariable("4027645791496469270"), gl.NewVariable("6446906876250510281")}, |
|||
{gl.NewVariable("8190141658485644545"), gl.NewVariable("3259909135802998300")}, |
|||
{gl.NewVariable("11270185749533517292"), gl.NewVariable("7032460358965516338")}, |
|||
{gl.NewVariable("12112891112487601597"), gl.NewVariable("3686732542066412082")}, |
|||
{gl.NewVariable("18143522178445971138"), gl.NewVariable("6066438010126851248")}, |
|||
{gl.NewVariable("16109160830754618815"), gl.NewVariable("2728516440557525242")}, |
|||
{gl.NewVariable("14634072837475699881"), gl.NewVariable("423778353213757146")}, |
|||
{gl.NewVariable("10421081673554059162"), gl.NewVariable("10142208889746521219")}, |
|||
{gl.NewVariable("12957639310809930956"), gl.NewVariable("1709286023553869935")}, |
|||
{gl.NewVariable("16217923109113456531"), gl.NewVariable("3257438610376598615")}, |
|||
{gl.NewVariable("14024104132094810570"), gl.NewVariable("6065015478137587430")}, |
|||
{gl.NewVariable("7972303368219061571"), gl.NewVariable("5413678307283424945")}, |
|||
{gl.NewVariable("10367882107777269226"), gl.NewVariable("9366367173763419226")}, |
|||
{gl.NewVariable("11506720810821148150"), gl.NewVariable("15210537421649867625")}, |
|||
{gl.NewVariable("10979917526797364486"), gl.NewVariable("3365843489182711842")}, |
|||
{gl.NewVariable("9176981360155624350"), gl.NewVariable("7315956459698675112")}, |
|||
{gl.NewVariable("3964217770504101577"), gl.NewVariable("9088242192411952739")}, |
|||
{gl.NewVariable("16243289324567090937"), gl.NewVariable("13379263550784156456")}, |
|||
{gl.NewVariable("18105277122985331384"), gl.NewVariable("13639149553905751132")}, |
|||
{gl.NewVariable("11145583988660932112"), gl.NewVariable("16125114195985557867")}, |
|||
{gl.NewVariable("18437667738670181477"), gl.NewVariable("8593343353929068644")}, |
|||
{gl.NewVariable("15549894364614350199"), gl.NewVariable("6234736889764963090")}, |
|||
{gl.NewVariable("17753837009416762390"), gl.NewVariable("15297774054893249240")}, |
|||
{gl.NewVariable("1465043006528110247"), gl.NewVariable("11029942851654974974")}, |
|||
{gl.NewVariable("14312704742949520917"), gl.NewVariable("17324353686056674958")}, |
|||
{gl.NewVariable("8078333430227959261"), gl.NewVariable("14797545414164578336")}, |
|||
{gl.NewVariable("3544997838139687150"), gl.NewVariable("8846840377946705678")}, |
|||
{gl.NewVariable("9981846866090807073"), gl.NewVariable("18142560414179130259")}, |
|||
{gl.NewVariable("1256577435119993994"), gl.NewVariable("155745544208227129")}, |
|||
{gl.NewVariable("6040293874299819317"), gl.NewVariable("10483265617246740662")}, |
|||
{gl.NewVariable("976159477616343697"), gl.NewVariable("6356544693059700239")}, |
|||
{gl.NewVariable("4771747444846377672"), gl.NewVariable("2466985401424965488")}, |
|||
{gl.NewVariable("9549711421417753693"), gl.NewVariable("9543806479040458857")}, |
|||
{gl.NewVariable("5277199124405775998"), gl.NewVariable("6251037001966593402")}, |
|||
{gl.NewVariable("13103543598051591262"), gl.NewVariable("2001921170471454234")}, |
|||
{gl.NewVariable("1254878001165263070"), gl.NewVariable("17587272030879777460")}, |
|||
{gl.NewVariable("2300344156307624878"), gl.NewVariable("14356513038946626528")}, |
|||
{gl.NewVariable("2482567400777596327"), gl.NewVariable("3314129985687795881")}, |
|||
{gl.NewVariable("16492046206730922155"), gl.NewVariable("1312905854247159931")}, |
|||
{gl.NewVariable("3061501132630116372"), gl.NewVariable("13315665946615810001")}, |
|||
{gl.NewVariable("16415932954051444990"), gl.NewVariable("925217124969456536")}, |
|||
{gl.NewVariable("9764657158286137619"), gl.NewVariable("16039332713210679567")}, |
|||
{gl.NewVariable("14993545086997628961"), gl.NewVariable("18010329211070748489")}, |
|||
{gl.NewVariable("17327862012036619887"), gl.NewVariable("16962349802452905993")}, |
|||
{gl.NewVariable("4826313026336060985"), gl.NewVariable("3597777099127511952")}, |
|||
} |
|||
|
|||
var publicInputsHash = poseidon.GoldilocksHashOut{ |
|||
gl.Zero(), |
|||
gl.Zero(), |
|||
gl.Zero(), |
|||
gl.Zero(), |
|||
} |
|||
|
|||
var publicInputGateExpectedConstraints = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("5101665081776077058"), gl.NewVariable("13601771238484783081")}, |
|||
{gl.NewVariable("13763997788502656587"), gl.NewVariable("6068443864169526207")}, |
|||
{gl.NewVariable("10492880302699453810"), gl.NewVariable("11304418575668616669")}, |
|||
{gl.NewVariable("2175168501339052813"), gl.NewVariable("3658211467579027796")}, |
|||
} |
|||
|
|||
// BaseSumGate { num_limbs: 63 }), (Base: 2)
|
|||
var baseSumGateExpectedConstraints = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("9928715244459351681"), gl.NewVariable("5344081500364361215")}, |
|||
{gl.NewVariable("10167164649082076581"), gl.NewVariable("15450889555489725096")}, |
|||
{gl.NewVariable("3546584706462116594"), gl.NewVariable("1476426705388693036")}, |
|||
{gl.NewVariable("12648634003162244983"), gl.NewVariable("2239452344495239178")}, |
|||
{gl.NewVariable("2301087631440580451"), gl.NewVariable("11975672920337250307")}, |
|||
{gl.NewVariable("14001554463269171732"), gl.NewVariable("6953207277617809048")}, |
|||
{gl.NewVariable("9895590040747031510"), gl.NewVariable("1356956949635190505")}, |
|||
{gl.NewVariable("14939964178677988571"), gl.NewVariable("454717738260444218")}, |
|||
{gl.NewVariable("12201660109699192297"), gl.NewVariable("12502457673278583036")}, |
|||
{gl.NewVariable("1175543972635147885"), gl.NewVariable("11103026408792334489")}, |
|||
{gl.NewVariable("3384025741923988904"), gl.NewVariable("2656764746353452717")}, |
|||
{gl.NewVariable("10849522185534943138"), gl.NewVariable("13172212508084788997")}, |
|||
{gl.NewVariable("10509522572526523739"), gl.NewVariable("2090707475955491976")}, |
|||
{gl.NewVariable("13692600715410336206"), gl.NewVariable("7227633217973806771")}, |
|||
{gl.NewVariable("8471053080480597138"), gl.NewVariable("2646922138422495173")}, |
|||
{gl.NewVariable("555344530120410083"), gl.NewVariable("13860459564781531385")}, |
|||
{gl.NewVariable("8748801107049442833"), gl.NewVariable("9263752460533085733")}, |
|||
{gl.NewVariable("13633964398888639692"), gl.NewVariable("10068133633095351031")}, |
|||
{gl.NewVariable("6911322073377914708"), gl.NewVariable("17978361073083837803")}, |
|||
{gl.NewVariable("11223090828346729804"), gl.NewVariable("5006610230932979596")}, |
|||
{gl.NewVariable("11581626217660221266"), gl.NewVariable("16347470001077006094")}, |
|||
{gl.NewVariable("2924189901864366701"), gl.NewVariable("4309265474738828848")}, |
|||
{gl.NewVariable("7275314468944461178"), gl.NewVariable("3109308884739285751")}, |
|||
{gl.NewVariable("12416988612575693809"), gl.NewVariable("13772367397588066248")}, |
|||
{gl.NewVariable("15438805794425696237"), gl.NewVariable("5809350894111990599")}, |
|||
{gl.NewVariable("4275145128501503120"), gl.NewVariable("13230668146909969114")}, |
|||
{gl.NewVariable("15244699495724739585"), gl.NewVariable("7672322205441472064")}, |
|||
{gl.NewVariable("5429809680618805220"), gl.NewVariable("3153880467220264060")}, |
|||
{gl.NewVariable("14715345489518514160"), gl.NewVariable("2246036712337629635")}, |
|||
{gl.NewVariable("9359342125434211935"), gl.NewVariable("7844760208539761732")}, |
|||
{gl.NewVariable("17550561700498841003"), gl.NewVariable("10851755490050776878")}, |
|||
{gl.NewVariable("12192385328855013814"), gl.NewVariable("6629056869404844416")}, |
|||
{gl.NewVariable("3424745785197724925"), gl.NewVariable("9833599393425172230")}, |
|||
{gl.NewVariable("8602078107149096927"), gl.NewVariable("6592109323720773368")}, |
|||
{gl.NewVariable("4109716921881297082"), gl.NewVariable("4396469548700606105")}, |
|||
{gl.NewVariable("10400304110319417426"), gl.NewVariable("1229823145437740976")}, |
|||
{gl.NewVariable("14853277673343952974"), gl.NewVariable("7653131044140686982")}, |
|||
{gl.NewVariable("15831955783787857197"), gl.NewVariable("16541106185743830609")}, |
|||
{gl.NewVariable("16097830673407036871"), gl.NewVariable("917501749911433098")}, |
|||
{gl.NewVariable("6819428296662518848"), gl.NewVariable("15325182544903569500")}, |
|||
{gl.NewVariable("3554857310728040215"), gl.NewVariable("17540168721765377170")}, |
|||
{gl.NewVariable("7246216899469226885"), gl.NewVariable("3184709231158489554")}, |
|||
{gl.NewVariable("3462793508732024933"), gl.NewVariable("13410498916934897793")}, |
|||
{gl.NewVariable("784714181705176804"), gl.NewVariable("8079390288171846846")}, |
|||
{gl.NewVariable("4592501261546923410"), gl.NewVariable("6046244648190342248")}, |
|||
{gl.NewVariable("14100558314779073910"), gl.NewVariable("9589305391181830029")}, |
|||
{gl.NewVariable("7208216654581381179"), gl.NewVariable("16662177305876430630")}, |
|||
{gl.NewVariable("13442246990998561849"), gl.NewVariable("6359024918649040199")}, |
|||
{gl.NewVariable("16196376030005699590"), gl.NewVariable("5656446490425854681")}, |
|||
{gl.NewVariable("16279173216505198700"), gl.NewVariable("6278440230935274234")}, |
|||
{gl.NewVariable("9299204333782277508"), gl.NewVariable("5539548698065086849")}, |
|||
{gl.NewVariable("531539748103362347"), gl.NewVariable("17008402782657673980")}, |
|||
{gl.NewVariable("11956287871118080485"), gl.NewVariable("17776888431041950837")}, |
|||
{gl.NewVariable("16795401491637949606"), gl.NewVariable("12112971435724505573")}, |
|||
{gl.NewVariable("10141270150228316653"), gl.NewVariable("8738825159351228227")}, |
|||
{gl.NewVariable("4249416130151320263"), gl.NewVariable("4171109024390883108")}, |
|||
{gl.NewVariable("13565954345346642147"), gl.NewVariable("11300077318998472624")}, |
|||
{gl.NewVariable("6006413348327738680"), gl.NewVariable("17429146764001291339")}, |
|||
{gl.NewVariable("3009379005164242386"), gl.NewVariable("17911649148503516453")}, |
|||
{gl.NewVariable("4172202865347441020"), gl.NewVariable("6700979848078030374")}, |
|||
{gl.NewVariable("9692174554453081047"), gl.NewVariable("16461309050820528716")}, |
|||
{gl.NewVariable("16012555505188709835"), gl.NewVariable("875036531415994728")}, |
|||
{gl.NewVariable("14527388813134058525"), gl.NewVariable("13371873777459370318")}, |
|||
{gl.NewVariable("6493493657980111839"), gl.NewVariable("14874520839734823069")}, |
|||
} |
|||
|
|||
// ArithmeticGate { num_ops: 20 }
|
|||
var arithmeticGateExpectedConstraints = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("8251494922795803874"), gl.NewVariable("7884328911897949424")}, |
|||
{gl.NewVariable("17545754596575389449"), gl.NewVariable("15111927979676704385")}, |
|||
{gl.NewVariable("10052040965126353731"), gl.NewVariable("1448153912054014611")}, |
|||
{gl.NewVariable("3878848318701063854"), gl.NewVariable("15999854355391952993")}, |
|||
{gl.NewVariable("2194699804496089007"), gl.NewVariable("7489112350095609056")}, |
|||
{gl.NewVariable("666656317372820215"), gl.NewVariable("8333111246649438880")}, |
|||
{gl.NewVariable("15500013716804095980"), gl.NewVariable("7739144386812042617")}, |
|||
{gl.NewVariable("2815612394018416154"), gl.NewVariable("15839168197108305099")}, |
|||
{gl.NewVariable("12980309813768330187"), gl.NewVariable("12446111953378048591")}, |
|||
{gl.NewVariable("1389916348936822477"), gl.NewVariable("2080258147396834809")}, |
|||
{gl.NewVariable("3676770229830052631"), gl.NewVariable("8984521981419906260")}, |
|||
{gl.NewVariable("4759606161035299488"), gl.NewVariable("18415228017149216426")}, |
|||
{gl.NewVariable("6849567585629675684"), gl.NewVariable("15231001333591586187")}, |
|||
{gl.NewVariable("17831496121270832947"), gl.NewVariable("1868580989876710210")}, |
|||
{gl.NewVariable("12226832860244216901"), gl.NewVariable("12352098694767236965")}, |
|||
{gl.NewVariable("9795530155924375772"), gl.NewVariable("4833402654226660686")}, |
|||
{gl.NewVariable("7421277748600887772"), gl.NewVariable("16979590244320625600")}, |
|||
{gl.NewVariable("4212532134312824848"), gl.NewVariable("7938725153260099101")}, |
|||
{gl.NewVariable("17718231164451799422"), gl.NewVariable("13363195988334771788")}, |
|||
{gl.NewVariable("5414385531680474153"), gl.NewVariable("13600409983387272243")}, |
|||
} |
|||
|
|||
// RandomAccessGate { bits: 4, num_copies: 4, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
|
|||
var randomAccessGateExpectedConstraints = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("18367067186009695282"), gl.NewVariable("6227937229941915629")}, |
|||
{gl.NewVariable("342627832935644960"), gl.NewVariable("11262336464371657587")}, |
|||
{gl.NewVariable("7711502047853221895"), gl.NewVariable("9814305320358879113")}, |
|||
{gl.NewVariable("2436675870898619939"), gl.NewVariable("12171743011114835714")}, |
|||
{gl.NewVariable("9224796650008092960"), gl.NewVariable("197827193844666436")}, |
|||
{gl.NewVariable("7661651717350955969"), gl.NewVariable("3929163527437938921")}, |
|||
{gl.NewVariable("11994613277879586781"), gl.NewVariable("2918199453077793278")}, |
|||
{gl.NewVariable("2133315582796573410"), gl.NewVariable("9920472598641951727")}, |
|||
{gl.NewVariable("5763420675219782924"), gl.NewVariable("193200772658790662")}, |
|||
{gl.NewVariable("14322103909897767697"), gl.NewVariable("2455403487869979318")}, |
|||
{gl.NewVariable("3583177870835306708"), gl.NewVariable("15956920993825363087")}, |
|||
{gl.NewVariable("15767764327818217757"), gl.NewVariable("17814936958431909187")}, |
|||
{gl.NewVariable("7224551806569620055"), gl.NewVariable("1191241782303323453")}, |
|||
{gl.NewVariable("3994846439282900915"), gl.NewVariable("16007298430807731888")}, |
|||
{gl.NewVariable("1904864531973789879"), gl.NewVariable("9374437322489636375")}, |
|||
{gl.NewVariable("17617411600595291430"), gl.NewVariable("11804426503917788826")}, |
|||
{gl.NewVariable("5010213812557284606"), gl.NewVariable("8276410914978849008")}, |
|||
{gl.NewVariable("13701536021647106057"), gl.NewVariable("5043776904396037625")}, |
|||
{gl.NewVariable("4336267979289896624"), gl.NewVariable("8771134635816393433")}, |
|||
{gl.NewVariable("17885926480537171976"), gl.NewVariable("9644095314646547597")}, |
|||
{gl.NewVariable("17179233085824331332"), gl.NewVariable("6950525108693323209")}, |
|||
{gl.NewVariable("9461258042008745175"), gl.NewVariable("6766975264204597922")}, |
|||
{gl.NewVariable("10838154179711471883"), gl.NewVariable("16554457937262927355")}, |
|||
{gl.NewVariable("5823858951686479642"), gl.NewVariable("10171201631442530906")}, |
|||
{gl.NewVariable("17476953112985367168"), gl.NewVariable("12062851564787792403")}, |
|||
{gl.NewVariable("7909573710893929152"), gl.NewVariable("6207515797705444652")}, |
|||
} |
|||
|
|||
// PoseidonGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>
|
|||
var poseidonGateExpectedConstraints = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("15438805794425696237"), gl.NewVariable("5809350894111990599")}, |
|||
{gl.NewVariable("105238306594298866"), gl.NewVariable("6398155585902798861")}, |
|||
{gl.NewVariable("5256232026568856387"), gl.NewVariable("9253448664982005262")}, |
|||
{gl.NewVariable("6559974022172208218"), gl.NewVariable("14478753759394222537")}, |
|||
{gl.NewVariable("7036928093413865537"), gl.NewVariable("895644692646980845")}, |
|||
{gl.NewVariable("6350074916129003337"), gl.NewVariable("10418298512623677843")}, |
|||
{gl.NewVariable("6618288817893266284"), gl.NewVariable("17565920952415773065")}, |
|||
{gl.NewVariable("7214268149308735221"), gl.NewVariable("17797640553663908886")}, |
|||
{gl.NewVariable("17038147867485750883"), gl.NewVariable("10766691853641769251")}, |
|||
{gl.NewVariable("1228066111137794024"), gl.NewVariable("1267834319488006514")}, |
|||
{gl.NewVariable("15317834050441961579"), gl.NewVariable("13280896488837969140")}, |
|||
{gl.NewVariable("10135227968960430585"), gl.NewVariable("7096433509203324519")}, |
|||
{gl.NewVariable("10733417635899979276"), gl.NewVariable("16819459255105516700")}, |
|||
{gl.NewVariable("4231839251429338586"), gl.NewVariable("3213678047797020863")}, |
|||
{gl.NewVariable("16271445286187692537"), gl.NewVariable("15377656608157234934")}, |
|||
{gl.NewVariable("9356442829698587975"), gl.NewVariable("14633910545825415036")}, |
|||
{gl.NewVariable("13952390018297698734"), gl.NewVariable("16325393355066618599")}, |
|||
{gl.NewVariable("11399251131586292643"), gl.NewVariable("16257107051968717815")}, |
|||
{gl.NewVariable("4274092107872068929"), gl.NewVariable("15550597684938436610")}, |
|||
{gl.NewVariable("13076618331457049912"), gl.NewVariable("4958059540220054374")}, |
|||
{gl.NewVariable("11650097218963026123"), gl.NewVariable("12070947109214611020")}, |
|||
{gl.NewVariable("2700303408109034014"), gl.NewVariable("5968338348636871194")}, |
|||
{gl.NewVariable("11508005723655482353"), gl.NewVariable("15224088756564969467")}, |
|||
{gl.NewVariable("9328231423353697829"), gl.NewVariable("10577349809783627634")}, |
|||
{gl.NewVariable("556544259468984890"), gl.NewVariable("13376447539117215836")}, |
|||
{gl.NewVariable("17319865455991589647"), gl.NewVariable("588985536671201497")}, |
|||
{gl.NewVariable("9528470026616131077"), gl.NewVariable("7257040911301352274")}, |
|||
{gl.NewVariable("14316182132889623635"), gl.NewVariable("9589165219691594711")}, |
|||
{gl.NewVariable("10405802815809041956"), gl.NewVariable("13917007789819955074")}, |
|||
{gl.NewVariable("12560668105252495616"), gl.NewVariable("3591188232548111694")}, |
|||
{gl.NewVariable("14765117357942682611"), gl.NewVariable("10757853341059462467")}, |
|||
{gl.NewVariable("6099902163260965551"), gl.NewVariable("11343816861356056114")}, |
|||
{gl.NewVariable("1083174255539258286"), gl.NewVariable("7587979659522435417")}, |
|||
{gl.NewVariable("2882552180249608570"), gl.NewVariable("7966658657757662554")}, |
|||
{gl.NewVariable("13490914415473336227"), gl.NewVariable("63845168436289811")}, |
|||
{gl.NewVariable("9459794640071212413"), gl.NewVariable("13417331052474309186")}, |
|||
{gl.NewVariable("18328090807516092318"), gl.NewVariable("11807085063599693782")}, |
|||
{gl.NewVariable("281059606944328759"), gl.NewVariable("13352248056867426135")}, |
|||
{gl.NewVariable("10905177588660050370"), gl.NewVariable("6597328385789442670")}, |
|||
{gl.NewVariable("8426356906491012567"), gl.NewVariable("17214424336396001022")}, |
|||
{gl.NewVariable("15696035667318839817"), gl.NewVariable("13285870048485492127")}, |
|||
{gl.NewVariable("6110244444680672193"), gl.NewVariable("17558548349689468031")}, |
|||
{gl.NewVariable("14614078615782659381"), gl.NewVariable("13184024850613726857")}, |
|||
{gl.NewVariable("1541592450520953410"), gl.NewVariable("18339388388315914026")}, |
|||
{gl.NewVariable("8059386643769157052"), gl.NewVariable("10208764910817462305")}, |
|||
{gl.NewVariable("7612459820354975117"), gl.NewVariable("7582060685277695926")}, |
|||
{gl.NewVariable("12515587043516861064"), gl.NewVariable("16099239041553682288")}, |
|||
{gl.NewVariable("14269196473871652102"), gl.NewVariable("1225067220600668761")}, |
|||
{gl.NewVariable("12691255077510636187"), gl.NewVariable("14147201911063761532")}, |
|||
{gl.NewVariable("3001134598446056765"), gl.NewVariable("14313090483058155636")}, |
|||
{gl.NewVariable("13964993951988177315"), gl.NewVariable("17731737838539414275")}, |
|||
{gl.NewVariable("2686259154263524343"), gl.NewVariable("12198712301337570859")}, |
|||
{gl.NewVariable("6730431920128908773"), gl.NewVariable("4325394084875720868")}, |
|||
{gl.NewVariable("988774723104779817"), gl.NewVariable("8388266879854983623")}, |
|||
{gl.NewVariable("8233087560647959985"), gl.NewVariable("7751837576340060020")}, |
|||
{gl.NewVariable("9546113779017699592"), gl.NewVariable("4049920632309298778")}, |
|||
{gl.NewVariable("3283837251411237060"), gl.NewVariable("13560940050752580093")}, |
|||
{gl.NewVariable("10388838746951897109"), gl.NewVariable("454393475113110282")}, |
|||
{gl.NewVariable("2208016536897042313"), gl.NewVariable("17105586471193083308")}, |
|||
{gl.NewVariable("17683990802267567604"), gl.NewVariable("15398473956537380705")}, |
|||
{gl.NewVariable("70612752050386177"), gl.NewVariable("12349994002954022957")}, |
|||
{gl.NewVariable("13794244952989612728"), gl.NewVariable("15888581169565306348")}, |
|||
{gl.NewVariable("8270800566553141412"), gl.NewVariable("1516938823651329185")}, |
|||
{gl.NewVariable("643507941153616368"), gl.NewVariable("3893451216814345882")}, |
|||
{gl.NewVariable("16464837166410943694"), gl.NewVariable("11108183142967610977")}, |
|||
{gl.NewVariable("9748621820629198396"), gl.NewVariable("3766489907402036319")}, |
|||
{gl.NewVariable("3115179618981245947"), gl.NewVariable("10160994694067456423")}, |
|||
{gl.NewVariable("4497210741038443097"), gl.NewVariable("6445446770984515259")}, |
|||
{gl.NewVariable("5470898125882256227"), gl.NewVariable("8249357863801204908")}, |
|||
{gl.NewVariable("16762380205819269382"), gl.NewVariable("172510727904060494")}, |
|||
{gl.NewVariable("7920011253931301350"), gl.NewVariable("9681193995678483756")}, |
|||
{gl.NewVariable("8258951043315574232"), gl.NewVariable("13137471323476190588")}, |
|||
{gl.NewVariable("4339364527801481944"), gl.NewVariable("16862579756243326257")}, |
|||
{gl.NewVariable("8980029737458438570"), gl.NewVariable("14651625524257781922")}, |
|||
{gl.NewVariable("17935993907375677671"), gl.NewVariable("5318319737405476029")}, |
|||
{gl.NewVariable("716791501623731831"), gl.NewVariable("18425818060734993303")}, |
|||
{gl.NewVariable("601549076806364660"), gl.NewVariable("12303919727550310013")}, |
|||
{gl.NewVariable("18026376178895562118"), gl.NewVariable("14687420532194520529")}, |
|||
{gl.NewVariable("16943892475592026666"), gl.NewVariable("7451688507369746594")}, |
|||
{gl.NewVariable("8724072308842121373"), gl.NewVariable("11662986251379699921")}, |
|||
{gl.NewVariable("3201079129905071298"), gl.NewVariable("11542621183935331871")}, |
|||
{gl.NewVariable("9889739070824270529"), gl.NewVariable("3891825006545095657")}, |
|||
{gl.NewVariable("15538978715382418651"), gl.NewVariable("2419672705453973015")}, |
|||
{gl.NewVariable("3001525234835174062"), gl.NewVariable("17115969716224377534")}, |
|||
{gl.NewVariable("18001237923148428045"), gl.NewVariable("2198015511953873786")}, |
|||
{gl.NewVariable("14186741561112601666"), gl.NewVariable("13156405199205086627")}, |
|||
{gl.NewVariable("10166592177477126663"), gl.NewVariable("13586051001537885658")}, |
|||
{gl.NewVariable("8678352780562557555"), gl.NewVariable("1968366090049630482")}, |
|||
{gl.NewVariable("5627999915794840395"), gl.NewVariable("13597556392696072088")}, |
|||
{gl.NewVariable("9291327714650886898"), gl.NewVariable("2411361999629511024")}, |
|||
{gl.NewVariable("6824943761729555359"), gl.NewVariable("7484507209360908175")}, |
|||
{gl.NewVariable("6276580084700132178"), gl.NewVariable("6246691657613415035")}, |
|||
{gl.NewVariable("10736230409698057656"), gl.NewVariable("7306720219045064925")}, |
|||
{gl.NewVariable("15442170485732017109"), gl.NewVariable("1739984147692575725")}, |
|||
{gl.NewVariable("4448878124301402845"), gl.NewVariable("18436455114977877323")}, |
|||
{gl.NewVariable("638012599023653143"), gl.NewVariable("16265955502846626936")}, |
|||
{gl.NewVariable("6793907577559820653"), gl.NewVariable("15343551069946118619")}, |
|||
{gl.NewVariable("17903286158968614509"), gl.NewVariable("9559701571149911252")}, |
|||
{gl.NewVariable("14652006464960400785"), gl.NewVariable("50421020503848143")}, |
|||
{gl.NewVariable("9452858006432860845"), gl.NewVariable("2625726945677447428")}, |
|||
{gl.NewVariable("853640589013584892"), gl.NewVariable("14655161412118141649")}, |
|||
{gl.NewVariable("12863832006745352780"), gl.NewVariable("14564189651136231029")}, |
|||
{gl.NewVariable("8551517270810530438"), gl.NewVariable("10859465327758962622")}, |
|||
{gl.NewVariable("10113468436120661191"), gl.NewVariable("16040944006557911589")}, |
|||
{gl.NewVariable("4921439225277518643"), gl.NewVariable("8399175422965154512")}, |
|||
{gl.NewVariable("13068240354812957183"), gl.NewVariable("8520393046894990946")}, |
|||
{gl.NewVariable("1189183420107219532"), gl.NewVariable("18066897627856601789")}, |
|||
{gl.NewVariable("3997900004790871153"), gl.NewVariable("1269718920871578117")}, |
|||
{gl.NewVariable("15438784576472256462"), gl.NewVariable("9577304425687441047")}, |
|||
{gl.NewVariable("17158083218962275971"), gl.NewVariable("17379790274576244684")}, |
|||
{gl.NewVariable("3470452736936929010"), gl.NewVariable("12769555113044633230")}, |
|||
{gl.NewVariable("18389243269515626865"), gl.NewVariable("8023737530782576805")}, |
|||
{gl.NewVariable("3529213023405995549"), gl.NewVariable("8829896701928525938")}, |
|||
{gl.NewVariable("14072413770981804653"), gl.NewVariable("9660693090213237836")}, |
|||
{gl.NewVariable("14369435038913678671"), gl.NewVariable("7659129852562422871")}, |
|||
{gl.NewVariable("6779301728445724040"), gl.NewVariable("18290152515233036523")}, |
|||
{gl.NewVariable("8113954200727174254"), gl.NewVariable("16490002532983549952")}, |
|||
{gl.NewVariable("11465655095604389561"), gl.NewVariable("9066100972825318010")}, |
|||
{gl.NewVariable("15998691377748321442"), gl.NewVariable("16970045124898180365")}, |
|||
{gl.NewVariable("8424730626816696233"), gl.NewVariable("17168184083072399403")}, |
|||
{gl.NewVariable("1941959246552302666"), gl.NewVariable("6751013195867127440")}, |
|||
{gl.NewVariable("1907519456922228224"), gl.NewVariable("689311996911195932")}, |
|||
{gl.NewVariable("16277197060525435740"), gl.NewVariable("12018417724719716072")}, |
|||
} |
|||
|
|||
var reducingExtensionGateExpectedConstraints = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("12832102811425062912"), gl.NewVariable("2979695993654444095")}, |
|||
{gl.NewVariable("4822478941232734654"), gl.NewVariable("2600327308894333341")}, |
|||
{gl.NewVariable("12450653411048814602"), gl.NewVariable("1161667420593062956")}, |
|||
{gl.NewVariable("3145631295867407955"), gl.NewVariable("1702059944088737075")}, |
|||
{gl.NewVariable("4597190091407364771"), gl.NewVariable("4257077286672555409")}, |
|||
{gl.NewVariable("10177664366491925772"), gl.NewVariable("10489575701186298604")}, |
|||
{gl.NewVariable("2754621968864722399"), gl.NewVariable("12087963411706301871")}, |
|||
{gl.NewVariable("534408217555793149"), gl.NewVariable("12559345737194357169")}, |
|||
{gl.NewVariable("9508765820222303634"), gl.NewVariable("14102461861317982082")}, |
|||
{gl.NewVariable("15070954032232801974"), gl.NewVariable("2078249670161696735")}, |
|||
{gl.NewVariable("10465809629504954691"), gl.NewVariable("16223748685835312497")}, |
|||
{gl.NewVariable("10957196413441800202"), gl.NewVariable("3841214025425953691")}, |
|||
{gl.NewVariable("18438848195188240825"), gl.NewVariable("5697684145424680565")}, |
|||
{gl.NewVariable("565455534266129104"), gl.NewVariable("12543354947937779806")}, |
|||
{gl.NewVariable("16376588778962418386"), gl.NewVariable("1273250903423198860")}, |
|||
{gl.NewVariable("4128104469872810921"), gl.NewVariable("1433037233801071123")}, |
|||
{gl.NewVariable("6011337242244377340"), gl.NewVariable("16068106780789397185")}, |
|||
{gl.NewVariable("4741354504248328629"), gl.NewVariable("3000853646720964165")}, |
|||
{gl.NewVariable("13064594310789140866"), gl.NewVariable("10950406741883971259")}, |
|||
{gl.NewVariable("17079026691450750925"), gl.NewVariable("6522027970928818261")}, |
|||
{gl.NewVariable("13158136237489326416"), gl.NewVariable("7677629162183242732")}, |
|||
{gl.NewVariable("14741398060174921234"), gl.NewVariable("2960243215156352194")}, |
|||
{gl.NewVariable("9111161782199179468"), gl.NewVariable("8010960876261510099")}, |
|||
{gl.NewVariable("1404837029582986528"), gl.NewVariable("9377230983302764181")}, |
|||
{gl.NewVariable("7086781234814455260"), gl.NewVariable("7571558192372650697")}, |
|||
{gl.NewVariable("5627013434503229817"), gl.NewVariable("14984048934926143304")}, |
|||
{gl.NewVariable("2115495655441739405"), gl.NewVariable("1656704965110317534")}, |
|||
{gl.NewVariable("2311846135199651566"), gl.NewVariable("17438437808346967358")}, |
|||
{gl.NewVariable("8679806319651401773"), gl.NewVariable("3278538718508560579")}, |
|||
{gl.NewVariable("7897681105604536660"), gl.NewVariable("10966573925848082711")}, |
|||
{gl.NewVariable("5451958405177630542"), gl.NewVariable("9207735009647199721")}, |
|||
{gl.NewVariable("8825486358121162697"), gl.NewVariable("15997852519026522914")}, |
|||
{gl.NewVariable("475225211669491693"), gl.NewVariable("1907827506180042626")}, |
|||
{gl.NewVariable("16033031089519343732"), gl.NewVariable("15009948832718035672")}, |
|||
{gl.NewVariable("5048598591200038865"), gl.NewVariable("156574475928756206")}, |
|||
{gl.NewVariable("3580311624647961767"), gl.NewVariable("6084715537433906996")}, |
|||
{gl.NewVariable("9121009921295095324"), gl.NewVariable("18407759801432275235")}, |
|||
{gl.NewVariable("16569013039730214123"), gl.NewVariable("3930908108224055041")}, |
|||
{gl.NewVariable("13844066138909451365"), gl.NewVariable("6585754647203519368")}, |
|||
{gl.NewVariable("14133345335167543367"), gl.NewVariable("3946807387480232364")}, |
|||
{gl.NewVariable("9876285028806980582"), gl.NewVariable("40898067822033734")}, |
|||
{gl.NewVariable("6293483059765701407"), gl.NewVariable("16009270905706605849")}, |
|||
{gl.NewVariable("11635947241393753594"), gl.NewVariable("5053395178858294866")}, |
|||
{gl.NewVariable("16062194595705166277"), gl.NewVariable("752574348595159408")}, |
|||
{gl.NewVariable("15607597716340375230"), gl.NewVariable("10428583315124220143")}, |
|||
{gl.NewVariable("6975301479426228318"), gl.NewVariable("16528136630898216147")}, |
|||
{gl.NewVariable("16312827398430223622"), gl.NewVariable("17909475722464415780")}, |
|||
{gl.NewVariable("2273087545743905667"), gl.NewVariable("12405446777919046866")}, |
|||
{gl.NewVariable("14781933506876191161"), gl.NewVariable("4464109151368149713")}, |
|||
{gl.NewVariable("4226716729950095934"), gl.NewVariable("8908251769229049654")}, |
|||
{gl.NewVariable("8310476487592089883"), gl.NewVariable("3834672170570438819")}, |
|||
{gl.NewVariable("4285568636604940795"), gl.NewVariable("7183765355016179794")}, |
|||
{gl.NewVariable("14300853697824059506"), gl.NewVariable("16287477445929928328")}, |
|||
{gl.NewVariable("1238186507267033247"), gl.NewVariable("12357102109973664962")}, |
|||
{gl.NewVariable("15607388919140050768"), gl.NewVariable("15421065238069253306")}, |
|||
{gl.NewVariable("12418734453826432586"), gl.NewVariable("12072056126139297564")}, |
|||
{gl.NewVariable("3924467115116313620"), gl.NewVariable("1212362379653628161")}, |
|||
{gl.NewVariable("8252514850759544679"), gl.NewVariable("7893938436444134034")}, |
|||
{gl.NewVariable("711675815009325200"), gl.NewVariable("15678724077367989757")}, |
|||
{gl.NewVariable("10920573406841924033"), gl.NewVariable("8189696933773246220")}, |
|||
{gl.NewVariable("9737295100232588618"), gl.NewVariable("13383462338120177171")}, |
|||
{gl.NewVariable("8983013033045953935"), gl.NewVariable("5301160793103788033")}, |
|||
{gl.NewVariable("2086512740154274197"), gl.NewVariable("9511985884344255651")}, |
|||
{gl.NewVariable("7404726366142548080"), gl.NewVariable("11257391295697140486")}, |
|||
{gl.NewVariable("10045968629671906256"), gl.NewVariable("10721172752468420959")}, |
|||
{gl.NewVariable("9499240237398016191"), gl.NewVariable("17996498955496851489")}, |
|||
} |
|||
|
|||
// ReducingGate { num_coeffs: 44 }
|
|||
var reducingGateExpectedConstraints = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("4189565386714553574"), gl.NewVariable("14972099283023295929")}, |
|||
{gl.NewVariable("4811224976739448335"), gl.NewVariable("17901409314576454439")}, |
|||
{gl.NewVariable("5140059407491502784"), gl.NewVariable("1144330742785924570")}, |
|||
{gl.NewVariable("7077436393778991453"), gl.NewVariable("13398199711778224412")}, |
|||
{gl.NewVariable("11213768990622043903"), gl.NewVariable("3886053425349218150")}, |
|||
{gl.NewVariable("2946099412905029571"), gl.NewVariable("16515307040211357295")}, |
|||
{gl.NewVariable("11766152895257088950"), gl.NewVariable("12561350435611412995")}, |
|||
{gl.NewVariable("15559670172179416359"), gl.NewVariable("14246884723129607378")}, |
|||
{gl.NewVariable("5240707719525548158"), gl.NewVariable("1640773599873992510")}, |
|||
{gl.NewVariable("14358821079049832289"), gl.NewVariable("2746855687282611080")}, |
|||
{gl.NewVariable("3214086216088588558"), gl.NewVariable("1520697626094905530")}, |
|||
{gl.NewVariable("9834748172213967248"), gl.NewVariable("13487010468070558667")}, |
|||
{gl.NewVariable("1423442768503334248"), gl.NewVariable("10945790255819476518")}, |
|||
{gl.NewVariable("2308372186436983690"), gl.NewVariable("8803174935784778070")}, |
|||
{gl.NewVariable("9995833078447025147"), gl.NewVariable("9074310518079663649")}, |
|||
{gl.NewVariable("14149697874498108875"), gl.NewVariable("15875817120435194028")}, |
|||
{gl.NewVariable("14564758547073982656"), gl.NewVariable("13386335755835868953")}, |
|||
{gl.NewVariable("6432745607675418074"), gl.NewVariable("8030247499566565321")}, |
|||
{gl.NewVariable("17308235779926438117"), gl.NewVariable("16843697410674499818")}, |
|||
{gl.NewVariable("15507223129386571868"), gl.NewVariable("3935281607585552366")}, |
|||
{gl.NewVariable("16041402982622709805"), gl.NewVariable("12432717078068957835")}, |
|||
{gl.NewVariable("6455955094164032063"), gl.NewVariable("2435635342699968412")}, |
|||
{gl.NewVariable("9814981570869789379"), gl.NewVariable("5009257884262115226")}, |
|||
{gl.NewVariable("9452031978763862902"), gl.NewVariable("15609083603899848676")}, |
|||
{gl.NewVariable("13532623109002857304"), gl.NewVariable("7324541443245949391")}, |
|||
{gl.NewVariable("7899075212455453622"), gl.NewVariable("14276489152002439614")}, |
|||
{gl.NewVariable("2403019844704266911"), gl.NewVariable("5922544710604013781")}, |
|||
{gl.NewVariable("9709471021111675830"), gl.NewVariable("5538539165068927028")}, |
|||
{gl.NewVariable("15700585567216041265"), gl.NewVariable("17893894492159337326")}, |
|||
{gl.NewVariable("8890003199638063977"), gl.NewVariable("17726621767321974437")}, |
|||
{gl.NewVariable("389239919653982052"), gl.NewVariable("3497778410650283061")}, |
|||
{gl.NewVariable("845227572644858827"), gl.NewVariable("7040344997713673855")}, |
|||
{gl.NewVariable("9861253052349275208"), gl.NewVariable("1880449137233040023")}, |
|||
{gl.NewVariable("9239454143759318515"), gl.NewVariable("7968256557482935820")}, |
|||
{gl.NewVariable("12576879243038758854"), gl.NewVariable("9784626207087825707")}, |
|||
{gl.NewVariable("14811673587164089973"), gl.NewVariable("10785522535030299714")}, |
|||
{gl.NewVariable("696437091186897361"), gl.NewVariable("13293602092569033065")}, |
|||
{gl.NewVariable("1240161179290551759"), gl.NewVariable("9542275505416038259")}, |
|||
{gl.NewVariable("5298553932515957396"), gl.NewVariable("14597738151157731445")}, |
|||
{gl.NewVariable("8472517818840783225"), gl.NewVariable("7685861056688910111")}, |
|||
{gl.NewVariable("10067665523858551777"), gl.NewVariable("13019870415534016025")}, |
|||
{gl.NewVariable("3030966178198674680"), gl.NewVariable("10107838846102885642")}, |
|||
{gl.NewVariable("6762889891370677550"), gl.NewVariable("16151528872832782368")}, |
|||
{gl.NewVariable("17207754552662723664"), gl.NewVariable("15168039969859158460")}, |
|||
{gl.NewVariable("9111161782199179468"), gl.NewVariable("8010960876261510099")}, |
|||
{gl.NewVariable("1212079098724692260"), gl.NewVariable("3976842077579916925")}, |
|||
{gl.NewVariable("8111924351272477885"), gl.NewVariable("1472738463707044435")}, |
|||
{gl.NewVariable("14549763060495382561"), gl.NewVariable("8148654488443197206")}, |
|||
{gl.NewVariable("9633247645878352168"), gl.NewVariable("4173826759172401145")}, |
|||
{gl.NewVariable("13429667484612728110"), gl.NewVariable("139708813783643870")}, |
|||
{gl.NewVariable("11164941208889426013"), gl.NewVariable("3615779386887825309")}, |
|||
{gl.NewVariable("15733773570058687441"), gl.NewVariable("11172582394325691371")}, |
|||
{gl.NewVariable("11237663549079845099"), gl.NewVariable("375954911737718734")}, |
|||
{gl.NewVariable("14815280969174152094"), gl.NewVariable("17903238907570421232")}, |
|||
{gl.NewVariable("12264332321023153985"), gl.NewVariable("4996015210046477989")}, |
|||
{gl.NewVariable("5733452693326962912"), gl.NewVariable("15445457134261228447")}, |
|||
{gl.NewVariable("11339891595047637420"), gl.NewVariable("762619178430884475")}, |
|||
{gl.NewVariable("10413672060220880988"), gl.NewVariable("2522708614237496949")}, |
|||
{gl.NewVariable("4759794002943168525"), gl.NewVariable("8366670758049431064")}, |
|||
{gl.NewVariable("11081128192182141387"), gl.NewVariable("5264843790841556843")}, |
|||
{gl.NewVariable("16467547707866820269"), gl.NewVariable("10395994280728082037")}, |
|||
{gl.NewVariable("7372902852922723938"), gl.NewVariable("6597057511414169148")}, |
|||
{gl.NewVariable("1246550990665510080"), gl.NewVariable("369146659419534786")}, |
|||
{gl.NewVariable("107137977263990694"), gl.NewVariable("13480217899797734610")}, |
|||
{gl.NewVariable("9352391006524927052"), gl.NewVariable("16474580549927501346")}, |
|||
{gl.NewVariable("11475195577527382963"), gl.NewVariable("16771481018793784004")}, |
|||
{gl.NewVariable("7763817490144412733"), gl.NewVariable("7847907679735875325")}, |
|||
{gl.NewVariable("6954934416977006194"), gl.NewVariable("1588175103882481774")}, |
|||
{gl.NewVariable("208699790124989138"), gl.NewVariable("104050776110144395")}, |
|||
{gl.NewVariable("1999712470949493845"), gl.NewVariable("14640293671425837284")}, |
|||
{gl.NewVariable("17489389210332023693"), gl.NewVariable("1485853484717956236")}, |
|||
{gl.NewVariable("13389678828109836153"), gl.NewVariable("12239927773742888217")}, |
|||
{gl.NewVariable("7279356606052782033"), gl.NewVariable("16889809967345118643")}, |
|||
{gl.NewVariable("5530632913824527303"), gl.NewVariable("6593916246324540830")}, |
|||
{gl.NewVariable("6517985275757881887"), gl.NewVariable("1094679265639341934")}, |
|||
{gl.NewVariable("16005022297334791008"), gl.NewVariable("2231375568117939019")}, |
|||
{gl.NewVariable("7801581545066110268"), gl.NewVariable("16195585011186011335")}, |
|||
{gl.NewVariable("2346311239309318787"), gl.NewVariable("10194252071441594046")}, |
|||
{gl.NewVariable("1333414916806612489"), gl.NewVariable("4078668601880487193")}, |
|||
{gl.NewVariable("17162202837341088150"), gl.NewVariable("3946492721743094611")}, |
|||
{gl.NewVariable("2372952988964786162"), gl.NewVariable("14459600129361968991")}, |
|||
{gl.NewVariable("15958985504784681452"), gl.NewVariable("18297567352909625870")}, |
|||
{gl.NewVariable("5468110010239944205"), gl.NewVariable("1297673223075459793")}, |
|||
{gl.NewVariable("5916958362061888790"), gl.NewVariable("12686064186569549334")}, |
|||
{gl.NewVariable("17141186363273294375"), gl.NewVariable("5330662447468959333")}, |
|||
{gl.NewVariable("9597329746711776008"), gl.NewVariable("13290917949843243492")}, |
|||
{gl.NewVariable("9061260430036409956"), gl.NewVariable("10642927510372211646")}, |
|||
{gl.NewVariable("9766392710518436993"), gl.NewVariable("1864738510099355769")}, |
|||
} |
|||
|
|||
// ArithmeticExtensionGate { num_ops: 10 }
|
|||
var arithmeticExtensionGateExpectedConstraints = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("14556369430662721230"), gl.NewVariable("4131185000258568561")}, |
|||
{gl.NewVariable("16378466706564867046"), gl.NewVariable("1439052841211884527")}, |
|||
{gl.NewVariable("8231479592213172392"), gl.NewVariable("8409169031581010782")}, |
|||
{gl.NewVariable("5465959779370835700"), gl.NewVariable("17016702720873000919")}, |
|||
{gl.NewVariable("10611951970626560747"), gl.NewVariable("11015475306668399283")}, |
|||
{gl.NewVariable("6566683434087540889"), gl.NewVariable("7528162900166069532")}, |
|||
{gl.NewVariable("13167150559619768862"), gl.NewVariable("15618445283750881414")}, |
|||
{gl.NewVariable("14768578132422983729"), gl.NewVariable("13938407401080069149")}, |
|||
{gl.NewVariable("18415232841919605685"), gl.NewVariable("15088528771916927003")}, |
|||
{gl.NewVariable("1305736199568141897"), gl.NewVariable("16885250849392919438")}, |
|||
{gl.NewVariable("1425549592953864549"), gl.NewVariable("1074162823816629148")}, |
|||
{gl.NewVariable("12616210534513128803"), gl.NewVariable("8618852250387339753")}, |
|||
{gl.NewVariable("16775588216530426832"), gl.NewVariable("16358913853138883160")}, |
|||
{gl.NewVariable("236831045676808583"), gl.NewVariable("16231688985959438642")}, |
|||
{gl.NewVariable("264831195814170716"), gl.NewVariable("9852325877887114505")}, |
|||
{gl.NewVariable("14065541678187010167"), gl.NewVariable("5594602585697559035")}, |
|||
{gl.NewVariable("2354884863196165822"), gl.NewVariable("12715102096346587892")}, |
|||
{gl.NewVariable("5881791209743274427"), gl.NewVariable("1913490798645218291")}, |
|||
{gl.NewVariable("3621056055759314065"), gl.NewVariable("15076066883455218113")}, |
|||
{gl.NewVariable("15382741815013668685"), gl.NewVariable("5674166256062091576")}, |
|||
} |
|||
|
|||
// MulExtensionGate { num_ops: 13 }
|
|||
var mulExtensionGateExpectedConstraints = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("14558272317822654580"), gl.NewVariable("833215892324477732")}, |
|||
{gl.NewVariable("9214806296346539012"), gl.NewVariable("7798842673847612486")}, |
|||
{gl.NewVariable("4933313819253472884"), gl.NewVariable("17115399133104593821")}, |
|||
{gl.NewVariable("6382294466663581729"), gl.NewVariable("8863722647290983592")}, |
|||
{gl.NewVariable("5274430631758054179"), gl.NewVariable("1761561038204031519")}, |
|||
{gl.NewVariable("6975818216493368257"), gl.NewVariable("3643153118790582585")}, |
|||
{gl.NewVariable("9382708770545050748"), gl.NewVariable("2040988809014144797")}, |
|||
{gl.NewVariable("7526300035416853327"), gl.NewVariable("8692405747344509879")}, |
|||
{gl.NewVariable("6092157877842311771"), gl.NewVariable("5767914690949635280")}, |
|||
{gl.NewVariable("3636879736078164520"), gl.NewVariable("454792903724498694")}, |
|||
{gl.NewVariable("5982213211108308130"), gl.NewVariable("3906161453783544349")}, |
|||
{gl.NewVariable("1353999567434327832"), gl.NewVariable("3912356165392315450")}, |
|||
{gl.NewVariable("3866250282554618990"), gl.NewVariable("14215790041865539111")}, |
|||
{gl.NewVariable("16972659905821970574"), gl.NewVariable("2550277288305104044")}, |
|||
{gl.NewVariable("6739526869755283609"), gl.NewVariable("4676222628249438354")}, |
|||
{gl.NewVariable("18314541579046409607"), gl.NewVariable("13871312232745645647")}, |
|||
{gl.NewVariable("13309435341537760906"), gl.NewVariable("10879629980202564460")}, |
|||
{gl.NewVariable("8149445702527176593"), gl.NewVariable("12079787385488004774")}, |
|||
{gl.NewVariable("141936326832390573"), gl.NewVariable("9852981409020916366")}, |
|||
{gl.NewVariable("1174277439708011834"), gl.NewVariable("11084240604056156653")}, |
|||
{gl.NewVariable("3890191667424476902"), gl.NewVariable("1428130379783403165")}, |
|||
{gl.NewVariable("18264002552181363059"), gl.NewVariable("17855293364353531924")}, |
|||
{gl.NewVariable("1657518282890904146"), gl.NewVariable("14874491364689193658")}, |
|||
{gl.NewVariable("9091236796792826297"), gl.NewVariable("18232800981045995203")}, |
|||
{gl.NewVariable("7965395014621568897"), gl.NewVariable("15643014489741966811")}, |
|||
{gl.NewVariable("14048129594584036134"), gl.NewVariable("8880723489474532129")}, |
|||
} |
|||
|
|||
// CosetInterpolationGate { subgroup_bits: 4, degree: 6, barycentric_weights: [17293822565076172801, 18374686475376656385, 18446744069413535745, 281474976645120, 17592186044416, 18446744069414584577, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 18446744069415632897, 18446462594437939201, 18446726477228539905, 18446744069414584065, 68719476720, 4294967296], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
|
|||
var cosetInterpolationGateExpectedConstraints = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("4489474937116132272"), gl.NewVariable("17966585078409280607")}, |
|||
{gl.NewVariable("6284821823752419954"), gl.NewVariable("15732864946173560339")}, |
|||
{gl.NewVariable("12879723719779486283"), gl.NewVariable("983649133858104142")}, |
|||
{gl.NewVariable("17293136937393925432"), gl.NewVariable("4033193666483141970")}, |
|||
{gl.NewVariable("10809912963683055710"), gl.NewVariable("3166226310305151244")}, |
|||
{gl.NewVariable("13051854837169808452"), gl.NewVariable("12636844243964449888")}, |
|||
{gl.NewVariable("15180422697988222141"), gl.NewVariable("3172471974421734205")}, |
|||
{gl.NewVariable("7715327263429433235"), gl.NewVariable("14269461688353925342")}, |
|||
{gl.NewVariable("7348198793616724228"), gl.NewVariable("11426363269581761252")}, |
|||
{gl.NewVariable("6529761710182712179"), gl.NewVariable("15370899814178958348")}, |
|||
{gl.NewVariable("1312640305437468539"), gl.NewVariable("7416725026793550034")}, |
|||
{gl.NewVariable("7435934314089172319"), gl.NewVariable("8931511780309647479")}, |
|||
} |
|||
|
|||
// PoseidonMdsGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>"
|
|||
var poseidonMdsGateExpectedConstraints = []gl.QuadraticExtensionVariable{ |
|||
{gl.NewVariable("7821764612044984890"), gl.NewVariable("11645399715550800761")}, |
|||
{gl.NewVariable("7054686226368496581"), gl.NewVariable("3456599659382547499")}, |
|||
{gl.NewVariable("9932401212201586910"), gl.NewVariable("15935184283784595275")}, |
|||
{gl.NewVariable("14850232436396031573"), gl.NewVariable("10054869170615550942")}, |
|||
{gl.NewVariable("17859784214232634920"), gl.NewVariable("3141019307077014353")}, |
|||
{gl.NewVariable("1316926243065869924"), gl.NewVariable("5447399801288094074")}, |
|||
{gl.NewVariable("12198784876096903918"), gl.NewVariable("10976551553233951532")}, |
|||
{gl.NewVariable("3280500541526908156"), gl.NewVariable("1813330468204166522")}, |
|||
{gl.NewVariable("6788483962196012692"), gl.NewVariable("15983747071745976199")}, |
|||
{gl.NewVariable("3372073447943379816"), gl.NewVariable("9356836818900551936")}, |
|||
{gl.NewVariable("13834815153351545489"), gl.NewVariable("1073963211629459057")}, |
|||
{gl.NewVariable("15376716257200419051"), gl.NewVariable("16044430964768811142")}, |
|||
{gl.NewVariable("16752138206727891451"), gl.NewVariable("6303059651352280564")}, |
|||
{gl.NewVariable("17195959285241102556"), gl.NewVariable("10990140109461952122")}, |
|||
{gl.NewVariable("16812594260057394716"), gl.NewVariable("5841834090350584793")}, |
|||
{gl.NewVariable("17706037262140285164"), gl.NewVariable("8626184557677598926")}, |
|||
{gl.NewVariable("6826825357492466350"), gl.NewVariable("17865947929743097490")}, |
|||
{gl.NewVariable("13679887869755160737"), gl.NewVariable("16481628195512675795")}, |
|||
{gl.NewVariable("7881296289635150478"), gl.NewVariable("15368930380652981390")}, |
|||
{gl.NewVariable("12075171536836315078"), gl.NewVariable("12900345753644751245")}, |
|||
{gl.NewVariable("11461113822534614109"), gl.NewVariable("2937306395206947398")}, |
|||
{gl.NewVariable("18365572828001780476"), gl.NewVariable("4309067613742479326")}, |
|||
{gl.NewVariable("9460729461000852035"), gl.NewVariable("9232487430983842586")}, |
|||
{gl.NewVariable("9920817005263779727"), gl.NewVariable("16326126591726196229")}, |
|||
} |
|||
|
|||
type TestGateCircuit struct { |
|||
testGate gates.Gate |
|||
ExpectedConstraints []gl.QuadraticExtensionVariable |
|||
} |
|||
|
|||
func (circuit *TestGateCircuit) Define(api frontend.API) error { |
|||
commonCircuitData := verifier.DeserializeCommonCircuitData("../../data/decode_block/common_circuit_data.json") |
|||
numSelectors := commonCircuitData.SelectorsInfo.NumSelectors() |
|||
|
|||
glApi := gl.NewChip(api) |
|||
|
|||
vars := gates.NewEvaluationVars(localConstants[numSelectors:], localWires, publicInputsHash) |
|||
|
|||
constraints := circuit.testGate.EvalUnfiltered(api, *glApi, *vars) |
|||
|
|||
if len(constraints) != len(circuit.ExpectedConstraints) { |
|||
return errors.New("gate constraints length mismatch") |
|||
} |
|||
for i := 0; i < len(constraints); i++ { |
|||
glApi.AssertIsEqualExtension(constraints[i], circuit.ExpectedConstraints[i]) |
|||
} |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func TestGates(t *testing.T) { |
|||
assert := test.NewAssert(t) |
|||
|
|||
testCase := func(testGate gates.Gate, expectedConstraints []gl.QuadraticExtensionVariable) { |
|||
circuit := &TestGateCircuit{testGate: testGate, ExpectedConstraints: expectedConstraints} |
|||
witness := &TestGateCircuit{testGate: testGate, ExpectedConstraints: expectedConstraints} |
|||
err := test.IsSolved(circuit, witness, ecc.BN254.ScalarField()) |
|||
assert.NoError(err) |
|||
} |
|||
|
|||
type gateTest struct { |
|||
testGate gates.Gate |
|||
expectedConstraints []gl.QuadraticExtensionVariable |
|||
} |
|||
|
|||
gateTests := []gateTest{ |
|||
{gates.NewPublicInputGate(), publicInputGateExpectedConstraints}, |
|||
{gates.NewBaseSumGate(63, 2), baseSumGateExpectedConstraints}, |
|||
{gates.NewArithmeticGate(20), arithmeticGateExpectedConstraints}, |
|||
{gates.NewRandomAccessGate(4, 4, 2), randomAccessGateExpectedConstraints}, |
|||
{gates.NewPoseidonGate(), poseidonGateExpectedConstraints}, |
|||
{gates.NewArithmeticExtensionGate(10), arithmeticExtensionGateExpectedConstraints}, |
|||
{gates.NewMultiplicationExtensionGate(13), mulExtensionGateExpectedConstraints}, |
|||
{gates.NewReducingExtensionGate(33), reducingExtensionGateExpectedConstraints}, |
|||
{gates.NewReducingGate(44), reducingGateExpectedConstraints}, |
|||
{gates.NewCosetInterpolationGate( |
|||
4, |
|||
6, |
|||
[]goldilocks.Element{ |
|||
goldilocks.NewElement(17293822565076172801), |
|||
goldilocks.NewElement(18374686475376656385), |
|||
goldilocks.NewElement(18446744069413535745), |
|||
goldilocks.NewElement(281474976645120), |
|||
goldilocks.NewElement(17592186044416), |
|||
goldilocks.NewElement(18446744069414584577), |
|||
goldilocks.NewElement(18446744000695107601), |
|||
goldilocks.NewElement(18446744065119617025), |
|||
goldilocks.NewElement(1152921504338411520), |
|||
goldilocks.NewElement(72057594037927936), |
|||
goldilocks.NewElement(18446744069415632897), |
|||
goldilocks.NewElement(18446462594437939201), |
|||
goldilocks.NewElement(18446726477228539905), |
|||
goldilocks.NewElement(18446744069414584065), |
|||
goldilocks.NewElement(68719476720), |
|||
goldilocks.NewElement(4294967296), |
|||
}, |
|||
), cosetInterpolationGateExpectedConstraints}, |
|||
{&gates.PoseidonMdsGate{}, poseidonMdsGateExpectedConstraints}, |
|||
} |
|||
|
|||
for _, test := range gateTests { |
|||
testCase( |
|||
test.testGate, |
|||
test.expectedConstraints, |
|||
) |
|||
} |
|||
} |
|||
@ -0,0 +1,204 @@ |
|||
package poseidon |
|||
|
|||
// This is a customized implementation of the Poseidon hash function inside the BN254 field.
|
|||
// This implementation is based on the following implementation:
|
|||
//
|
|||
// https://github.com/iden3/go-iden3-crypto/blob/master/poseidon/poseidon.go
|
|||
//
|
|||
// The input and output are modified to ingest Goldilocks field elements.
|
|||
|
|||
import ( |
|||
"math/big" |
|||
|
|||
"github.com/consensys/gnark/frontend" |
|||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
) |
|||
|
|||
const BN254_FULL_ROUNDS int = 8 |
|||
const BN254_PARTIAL_ROUNDS int = 56 |
|||
const BN254_SPONGE_WIDTH int = 4 |
|||
const BN254_SPONGE_RATE int = 3 |
|||
|
|||
type BN254Chip struct { |
|||
api frontend.API `gnark:"-"` |
|||
gl gl.Chip `gnark:"-"` |
|||
} |
|||
|
|||
type BN254State = [BN254_SPONGE_WIDTH]frontend.Variable |
|||
type BN254HashOut = frontend.Variable |
|||
|
|||
func NewBN254Chip(api frontend.API) *BN254Chip { |
|||
return &BN254Chip{api: api, gl: *gl.NewChip(api)} |
|||
} |
|||
|
|||
func (c *BN254Chip) Poseidon(state BN254State) BN254State { |
|||
state = c.ark(state, 0) |
|||
state = c.fullRounds(state, true) |
|||
state = c.partialRounds(state) |
|||
state = c.fullRounds(state, false) |
|||
return state |
|||
} |
|||
|
|||
func (c *BN254Chip) HashNoPad(input []gl.Variable) BN254HashOut { |
|||
state := BN254State{ |
|||
frontend.Variable(0), |
|||
frontend.Variable(0), |
|||
frontend.Variable(0), |
|||
frontend.Variable(0), |
|||
} |
|||
|
|||
for i := 0; i < len(input); i += BN254_SPONGE_RATE * 3 { |
|||
endI := c.min(len(input), i+BN254_SPONGE_RATE*3) |
|||
rateChunk := input[i:endI] |
|||
for j, stateIdx := 0, 0; j < len(rateChunk); j, stateIdx = j+3, stateIdx+1 { |
|||
endJ := c.min(len(rateChunk), j+3) |
|||
bn254Chunk := rateChunk[j:endJ] |
|||
|
|||
bits := []frontend.Variable{} |
|||
for k := 0; k < len(bn254Chunk); k++ { |
|||
bn254Chunk[k] = c.gl.Reduce(bn254Chunk[k]) |
|||
bits = append(bits, c.api.ToBinary(bn254Chunk[k].Limb, 64)...) |
|||
} |
|||
|
|||
state[stateIdx+1] = c.api.FromBinary(bits...) |
|||
} |
|||
|
|||
state = c.Poseidon(state) |
|||
} |
|||
|
|||
return BN254HashOut(state[0]) |
|||
} |
|||
|
|||
func (c *BN254Chip) HashOrNoop(input []gl.Variable) BN254HashOut { |
|||
if len(input) <= 3 { |
|||
returnVal := frontend.Variable(0) |
|||
|
|||
alpha := new(big.Int).SetInt64(1 << 32) |
|||
for i, inputElement := range input { |
|||
returnVal = c.api.Add(returnVal, c.api.Mul(inputElement, alpha.Exp(alpha, big.NewInt(int64(i)), nil))) |
|||
} |
|||
|
|||
return BN254HashOut(returnVal) |
|||
} else { |
|||
return c.HashNoPad(input) |
|||
} |
|||
} |
|||
|
|||
func (c *BN254Chip) TwoToOne(left BN254HashOut, right BN254HashOut) BN254HashOut { |
|||
var inputs BN254State |
|||
inputs[0] = frontend.Variable(0) |
|||
inputs[1] = frontend.Variable(0) |
|||
inputs[2] = left |
|||
inputs[3] = right |
|||
state := c.Poseidon(inputs) |
|||
return state[0] |
|||
} |
|||
|
|||
func (c *BN254Chip) ToVec(hash BN254HashOut) []gl.Variable { |
|||
bits := c.api.ToBinary(hash) |
|||
|
|||
returnElements := []gl.Variable{} |
|||
|
|||
// Split into 7 byte chunks, since 8 byte chunks can result in collisions
|
|||
chunkSize := 56 |
|||
for i := 0; i < len(bits); i += chunkSize { |
|||
maxIdx := c.min(len(bits), i+chunkSize) |
|||
bitChunk := bits[i:maxIdx] |
|||
returnElements = append(returnElements, gl.NewVariable(c.api.FromBinary(bitChunk...))) |
|||
} |
|||
|
|||
return returnElements |
|||
} |
|||
|
|||
func (c *BN254Chip) min(x, y int) int { |
|||
if x < y { |
|||
return x |
|||
} |
|||
|
|||
return y |
|||
} |
|||
|
|||
func (c *BN254Chip) fullRounds(state BN254State, isFirst bool) BN254State { |
|||
for i := 0; i < BN254_FULL_ROUNDS/2-1; i++ { |
|||
state = c.exp5state(state) |
|||
if isFirst { |
|||
state = c.ark(state, (i+1)*BN254_SPONGE_WIDTH) |
|||
} else { |
|||
state = c.ark(state, (BN254_FULL_ROUNDS/2+1)*BN254_SPONGE_WIDTH+BN254_PARTIAL_ROUNDS+i*BN254_SPONGE_WIDTH) |
|||
} |
|||
state = c.mix(state, mMatrix) |
|||
} |
|||
|
|||
state = c.exp5state(state) |
|||
if isFirst { |
|||
state = c.ark(state, (BN254_FULL_ROUNDS/2)*BN254_SPONGE_WIDTH) |
|||
state = c.mix(state, pMatrix) |
|||
} else { |
|||
state = c.mix(state, mMatrix) |
|||
} |
|||
|
|||
return state |
|||
} |
|||
|
|||
func (c *BN254Chip) partialRounds(state BN254State) BN254State { |
|||
for i := 0; i < BN254_PARTIAL_ROUNDS; i++ { |
|||
state[0] = c.exp5(state[0]) |
|||
state[0] = c.api.Add(state[0], cConstants[(BN254_FULL_ROUNDS/2+1)*BN254_SPONGE_WIDTH+i]) |
|||
|
|||
var mul frontend.Variable |
|||
newState0 := frontend.Variable(0) |
|||
for j := 0; j < BN254_SPONGE_WIDTH; j++ { |
|||
mul = c.api.Mul(sConstants[(BN254_SPONGE_WIDTH*2-1)*i+j], state[j]) |
|||
newState0 = c.api.Add(newState0, mul) |
|||
} |
|||
|
|||
for k := 1; k < BN254_SPONGE_WIDTH; k++ { |
|||
mul = c.api.Mul(state[0], sConstants[(BN254_SPONGE_WIDTH*2-1)*i+BN254_SPONGE_WIDTH+k-1]) |
|||
state[k] = c.api.Add(state[k], mul) |
|||
} |
|||
state[0] = newState0 |
|||
} |
|||
|
|||
return state |
|||
} |
|||
|
|||
func (c *BN254Chip) ark(state BN254State, it int) BN254State { |
|||
var result BN254State |
|||
|
|||
for i := 0; i < len(state); i++ { |
|||
result[i] = c.api.Add(state[i], cConstants[it+i]) |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
func (c *BN254Chip) exp5(x frontend.Variable) frontend.Variable { |
|||
x2 := c.api.Mul(x, x) |
|||
x4 := c.api.Mul(x2, x2) |
|||
return c.api.Mul(x4, x) |
|||
} |
|||
|
|||
func (c *BN254Chip) exp5state(state BN254State) BN254State { |
|||
for i := 0; i < BN254_SPONGE_WIDTH; i++ { |
|||
state[i] = c.exp5(state[i]) |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *BN254Chip) mix(state_ BN254State, constantMatrix [][]*big.Int) BN254State { |
|||
var mul frontend.Variable |
|||
var result BN254State |
|||
|
|||
for i := 0; i < BN254_SPONGE_WIDTH; i++ { |
|||
result[i] = frontend.Variable(0) |
|||
} |
|||
|
|||
for i := 0; i < BN254_SPONGE_WIDTH; i++ { |
|||
for j := 0; j < BN254_SPONGE_WIDTH; j++ { |
|||
mul = c.api.Mul(constantMatrix[j][i], state_[j]) |
|||
result[i] = c.api.Add(result[i], mul) |
|||
} |
|||
} |
|||
|
|||
return result |
|||
} |
|||
@ -0,0 +1,357 @@ |
|||
package poseidon |
|||
|
|||
import ( |
|||
"github.com/consensys/gnark/frontend" |
|||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
) |
|||
|
|||
const HALF_N_FULL_ROUNDS = 4 |
|||
const N_PARTIAL_ROUNDS = 22 |
|||
const MAX_WIDTH = 12 |
|||
const SPONGE_WIDTH = 12 |
|||
const SPONGE_RATE = 8 |
|||
|
|||
type GoldilocksState = [SPONGE_WIDTH]gl.Variable |
|||
type GoldilocksStateExtension = [SPONGE_WIDTH]gl.QuadraticExtensionVariable |
|||
type GoldilocksHashOut = [4]gl.Variable |
|||
|
|||
type GoldilocksChip struct { |
|||
api frontend.API `gnark:"-"` |
|||
gl gl.Chip `gnark:"-"` |
|||
} |
|||
|
|||
func NewGoldilocksChip(api frontend.API) *GoldilocksChip { |
|||
return &GoldilocksChip{api: api, gl: *gl.NewChip(api)} |
|||
} |
|||
|
|||
// The permutation function.
|
|||
// The input state MUST have all it's elements be within Goldilocks field (e.g. this function will not reduce the input elements).
|
|||
// The returned state's elements will all be within Goldilocks field.
|
|||
func (c *GoldilocksChip) Poseidon(input GoldilocksState) GoldilocksState { |
|||
state := input |
|||
roundCounter := 0 |
|||
state = c.fullRounds(state, &roundCounter) |
|||
state = c.partialRounds(state, &roundCounter) |
|||
state = c.fullRounds(state, &roundCounter) |
|||
return state |
|||
} |
|||
|
|||
// The input elements MUST have all it's elements be within Goldilocks field.
|
|||
// The returned slice's elements will all be within Goldilocks field.
|
|||
func (c *GoldilocksChip) HashNToMNoPad(input []gl.Variable, nbOutputs int) []gl.Variable { |
|||
var state GoldilocksState |
|||
|
|||
for i := 0; i < SPONGE_WIDTH; i++ { |
|||
state[i] = gl.NewVariable(0) |
|||
} |
|||
|
|||
for i := 0; i < len(input); i += SPONGE_RATE { |
|||
for j := 0; j < SPONGE_RATE; j++ { |
|||
if i+j < len(input) { |
|||
state[j] = input[i+j] |
|||
} |
|||
} |
|||
state = c.Poseidon(state) |
|||
} |
|||
|
|||
var outputs []gl.Variable |
|||
|
|||
for { |
|||
for i := 0; i < SPONGE_RATE; i++ { |
|||
outputs = append(outputs, state[i]) |
|||
if len(outputs) == nbOutputs { |
|||
return outputs |
|||
} |
|||
} |
|||
state = c.Poseidon(state) |
|||
} |
|||
} |
|||
|
|||
// The input elements can be outside of the Goldilocks field.
|
|||
// The returned slice's elements will all be within Goldilocks field.
|
|||
func (c *GoldilocksChip) HashNoPad(input []gl.Variable) GoldilocksHashOut { |
|||
var hash GoldilocksHashOut |
|||
inputVars := []gl.Variable{} |
|||
|
|||
for i := 0; i < len(input); i++ { |
|||
inputVars = append(inputVars, c.gl.Reduce(input[i])) |
|||
} |
|||
|
|||
outputVars := c.HashNToMNoPad(inputVars, 4) |
|||
for i := 0; i < 4; i++ { |
|||
hash[i] = outputVars[i] |
|||
} |
|||
|
|||
return hash |
|||
} |
|||
|
|||
func (c *GoldilocksChip) ToVec(hash GoldilocksHashOut) []gl.Variable { |
|||
return hash[:] |
|||
} |
|||
|
|||
func (c *GoldilocksChip) fullRounds(state GoldilocksState, roundCounter *int) GoldilocksState { |
|||
for i := 0; i < HALF_N_FULL_ROUNDS; i++ { |
|||
state = c.constantLayer(state, roundCounter) |
|||
state = c.sBoxLayer(state) |
|||
state = c.mdsLayer(state) |
|||
*roundCounter += 1 |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *GoldilocksChip) partialRounds(state GoldilocksState, roundCounter *int) GoldilocksState { |
|||
state = c.partialFirstConstantLayer(state) |
|||
state = c.mdsPartialLayerInit(state) |
|||
|
|||
for i := 0; i < N_PARTIAL_ROUNDS; i++ { |
|||
state[0] = c.sBoxMonomial(state[0]) |
|||
state[0] = c.gl.Add(state[0], gl.NewVariable(FAST_PARTIAL_ROUND_CONSTANTS[i])) |
|||
state = c.mdsPartialLayerFast(state, i) |
|||
} |
|||
|
|||
*roundCounter += N_PARTIAL_ROUNDS |
|||
|
|||
return state |
|||
} |
|||
|
|||
func (c *GoldilocksChip) constantLayer(state GoldilocksState, roundCounter *int) GoldilocksState { |
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
roundConstant := ALL_ROUND_CONSTANTS[i+SPONGE_WIDTH*(*roundCounter)] |
|||
state[i] = c.gl.MulAdd(state[i], gl.NewVariable(1), gl.NewVariable(roundConstant)) |
|||
} |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *GoldilocksChip) ConstantLayerExtension(state GoldilocksStateExtension, roundCounter *int) GoldilocksStateExtension { |
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
roundConstant := gl.NewVariable(ALL_ROUND_CONSTANTS[i+SPONGE_WIDTH*(*roundCounter)]) |
|||
roundConstantQE := gl.NewQuadraticExtensionVariable(roundConstant, gl.Zero()) |
|||
state[i] = c.gl.AddExtension(state[i], roundConstantQE) |
|||
} |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *GoldilocksChip) sBoxMonomial(x gl.Variable) gl.Variable { |
|||
x2 := c.gl.MulNoReduce(x, x) |
|||
x3 := c.gl.MulNoReduce(x, x2) |
|||
x3 = c.gl.ReduceWithMaxBits(x3, 192) |
|||
x6 := c.gl.MulNoReduce(x3, x3) |
|||
x7 := c.gl.MulNoReduce(x, x6) |
|||
return c.gl.ReduceWithMaxBits(x7, 192) |
|||
} |
|||
|
|||
func (c *GoldilocksChip) SBoxMonomialExtension(x gl.QuadraticExtensionVariable) gl.QuadraticExtensionVariable { |
|||
x2 := c.gl.MulExtension(x, x) |
|||
x4 := c.gl.MulExtension(x2, x2) |
|||
x3 := c.gl.MulExtension(x, x2) |
|||
return c.gl.MulExtension(x4, x3) |
|||
} |
|||
|
|||
func (c *GoldilocksChip) sBoxLayer(state GoldilocksState) GoldilocksState { |
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
state[i] = c.sBoxMonomial(state[i]) |
|||
} |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *GoldilocksChip) SBoxLayerExtension(state GoldilocksStateExtension) GoldilocksStateExtension { |
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
state[i] = c.SBoxMonomialExtension(state[i]) |
|||
} |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *GoldilocksChip) mdsRowShf(r int, v [SPONGE_WIDTH]gl.Variable) gl.Variable { |
|||
res := gl.Zero() |
|||
|
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
res = c.gl.MulAddNoReduce(v[(i+r)%SPONGE_WIDTH], gl.NewVariable(MDS_MATRIX_CIRC_VARS[i]), res) |
|||
} |
|||
} |
|||
|
|||
res = c.gl.MulAddNoReduce(v[r], gl.NewVariable(MDS_MATRIX_DIAG_VARS[r]), res) |
|||
return c.gl.Reduce(res) |
|||
} |
|||
|
|||
func (c *GoldilocksChip) MdsRowShfExtension(r int, v [SPONGE_WIDTH]gl.QuadraticExtensionVariable) gl.QuadraticExtensionVariable { |
|||
res := gl.ZeroExtension() |
|||
|
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
matrixVal := gl.NewVariable(MDS_MATRIX_CIRC[i]) |
|||
matrixValQE := gl.NewQuadraticExtensionVariable(matrixVal, gl.Zero()) |
|||
res1 := c.gl.MulExtension(v[(i+r)%SPONGE_WIDTH], matrixValQE) |
|||
res = c.gl.AddExtension(res, res1) |
|||
} |
|||
} |
|||
|
|||
matrixVal := gl.NewVariable(MDS_MATRIX_DIAG[r]) |
|||
matrixValQE := gl.NewQuadraticExtensionVariable(matrixVal, gl.Zero()) |
|||
res = c.gl.AddExtension(res, c.gl.MulExtension(v[r], matrixValQE)) |
|||
return res |
|||
} |
|||
|
|||
func (c *GoldilocksChip) mdsLayer(state_ GoldilocksState) GoldilocksState { |
|||
var result GoldilocksState |
|||
for i := 0; i < SPONGE_WIDTH; i++ { |
|||
result[i] = gl.NewVariable(0) |
|||
} |
|||
|
|||
for r := 0; r < 12; r++ { |
|||
if r < SPONGE_WIDTH { |
|||
result[r] = c.mdsRowShf(r, state_) |
|||
} |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
func (c *GoldilocksChip) MdsLayerExtension(state_ GoldilocksStateExtension) GoldilocksStateExtension { |
|||
var result GoldilocksStateExtension |
|||
|
|||
for r := 0; r < 12; r++ { |
|||
if r < SPONGE_WIDTH { |
|||
sum := c.MdsRowShfExtension(r, state_) |
|||
result[r] = sum |
|||
} |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
func (c *GoldilocksChip) partialFirstConstantLayer(state GoldilocksState) GoldilocksState { |
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
state[i] = c.gl.Add(state[i], gl.NewVariable(FAST_PARTIAL_FIRST_ROUND_CONSTANT[i])) |
|||
} |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *GoldilocksChip) PartialFirstConstantLayerExtension(state GoldilocksStateExtension) GoldilocksStateExtension { |
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
fastPartialRoundConstant := gl.NewVariable(FAST_PARTIAL_FIRST_ROUND_CONSTANT[i]) |
|||
fastPartialRoundConstantQE := gl.NewQuadraticExtensionVariable(fastPartialRoundConstant, gl.Zero()) |
|||
state[i] = c.gl.AddExtension(state[i], fastPartialRoundConstantQE) |
|||
} |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *GoldilocksChip) mdsPartialLayerInit(state GoldilocksState) GoldilocksState { |
|||
var result GoldilocksState |
|||
for i := 0; i < 12; i++ { |
|||
result[i] = gl.NewVariable(0) |
|||
} |
|||
|
|||
result[0] = state[0] |
|||
|
|||
for r := 1; r < 12; r++ { |
|||
if r < SPONGE_WIDTH { |
|||
for d := 1; d < 12; d++ { |
|||
if d < SPONGE_WIDTH { |
|||
t := FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1] |
|||
result[d] = c.gl.MulAddNoReduce(state[r], gl.NewVariable(t), result[d]) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
for i := 0; i < 12; i++ { |
|||
result[i] = c.gl.Reduce(result[i]) |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
func (c *GoldilocksChip) MdsPartialLayerInitExtension(state GoldilocksStateExtension) GoldilocksStateExtension { |
|||
var result GoldilocksStateExtension |
|||
for i := 0; i < 12; i++ { |
|||
result[i] = gl.ZeroExtension() |
|||
} |
|||
|
|||
result[0] = state[0] |
|||
|
|||
for r := 1; r < 12; r++ { |
|||
if r < SPONGE_WIDTH { |
|||
for d := 1; d < 12; d++ { |
|||
if d < SPONGE_WIDTH { |
|||
t := gl.NewVariable(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1]) |
|||
tQE := gl.NewQuadraticExtensionVariable(t, gl.Zero()) |
|||
result[d] = c.gl.AddExtension(result[d], c.gl.MulExtension(state[r], tQE)) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
func (c *GoldilocksChip) mdsPartialLayerFast(state GoldilocksState, r int) GoldilocksState { |
|||
dSum := gl.Zero() |
|||
for i := 1; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
t := FAST_PARTIAL_ROUND_W_HATS_VARS[r][i-1] |
|||
dSum = c.gl.MulAddNoReduce(state[i], gl.NewVariable(t), dSum) |
|||
} |
|||
} |
|||
|
|||
d := c.gl.MulAddNoReduce(state[0], gl.NewVariable(MDS0TO0_VAR), dSum) |
|||
d = c.gl.Reduce(d) |
|||
|
|||
var result GoldilocksState |
|||
for i := 0; i < SPONGE_WIDTH; i++ { |
|||
result[i] = gl.NewVariable(0) |
|||
} |
|||
|
|||
result[0] = d |
|||
|
|||
for i := 1; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
t := FAST_PARTIAL_ROUND_VS[r][i-1] |
|||
result[i] = c.gl.MulAddNoReduce(state[0], gl.NewVariable(t), state[i]) |
|||
} |
|||
} |
|||
|
|||
for i := 0; i < len(state); i++ { |
|||
result[i] = c.gl.Reduce(result[i]) |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
func (c *GoldilocksChip) MdsPartialLayerFastExtension(state GoldilocksStateExtension, r int) GoldilocksStateExtension { |
|||
s0 := state[0] |
|||
mds0to0 := gl.NewVariable(MDS0TO0) |
|||
mds0to0QE := gl.NewQuadraticExtensionVariable(mds0to0, gl.Zero()) |
|||
d := c.gl.MulExtension(s0, mds0to0QE) |
|||
for i := 1; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
t := gl.NewVariable(FAST_PARTIAL_ROUND_W_HATS[r][i-1]) |
|||
tQE := gl.NewQuadraticExtensionVariable(t, gl.Zero()) |
|||
d = c.gl.AddExtension(d, c.gl.MulExtension(state[i], tQE)) |
|||
} |
|||
} |
|||
|
|||
var result GoldilocksStateExtension |
|||
result[0] = d |
|||
for i := 1; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
t := gl.NewVariable(FAST_PARTIAL_ROUND_VS[r][i-1]) |
|||
tQE := gl.NewQuadraticExtensionVariable(t, gl.Zero()) |
|||
result[i] = c.gl.AddExtension(c.gl.MulExtension(state[0], tQE), state[i]) |
|||
} |
|||
} |
|||
|
|||
return result |
|||
} |
|||
@ -1,338 +0,0 @@ |
|||
package poseidon |
|||
|
|||
import ( |
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/field" |
|||
) |
|||
|
|||
const HALF_N_FULL_ROUNDS = 4 |
|||
const N_PARTIAL_ROUNDS = 22 |
|||
const MAX_WIDTH = 12 |
|||
const SPONGE_WIDTH = 12 |
|||
const SPONGE_RATE = 8 |
|||
|
|||
type PoseidonState = [SPONGE_WIDTH]frontend.Variable |
|||
type PoseidonStateExtension = [SPONGE_WIDTH]field.QuadraticExtension |
|||
type PoseidonHashOut = [4]field.F |
|||
|
|||
type PoseidonChip struct { |
|||
api frontend.API `gnark:"-"` |
|||
fieldAPI field.FieldAPI `gnark:"-"` |
|||
qeAPI *field.QuadraticExtensionAPI `gnark:"-"` |
|||
} |
|||
|
|||
func NewPoseidonChip(api frontend.API, fieldAPI field.FieldAPI, qeAPI *field.QuadraticExtensionAPI) *PoseidonChip { |
|||
return &PoseidonChip{api: api, fieldAPI: fieldAPI, qeAPI: qeAPI} |
|||
} |
|||
|
|||
// The permutation function.
|
|||
// The input state MUST have all it's elements be within Goldilocks field (e.g. this function will not reduce the input elements).
|
|||
// The returned state's elements will all be within Goldilocks field.
|
|||
func (c *PoseidonChip) Poseidon(input PoseidonState) PoseidonState { |
|||
state := input |
|||
roundCounter := 0 |
|||
state = c.fullRounds(state, &roundCounter) |
|||
state = c.partialRounds(state, &roundCounter) |
|||
state = c.fullRounds(state, &roundCounter) |
|||
return state |
|||
} |
|||
|
|||
// The input elements MUST have all it's elements be within Goldilocks field.
|
|||
// The returned slice's elements will all be within Goldilocks field.
|
|||
func (c *PoseidonChip) HashNToMNoPad(input []frontend.Variable, nbOutputs int) []frontend.Variable { |
|||
var state PoseidonState |
|||
|
|||
for i := 0; i < SPONGE_WIDTH; i++ { |
|||
state[i] = frontend.Variable(0) |
|||
} |
|||
|
|||
for i := 0; i < len(input); i += SPONGE_RATE { |
|||
for j := 0; j < SPONGE_RATE; j++ { |
|||
if i+j < len(input) { |
|||
state[j] = input[i+j] |
|||
} |
|||
} |
|||
state = c.Poseidon(state) |
|||
} |
|||
|
|||
var outputs []frontend.Variable |
|||
|
|||
for { |
|||
for i := 0; i < SPONGE_RATE; i++ { |
|||
outputs = append(outputs, state[i]) |
|||
if len(outputs) == nbOutputs { |
|||
return outputs |
|||
} |
|||
} |
|||
state = c.Poseidon(state) |
|||
} |
|||
} |
|||
|
|||
// The input elements can be outside of the Goldilocks field.
|
|||
// The returned slice's elements will all be within Goldilocks field.
|
|||
func (c *PoseidonChip) HashNoPad(input []field.F) PoseidonHashOut { |
|||
var hash PoseidonHashOut |
|||
inputVars := []frontend.Variable{} |
|||
|
|||
for i := 0; i < len(input); i++ { |
|||
inputVars = append(inputVars, c.fieldAPI.Reduce(input[i]).Limbs[0]) |
|||
} |
|||
|
|||
outputVars := c.HashNToMNoPad(inputVars, 4) |
|||
for i := 0; i < 4; i++ { |
|||
hash[i] = c.fieldAPI.NewElement(outputVars[i]) |
|||
} |
|||
|
|||
return hash |
|||
} |
|||
|
|||
func (c *PoseidonChip) ToVec(hash PoseidonHashOut) []field.F { |
|||
return hash[:] |
|||
} |
|||
|
|||
func (c *PoseidonChip) fullRounds(state PoseidonState, roundCounter *int) PoseidonState { |
|||
for i := 0; i < HALF_N_FULL_ROUNDS; i++ { |
|||
state = c.constantLayer(state, roundCounter) |
|||
state = c.sBoxLayer(state) |
|||
state = c.mdsLayer(state) |
|||
*roundCounter += 1 |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *PoseidonChip) partialRounds(state PoseidonState, roundCounter *int) PoseidonState { |
|||
state = c.partialFirstConstantLayer(state) |
|||
state = c.mdsPartialLayerInit(state) |
|||
|
|||
for i := 0; i < N_PARTIAL_ROUNDS; i++ { |
|||
state[0] = c.sBoxMonomial(state[0]) |
|||
state[0] = field.GoldilocksMulAdd(c.api, frontend.Variable(1), state[0], FAST_PARTIAL_ROUND_CONSTANTS[i]) |
|||
state = c.mdsPartialLayerFast(state, i) |
|||
} |
|||
|
|||
*roundCounter += N_PARTIAL_ROUNDS |
|||
|
|||
return state |
|||
} |
|||
|
|||
func (c *PoseidonChip) constantLayer(state PoseidonState, roundCounter *int) PoseidonState { |
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
roundConstant := ALL_ROUND_CONSTANTS[i+SPONGE_WIDTH*(*roundCounter)] |
|||
state[i] = field.GoldilocksMulAdd(c.api, frontend.Variable(1), state[i], roundConstant) |
|||
} |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *PoseidonChip) ConstantLayerExtension(state PoseidonStateExtension, roundCounter *int) PoseidonStateExtension { |
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
roundConstant := c.qeAPI.VarToQE(ALL_ROUND_CONSTANTS[i+SPONGE_WIDTH*(*roundCounter)]) |
|||
state[i] = c.qeAPI.AddExtension(state[i], roundConstant) |
|||
} |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *PoseidonChip) sBoxMonomial(x frontend.Variable) frontend.Variable { |
|||
x2 := field.GoldilocksMulAdd(c.api, x, x, frontend.Variable(0)) |
|||
x4 := field.GoldilocksMulAdd(c.api, x2, x2, frontend.Variable(0)) |
|||
x6 := field.GoldilocksMulAdd(c.api, x4, x2, frontend.Variable(0)) |
|||
return field.GoldilocksMulAdd(c.api, x6, x, frontend.Variable(0)) |
|||
} |
|||
|
|||
func (c *PoseidonChip) SBoxMonomialExtension(x field.QuadraticExtension) field.QuadraticExtension { |
|||
x2 := c.qeAPI.SquareExtension(x) |
|||
x4 := c.qeAPI.SquareExtension(x2) |
|||
x3 := c.qeAPI.MulExtension(x, x2) |
|||
return c.qeAPI.MulExtension(x3, x4) |
|||
} |
|||
|
|||
func (c *PoseidonChip) sBoxLayer(state PoseidonState) PoseidonState { |
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
state[i] = c.sBoxMonomial(state[i]) |
|||
} |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *PoseidonChip) SBoxLayerExtension(state PoseidonStateExtension) PoseidonStateExtension { |
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
state[i] = c.SBoxMonomialExtension(state[i]) |
|||
} |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *PoseidonChip) mdsRowShf(r int, v [SPONGE_WIDTH]frontend.Variable) frontend.Variable { |
|||
res := ZERO_VAR |
|||
|
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
res = field.GoldilocksMulAdd(c.api, v[(i+r)%SPONGE_WIDTH], MDS_MATRIX_CIRC_VARS[i], res) |
|||
} |
|||
} |
|||
|
|||
res = field.GoldilocksMulAdd(c.api, v[r], MDS_MATRIX_DIAG_VARS[r], res) |
|||
return res |
|||
} |
|||
|
|||
func (c *PoseidonChip) MdsRowShfExtension(r int, v [SPONGE_WIDTH]field.QuadraticExtension) field.QuadraticExtension { |
|||
res := c.qeAPI.FieldToQE(field.ZERO_F) |
|||
|
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
matrixVal := c.qeAPI.VarToQE(MDS_MATRIX_CIRC[i]) |
|||
res1 := c.qeAPI.MulExtension(v[(i+r)%SPONGE_WIDTH], matrixVal) |
|||
res = c.qeAPI.AddExtension(res, res1) |
|||
} |
|||
} |
|||
|
|||
matrixVal := c.qeAPI.VarToQE(MDS_MATRIX_DIAG[r]) |
|||
res = c.qeAPI.AddExtension(res, c.qeAPI.MulExtension(v[r], matrixVal)) |
|||
return res |
|||
} |
|||
|
|||
func (c *PoseidonChip) mdsLayer(state_ PoseidonState) PoseidonState { |
|||
var result PoseidonState |
|||
for i := 0; i < SPONGE_WIDTH; i++ { |
|||
result[i] = frontend.Variable(0) |
|||
} |
|||
|
|||
for r := 0; r < 12; r++ { |
|||
if r < SPONGE_WIDTH { |
|||
result[r] = c.mdsRowShf(r, state_) |
|||
} |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
func (c *PoseidonChip) MdsLayerExtension(state_ PoseidonStateExtension) PoseidonStateExtension { |
|||
var result PoseidonStateExtension |
|||
|
|||
for r := 0; r < 12; r++ { |
|||
if r < SPONGE_WIDTH { |
|||
sum := c.MdsRowShfExtension(r, state_) |
|||
result[r] = sum |
|||
} |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
func (c *PoseidonChip) partialFirstConstantLayer(state PoseidonState) PoseidonState { |
|||
for i := 0; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
state[i] = field.GoldilocksMulAdd(c.api, frontend.Variable(1), state[i], FAST_PARTIAL_FIRST_ROUND_CONSTANT[i]) |
|||
} |
|||
} |
|||
return state |
|||
} |
|||
|
|||
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.VarToQE((FAST_PARTIAL_FIRST_ROUND_CONSTANT[i]))) |
|||
} |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *PoseidonChip) mdsPartialLayerInit(state PoseidonState) PoseidonState { |
|||
var result PoseidonState |
|||
for i := 0; i < 12; i++ { |
|||
result[i] = frontend.Variable(0) |
|||
} |
|||
|
|||
result[0] = state[0] |
|||
|
|||
for r := 1; r < 12; r++ { |
|||
if r < SPONGE_WIDTH { |
|||
for d := 1; d < 12; d++ { |
|||
if d < SPONGE_WIDTH { |
|||
t := FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1] |
|||
result[d] = field.GoldilocksMulAdd(c.api, state[r], t, result[d]) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
func (c *PoseidonChip) MdsPartialLayerInitExtension(state PoseidonStateExtension) PoseidonStateExtension { |
|||
var result PoseidonStateExtension |
|||
for i := 0; i < 12; i++ { |
|||
result[i] = c.qeAPI.FieldToQE(field.ZERO_F) |
|||
} |
|||
|
|||
result[0] = state[0] |
|||
|
|||
for r := 1; r < 12; r++ { |
|||
if r < SPONGE_WIDTH { |
|||
for d := 1; d < 12; d++ { |
|||
if d < SPONGE_WIDTH { |
|||
t := c.qeAPI.VarToQE(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1]) |
|||
result[d] = c.qeAPI.AddExtension(result[d], c.qeAPI.MulExtension(state[r], t)) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
func (c *PoseidonChip) mdsPartialLayerFast(state PoseidonState, r int) PoseidonState { |
|||
dSum := ZERO_VAR |
|||
for i := 1; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
t := FAST_PARTIAL_ROUND_W_HATS_VARS[r][i-1] |
|||
dSum = field.GoldilocksMulAdd(c.api, state[i], t, dSum) |
|||
} |
|||
} |
|||
|
|||
d := field.GoldilocksMulAdd(c.api, state[0], MDS0TO0_VAR, dSum) |
|||
|
|||
var result PoseidonState |
|||
for i := 0; i < SPONGE_WIDTH; i++ { |
|||
result[i] = frontend.Variable(0) |
|||
} |
|||
|
|||
result[0] = d |
|||
|
|||
for i := 1; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
t := FAST_PARTIAL_ROUND_VS[r][i-1] |
|||
result[i] = field.GoldilocksMulAdd(c.api, state[0], t, state[i]) |
|||
} |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
func (c *PoseidonChip) MdsPartialLayerFastExtension(state PoseidonStateExtension, r int) PoseidonStateExtension { |
|||
s0 := state[0] |
|||
mds0to0 := c.qeAPI.VarToQE(MDS0TO0) |
|||
d := c.qeAPI.MulExtension(s0, mds0to0) |
|||
for i := 1; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
t := c.qeAPI.VarToQE(FAST_PARTIAL_ROUND_W_HATS[r][i-1]) |
|||
d = c.qeAPI.AddExtension(d, c.qeAPI.MulExtension(state[i], t)) |
|||
} |
|||
} |
|||
|
|||
var result PoseidonStateExtension |
|||
result[0] = d |
|||
for i := 1; i < 12; i++ { |
|||
if i < SPONGE_WIDTH { |
|||
t := c.qeAPI.VarToQE(FAST_PARTIAL_ROUND_VS[r][i-1]) |
|||
result[i] = c.qeAPI.AddExtension(c.qeAPI.MulExtension(state[0], t), state[i]) |
|||
} |
|||
} |
|||
|
|||
return result |
|||
} |
|||
@ -1,199 +0,0 @@ |
|||
package poseidon |
|||
|
|||
import ( |
|||
"math/big" |
|||
|
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/field" |
|||
) |
|||
|
|||
const fullRounds = 8 |
|||
const partialRounds = 56 |
|||
const spongeWidth = 4 |
|||
const spongeRate = 3 |
|||
|
|||
type PoseidonBN128Chip struct { |
|||
api frontend.API `gnark:"-"` |
|||
fieldAPI field.FieldAPI `gnark:"-"` |
|||
} |
|||
|
|||
type PoseidonBN128State = [spongeWidth]frontend.Variable |
|||
type PoseidonBN128HashOut = frontend.Variable |
|||
|
|||
// This implementation is based on the following implementation:
|
|||
// https://github.com/iden3/go-iden3-crypto/blob/e5cf066b8be3da9a3df9544c65818df189fdbebe/poseidon/poseidon.go
|
|||
func NewPoseidonBN128Chip(api frontend.API, fieldAPI field.FieldAPI) *PoseidonBN128Chip { |
|||
return &PoseidonBN128Chip{api: api, fieldAPI: fieldAPI} |
|||
} |
|||
|
|||
func (c *PoseidonBN128Chip) Poseidon(state PoseidonBN128State) PoseidonBN128State { |
|||
state = c.ark(state, 0) |
|||
state = c.fullRounds(state, true) |
|||
state = c.partialRounds(state) |
|||
state = c.fullRounds(state, false) |
|||
return state |
|||
} |
|||
|
|||
func (c *PoseidonBN128Chip) HashNoPad(input []field.F) PoseidonBN128HashOut { |
|||
state := PoseidonBN128State{ |
|||
frontend.Variable(0), |
|||
frontend.Variable(0), |
|||
frontend.Variable(0), |
|||
frontend.Variable(0), |
|||
} |
|||
|
|||
for i := 0; i < len(input); i += spongeRate * 3 { |
|||
endI := c.min(len(input), i+spongeRate*3) |
|||
rateChunk := input[i:endI] |
|||
for j, stateIdx := 0, 0; j < len(rateChunk); j, stateIdx = j+3, stateIdx+1 { |
|||
endJ := c.min(len(rateChunk), j+3) |
|||
bn128Chunk := rateChunk[j:endJ] |
|||
|
|||
bits := []frontend.Variable{} |
|||
for k := 0; k < len(bn128Chunk); k++ { |
|||
bn128Chunk[k] = c.fieldAPI.Reduce(bn128Chunk[k]) |
|||
bits = append(bits, c.fieldAPI.ToBits(bn128Chunk[k])...) |
|||
} |
|||
|
|||
state[stateIdx+1] = c.api.FromBinary(bits...) |
|||
} |
|||
|
|||
state = c.Poseidon(state) |
|||
} |
|||
|
|||
return PoseidonBN128HashOut(state[0]) |
|||
} |
|||
|
|||
func (c *PoseidonBN128Chip) HashOrNoop(input []field.F) PoseidonBN128HashOut { |
|||
if len(input) <= 3 { |
|||
returnVal := frontend.Variable(0) |
|||
|
|||
alpha := new(big.Int).SetInt64(1 << 32) |
|||
for i, inputElement := range input { |
|||
returnVal = c.api.Add(returnVal, c.api.Mul(inputElement, alpha.Exp(alpha, big.NewInt(int64(i)), nil))) |
|||
} |
|||
|
|||
return PoseidonBN128HashOut(returnVal) |
|||
} else { |
|||
return c.HashNoPad(input) |
|||
} |
|||
} |
|||
|
|||
func (c *PoseidonBN128Chip) TwoToOne(left PoseidonBN128HashOut, right PoseidonBN128HashOut) PoseidonBN128HashOut { |
|||
var inputs PoseidonBN128State |
|||
inputs[0] = frontend.Variable(0) |
|||
inputs[1] = frontend.Variable(0) |
|||
inputs[2] = left |
|||
inputs[3] = right |
|||
state := c.Poseidon(inputs) |
|||
return state[0] |
|||
} |
|||
|
|||
func (c *PoseidonBN128Chip) ToVec(hash PoseidonBN128HashOut) []field.F { |
|||
bits := c.api.ToBinary(hash) |
|||
|
|||
returnElements := []field.F{} |
|||
|
|||
// Split into 7 byte chunks, since 8 byte chunks can result in collisions
|
|||
chunkSize := 56 |
|||
for i := 0; i < len(bits); i += chunkSize { |
|||
maxIdx := c.min(len(bits), i+chunkSize) |
|||
bitChunk := bits[i:maxIdx] |
|||
returnElements = append(returnElements, c.fieldAPI.FromBits(bitChunk...)) |
|||
} |
|||
|
|||
return returnElements |
|||
} |
|||
|
|||
func (c *PoseidonBN128Chip) min(x, y int) int { |
|||
if x < y { |
|||
return x |
|||
} |
|||
|
|||
return y |
|||
} |
|||
|
|||
func (c *PoseidonBN128Chip) fullRounds(state PoseidonBN128State, isFirst bool) PoseidonBN128State { |
|||
for i := 0; i < fullRounds/2-1; i++ { |
|||
state = c.exp5state(state) |
|||
if isFirst { |
|||
state = c.ark(state, (i+1)*spongeWidth) |
|||
} else { |
|||
state = c.ark(state, (fullRounds/2+1)*spongeWidth+partialRounds+i*spongeWidth) |
|||
} |
|||
state = c.mix(state, mMatrix) |
|||
} |
|||
|
|||
state = c.exp5state(state) |
|||
if isFirst { |
|||
state = c.ark(state, (fullRounds/2)*spongeWidth) |
|||
state = c.mix(state, pMatrix) |
|||
} else { |
|||
state = c.mix(state, mMatrix) |
|||
} |
|||
|
|||
return state |
|||
} |
|||
|
|||
func (c *PoseidonBN128Chip) partialRounds(state PoseidonBN128State) PoseidonBN128State { |
|||
for i := 0; i < partialRounds; i++ { |
|||
state[0] = c.exp5(state[0]) |
|||
state[0] = c.api.Add(state[0], cConstants[(fullRounds/2+1)*spongeWidth+i]) |
|||
|
|||
var mul frontend.Variable |
|||
newState0 := frontend.Variable(0) |
|||
for j := 0; j < spongeWidth; j++ { |
|||
mul = c.api.Mul(sConstants[(spongeWidth*2-1)*i+j], state[j]) |
|||
newState0 = c.api.Add(newState0, mul) |
|||
} |
|||
|
|||
for k := 1; k < spongeWidth; k++ { |
|||
mul = c.api.Mul(state[0], sConstants[(spongeWidth*2-1)*i+spongeWidth+k-1]) |
|||
state[k] = c.api.Add(state[k], mul) |
|||
} |
|||
state[0] = newState0 |
|||
} |
|||
|
|||
return state |
|||
} |
|||
|
|||
func (c *PoseidonBN128Chip) ark(state PoseidonBN128State, it int) PoseidonBN128State { |
|||
var result PoseidonBN128State |
|||
|
|||
for i := 0; i < len(state); i++ { |
|||
result[i] = c.api.Add(state[i], cConstants[it+i]) |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
func (c *PoseidonBN128Chip) exp5(x frontend.Variable) frontend.Variable { |
|||
x2 := c.api.Mul(x, x) |
|||
x4 := c.api.Mul(x2, x2) |
|||
return c.api.Mul(x4, x) |
|||
} |
|||
|
|||
func (c *PoseidonBN128Chip) exp5state(state PoseidonBN128State) PoseidonBN128State { |
|||
for i := 0; i < spongeWidth; i++ { |
|||
state[i] = c.exp5(state[i]) |
|||
} |
|||
return state |
|||
} |
|||
|
|||
func (c *PoseidonBN128Chip) mix(state_ PoseidonBN128State, constantMatrix [][]*big.Int) PoseidonBN128State { |
|||
var mul frontend.Variable |
|||
var result PoseidonBN128State |
|||
|
|||
for i := 0; i < spongeWidth; i++ { |
|||
result[i] = frontend.Variable(0) |
|||
} |
|||
|
|||
for i := 0; i < spongeWidth; i++ { |
|||
for j := 0; j < spongeWidth; j++ { |
|||
mul = c.api.Mul(constantMatrix[j][i], state_[j]) |
|||
result[i] = c.api.Add(result[i], mul) |
|||
} |
|||
} |
|||
|
|||
return result |
|||
} |
|||
@ -0,0 +1,99 @@ |
|||
package types |
|||
|
|||
import ( |
|||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon" |
|||
) |
|||
|
|||
type PolynomialCoeffs struct { |
|||
Coeffs []gl.QuadraticExtensionVariable |
|||
} |
|||
|
|||
func NewPolynomialCoeffs(numCoeffs uint64) PolynomialCoeffs { |
|||
return PolynomialCoeffs{Coeffs: make([]gl.QuadraticExtensionVariable, numCoeffs)} |
|||
} |
|||
|
|||
type FriConfig struct { |
|||
RateBits uint64 |
|||
CapHeight uint64 |
|||
ProofOfWorkBits uint64 |
|||
NumQueryRounds uint64 |
|||
// TODO: add FriReductionStrategy
|
|||
} |
|||
|
|||
func (fc *FriConfig) Rate() float64 { |
|||
return 1.0 / float64((uint64(1) << fc.RateBits)) |
|||
} |
|||
|
|||
type FriParams struct { |
|||
Config FriConfig |
|||
Hiding bool |
|||
DegreeBits uint64 |
|||
ReductionArityBits []uint64 |
|||
} |
|||
|
|||
type FriMerkleCap = []poseidon.BN254HashOut |
|||
|
|||
func NewFriMerkleCap(capHeight uint64) FriMerkleCap { |
|||
return make([]poseidon.BN254HashOut, 1<<capHeight) |
|||
} |
|||
|
|||
type FriMerkleProof struct { |
|||
Siblings []poseidon.BN254HashOut // Length = CircuitConfig.FriConfig.DegreeBits + CircuitConfig.FriConfig.RateBits - CircuitConfig.FriConfig.CapHeight
|
|||
} |
|||
|
|||
func NewFriMerkleProof(merkleProofLen uint64) FriMerkleProof { |
|||
return FriMerkleProof{Siblings: make([]poseidon.BN254HashOut, merkleProofLen)} |
|||
} |
|||
|
|||
type FriEvalProof struct { |
|||
Elements []gl.Variable // Length = [CommonCircuitData.Constants + CommonCircuitData.NumRoutedWires, CommonCircuitData.NumWires + CommonCircuitData.FriParams.Hiding ? 4 : 0, CommonCircuitData.NumChallenges * (1 + CommonCircuitData.NumPartialProducts) + salt, CommonCircuitData.NumChallenges * CommonCircuitData.QuotientDegreeFactor + salt]
|
|||
MerkleProof FriMerkleProof |
|||
} |
|||
|
|||
func NewFriEvalProof(elements []gl.Variable, merkleProof FriMerkleProof) FriEvalProof { |
|||
return FriEvalProof{Elements: elements, MerkleProof: merkleProof} |
|||
} |
|||
|
|||
type FriInitialTreeProof struct { |
|||
EvalsProofs []FriEvalProof // Length = 4
|
|||
} |
|||
|
|||
func NewFriInitialTreeProof(evalsProofs []FriEvalProof) FriInitialTreeProof { |
|||
return FriInitialTreeProof{EvalsProofs: evalsProofs} |
|||
} |
|||
|
|||
type FriQueryStep struct { |
|||
Evals []gl.QuadraticExtensionVariable // Length = [2^arityBit for arityBit in CommonCircuitData.FriParams.ReductionArityBits]
|
|||
MerkleProof FriMerkleProof // Length = [regularSize - arityBit for arityBit in CommonCircuitData.FriParams.ReductionArityBits]
|
|||
} |
|||
|
|||
func NewFriQueryStep(arityBit uint64, merkleProofLen uint64) FriQueryStep { |
|||
return FriQueryStep{ |
|||
Evals: make([]gl.QuadraticExtensionVariable, 1<<arityBit), |
|||
MerkleProof: NewFriMerkleProof(merkleProofLen), |
|||
} |
|||
} |
|||
|
|||
type FriQueryRound struct { |
|||
InitialTreesProof FriInitialTreeProof |
|||
Steps []FriQueryStep // Length = Len(CommonCircuitData.FriParams.ReductionArityBits)
|
|||
} |
|||
|
|||
func NewFriQueryRound(steps []FriQueryStep, initialTreesProof FriInitialTreeProof) FriQueryRound { |
|||
return FriQueryRound{InitialTreesProof: initialTreesProof, Steps: steps} |
|||
} |
|||
|
|||
type FriProof struct { |
|||
CommitPhaseMerkleCaps []FriMerkleCap // Length = Len(CommonCircuitData.FriParams.ReductionArityBits)
|
|||
QueryRoundProofs []FriQueryRound // Length = CommonCircuitData.FriConfig.FriParams.NumQueryRounds
|
|||
FinalPoly PolynomialCoeffs |
|||
PowWitness gl.Variable |
|||
} |
|||
|
|||
type FriChallenges struct { |
|||
FriAlpha gl.QuadraticExtensionVariable |
|||
FriBetas []gl.QuadraticExtensionVariable |
|||
FriPowResponse gl.Variable |
|||
FriQueryIndices []gl.Variable |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
package types |
|||
|
|||
import gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
|
|||
type OpeningSet struct { |
|||
Constants []gl.QuadraticExtensionVariable // Length = CommonCircuitData.Constants
|
|||
PlonkSigmas []gl.QuadraticExtensionVariable // Length = CommonCircuitData.NumRoutedWires
|
|||
Wires []gl.QuadraticExtensionVariable // Length = CommonCircuitData.NumWires
|
|||
PlonkZs []gl.QuadraticExtensionVariable // Length = CommonCircuitData.NumChallenges
|
|||
PlonkZsNext []gl.QuadraticExtensionVariable // Length = CommonCircuitData.NumChallenges
|
|||
PartialProducts []gl.QuadraticExtensionVariable // Length = CommonCircuitData.NumChallenges * CommonCircuitData.NumPartialProducts
|
|||
QuotientPolys []gl.QuadraticExtensionVariable // Length = CommonCircuitData.NumChallenges * CommonCircuitData.QuotientDegreeFactor
|
|||
} |
|||
|
|||
func NewOpeningSet(numConstants uint64, numRoutedWires uint64, numWires uint64, numChallenges uint64, numPartialProducts uint64, quotientDegreeFactor uint64) OpeningSet { |
|||
return OpeningSet{ |
|||
Constants: make([]gl.QuadraticExtensionVariable, numConstants), |
|||
PlonkSigmas: make([]gl.QuadraticExtensionVariable, numRoutedWires), |
|||
Wires: make([]gl.QuadraticExtensionVariable, numWires), |
|||
PlonkZs: make([]gl.QuadraticExtensionVariable, numChallenges), |
|||
PlonkZsNext: make([]gl.QuadraticExtensionVariable, numChallenges), |
|||
PartialProducts: make([]gl.QuadraticExtensionVariable, numChallenges*numPartialProducts), |
|||
QuotientPolys: make([]gl.QuadraticExtensionVariable, numChallenges*quotientDegreeFactor), |
|||
} |
|||
} |
|||
|
|||
type ProofChallenges struct { |
|||
PlonkBetas []gl.Variable |
|||
PlonkGammas []gl.Variable |
|||
PlonkAlphas []gl.Variable |
|||
PlonkZeta gl.QuadraticExtensionVariable |
|||
FriChallenges FriChallenges |
|||
} |
|||
@ -1,123 +0,0 @@ |
|||
package common |
|||
|
|||
import ( |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/field" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon" |
|||
) |
|||
|
|||
type MerkleCap = []poseidon.PoseidonBN128HashOut |
|||
|
|||
func NewMerkleCap(capHeight uint64) MerkleCap { |
|||
return make([]poseidon.PoseidonBN128HashOut, 1<<capHeight) |
|||
} |
|||
|
|||
type MerkleProof struct { |
|||
Siblings []poseidon.PoseidonBN128HashOut // Length = CircuitConfig.FriConfig.DegreeBits + CircuitConfig.FriConfig.RateBits - CircuitConfig.FriConfig.CapHeight
|
|||
} |
|||
|
|||
func NewMerkleProof(merkleProofLen uint64) MerkleProof { |
|||
return MerkleProof{Siblings: make([]poseidon.PoseidonBN128HashOut, merkleProofLen)} |
|||
} |
|||
|
|||
type EvalProof struct { |
|||
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 // 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 // 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 // Length = CommonCircuitData.NumPublicInputs
|
|||
} |
|||
|
|||
type ProofChallenges struct { |
|||
PlonkBetas []field.F |
|||
PlonkGammas []field.F |
|||
PlonkAlphas []field.F |
|||
PlonkZeta field.QuadraticExtension |
|||
FriChallenges FriChallenges |
|||
} |
|||
|
|||
type FriInitialTreeProof struct { |
|||
EvalsProofs []EvalProof // Length = 4
|
|||
} |
|||
|
|||
func NewFriInitialTreeProof(evalsProofs []EvalProof) FriInitialTreeProof { |
|||
return FriInitialTreeProof{EvalsProofs: evalsProofs} |
|||
} |
|||
|
|||
type FriQueryStep struct { |
|||
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 // Length = Len(CommonCircuitData.FriParams.ReductionArityBits)
|
|||
} |
|||
|
|||
func NewFriQueryRound(steps []FriQueryStep, initialTreesProof FriInitialTreeProof) FriQueryRound { |
|||
return FriQueryRound{InitialTreesProof: initialTreesProof, Steps: steps} |
|||
} |
|||
|
|||
type FriProof struct { |
|||
CommitPhaseMerkleCaps []MerkleCap // Length = Len(CommonCircuitData.FriParams.ReductionArityBits)
|
|||
QueryRoundProofs []FriQueryRound // Length = CommonCircuitData.FriConfig.FriParams.NumQueryRounds
|
|||
FinalPoly PolynomialCoeffs |
|||
PowWitness field.F |
|||
} |
|||
|
|||
type FriChallenges struct { |
|||
FriAlpha field.QuadraticExtension |
|||
FriBetas []field.QuadraticExtension |
|||
FriPowResponse field.F |
|||
FriQueryIndices []field.F |
|||
} |
|||
@ -1,4 +1,4 @@ |
|||
package utils |
|||
package verifier |
|||
|
|||
import ( |
|||
"fmt" |
|||
@ -1,124 +0,0 @@ |
|||
package fri_test |
|||
|
|||
import ( |
|||
"testing" |
|||
|
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/consensys/gnark/test" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/field" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/fri" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/plonk" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils" |
|||
) |
|||
|
|||
type TestFriCircuit struct { |
|||
proofWithPIsFilename string `gnark:"-"` |
|||
commonCircuitDataFilename string `gnark:"-"` |
|||
verifierOnlyCircuitDataFilename string `gnark:"-"` |
|||
} |
|||
|
|||
func (circuit *TestFriCircuit) Define(api frontend.API) error { |
|||
proofWithPis := utils.DeserializeProofWithPublicInputs(circuit.proofWithPIsFilename) |
|||
commonCircuitData := utils.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename) |
|||
verifierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(circuit.verifierOnlyCircuitDataFilename) |
|||
|
|||
fieldAPI := field.NewFieldAPI(api) |
|||
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI) |
|||
poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI, qeAPI) |
|||
poseidonBN128Chip := poseidon.NewPoseidonBN128Chip(api, fieldAPI) |
|||
friChip := fri.NewFriChip(api, fieldAPI, qeAPI, poseidonBN128Chip, &commonCircuitData.FriParams) |
|||
challengerChip := plonk.NewChallengerChip(api, fieldAPI, poseidonChip, poseidonBN128Chip) |
|||
|
|||
challengerChip.ObserveBN128Hash(verifierOnlyCircuitData.CircuitDigest) |
|||
challengerChip.ObserveHash(poseidonChip.HashNoPad(proofWithPis.PublicInputs)) |
|||
challengerChip.ObserveCap(proofWithPis.Proof.WiresCap) |
|||
plonkBetas := challengerChip.GetNChallenges(commonCircuitData.Config.NumChallenges) // For plonk betas
|
|||
fieldAPI.AssertIsEqual(plonkBetas[0], field.NewFieldConst(17615363392879944733)) |
|||
plonkGammas := challengerChip.GetNChallenges(commonCircuitData.Config.NumChallenges) // For plonk gammas
|
|||
fieldAPI.AssertIsEqual(plonkGammas[0], field.NewFieldConst(15174493176564484303)) |
|||
|
|||
challengerChip.ObserveCap(proofWithPis.Proof.PlonkZsPartialProductsCap) |
|||
plonkAlphas := challengerChip.GetNChallenges(commonCircuitData.Config.NumChallenges) // For plonk alphas
|
|||
fieldAPI.AssertIsEqual(plonkAlphas[0], field.NewFieldConst(9276470834414745550)) |
|||
|
|||
challengerChip.ObserveCap(proofWithPis.Proof.QuotientPolysCap) |
|||
plonkZeta := challengerChip.GetExtensionChallenge() |
|||
fieldAPI.AssertIsEqual(plonkZeta[0], field.NewFieldConst(3892795992421241388)) |
|||
|
|||
challengerChip.ObserveOpenings(fri.ToFriOpenings(proofWithPis.Proof.Openings)) |
|||
|
|||
friChallenges := challengerChip.GetFriChallenges( |
|||
proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps, |
|||
proofWithPis.Proof.OpeningProof.FinalPoly, |
|||
proofWithPis.Proof.OpeningProof.PowWitness, |
|||
commonCircuitData.DegreeBits, |
|||
commonCircuitData.Config.FriConfig, |
|||
) |
|||
|
|||
fieldAPI.AssertIsEqual(friChallenges.FriAlpha[0], field.NewFieldConst(885535811531859621)) |
|||
|
|||
fieldAPI.AssertIsEqual(friChallenges.FriBetas[0][0], field.NewFieldConst(5231781384587895507)) |
|||
|
|||
fieldAPI.AssertIsEqual(friChallenges.FriPowResponse, field.NewFieldConst(70715523064019)) |
|||
|
|||
fieldAPI.AssertIsEqual(friChallenges.FriQueryIndices[0], field.NewFieldConst(11890500485816111017)) |
|||
|
|||
initialMerkleCaps := []common.MerkleCap{ |
|||
verifierOnlyCircuitData.ConstantSigmasCap, |
|||
proofWithPis.Proof.WiresCap, |
|||
proofWithPis.Proof.PlonkZsPartialProductsCap, |
|||
proofWithPis.Proof.QuotientPolysCap, |
|||
} |
|||
|
|||
// Seems like there is a bug in the emulated field code.
|
|||
// Add ZERO to all of the fri challenges values to reduce them.
|
|||
plonkZeta[0] = fieldAPI.Add(plonkZeta[0], field.ZERO_F) |
|||
plonkZeta[1] = fieldAPI.Add(plonkZeta[1], field.ZERO_F) |
|||
|
|||
friChallenges.FriAlpha[0] = fieldAPI.Add(friChallenges.FriAlpha[0], field.ZERO_F) |
|||
friChallenges.FriAlpha[1] = fieldAPI.Add(friChallenges.FriAlpha[1], field.ZERO_F) |
|||
|
|||
for i := 0; i < len(friChallenges.FriBetas); i++ { |
|||
friChallenges.FriBetas[i][0] = fieldAPI.Add(friChallenges.FriBetas[i][0], field.ZERO_F) |
|||
friChallenges.FriBetas[i][1] = fieldAPI.Add(friChallenges.FriBetas[i][1], field.ZERO_F) |
|||
} |
|||
|
|||
friChallenges.FriPowResponse = fieldAPI.Add(friChallenges.FriPowResponse, field.ZERO_F) |
|||
|
|||
for i := 0; i < len(friChallenges.FriQueryIndices); i++ { |
|||
friChallenges.FriQueryIndices[i] = fieldAPI.Add(friChallenges.FriQueryIndices[i], field.ZERO_F) |
|||
} |
|||
|
|||
friChip.VerifyFriProof( |
|||
fri.GetFriInstance(&commonCircuitData, qeAPI, plonkZeta, commonCircuitData.DegreeBits), |
|||
fri.ToFriOpenings(proofWithPis.Proof.Openings), |
|||
&friChallenges, |
|||
initialMerkleCaps, |
|||
&proofWithPis.Proof.OpeningProof, |
|||
) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func TestDecodeBlockFriVerification(t *testing.T) { |
|||
assert := test.NewAssert(t) |
|||
|
|||
testCase := func() { |
|||
circuit := TestFriCircuit{ |
|||
proofWithPIsFilename: "../../data/decode_block/proof_with_public_inputs.json", |
|||
commonCircuitDataFilename: "../../data/decode_block//common_circuit_data.json", |
|||
verifierOnlyCircuitDataFilename: "../../data/decode_block//verifier_only_circuit_data.json", |
|||
} |
|||
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", |
|||
} |
|||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField()) |
|||
assert.NoError(err) |
|||
} |
|||
|
|||
testCase() |
|||
} |
|||
@ -1,763 +0,0 @@ |
|||
package gates_test |
|||
|
|||
import ( |
|||
"errors" |
|||
"testing" |
|||
|
|||
"github.com/consensys/gnark-crypto/field/goldilocks" |
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/consensys/gnark/test" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/field" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/gates" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils" |
|||
) |
|||
|
|||
// From recursive_step circuit
|
|||
var localConstants = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(4962976205186800892), field.NewFieldConst(6982360466972099197)}, |
|||
{field.NewFieldConst(3587364333101709084), field.NewFieldConst(17496916837371484700)}, |
|||
{field.NewFieldConst(17287374881609559799), field.NewFieldConst(3152841633956965234)}, |
|||
{field.NewFieldConst(8531030241248616826), field.NewFieldConst(7753678118587211959)}, |
|||
{field.NewFieldConst(7622109056373824903), field.NewFieldConst(6523636236475969621)}, |
|||
} |
|||
|
|||
var localWires = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(5101665081776077058), field.NewFieldConst(13601771238484783081)}, |
|||
{field.NewFieldConst(13763997788502656587), field.NewFieldConst(6068443864169526207)}, |
|||
{field.NewFieldConst(10492880302699453810), field.NewFieldConst(11304418575668616669)}, |
|||
{field.NewFieldConst(2175168501339052813), field.NewFieldConst(3658211467579027796)}, |
|||
{field.NewFieldConst(11342710587435471757), field.NewFieldConst(658078906333318768)}, |
|||
{field.NewFieldConst(16590262768413671742), field.NewFieldConst(4678191900868819358)}, |
|||
{field.NewFieldConst(18412513594273328173), field.NewFieldConst(3981245463942959904)}, |
|||
{field.NewFieldConst(18150166316938544267), field.NewFieldConst(6968565044901838140)}, |
|||
{field.NewFieldConst(1048835939602984673), field.NewFieldConst(3511920575130606798)}, |
|||
{field.NewFieldConst(13693300152826538654), field.NewFieldConst(5872314861500881782)}, |
|||
{field.NewFieldConst(6394696263219721312), field.NewFieldConst(92364988976021720)}, |
|||
{field.NewFieldConst(468193345380249942), field.NewFieldConst(4951036536117371576)}, |
|||
{field.NewFieldConst(9660006729985637684), field.NewFieldConst(14762789799642492635)}, |
|||
{field.NewFieldConst(10091149087332313493), field.NewFieldConst(13279468039286967053)}, |
|||
{field.NewFieldConst(12007469191150580744), field.NewFieldConst(2495445179052731885)}, |
|||
{field.NewFieldConst(14225726459587943147), field.NewFieldConst(13484648741862607201)}, |
|||
{field.NewFieldConst(15365400400136175672), field.NewFieldConst(12227857303059870833)}, |
|||
{field.NewFieldConst(1717742269682481687), field.NewFieldConst(14319701537357602192)}, |
|||
{field.NewFieldConst(2130805637557027375), field.NewFieldConst(9674794597783493233)}, |
|||
{field.NewFieldConst(4200526016516623452), field.NewFieldConst(1757832412907480092)}, |
|||
{field.NewFieldConst(4159226258922372229), field.NewFieldConst(2121976810680943769)}, |
|||
{field.NewFieldConst(2887943290582259162), field.NewFieldConst(10337505797799617185)}, |
|||
{field.NewFieldConst(14760843822980496189), field.NewFieldConst(16331301823872182680)}, |
|||
{field.NewFieldConst(14715580754822129725), field.NewFieldConst(13761736659446638375)}, |
|||
{field.NewFieldConst(6925818640561435525), field.NewFieldConst(14142327999826777974)}, |
|||
{field.NewFieldConst(14048060513252076245), field.NewFieldConst(14860933194240516940)}, |
|||
{field.NewFieldConst(3928889853630846436), field.NewFieldConst(16211791673476822740)}, |
|||
{field.NewFieldConst(15980387576926781891), field.NewFieldConst(6238947314711778055)}, |
|||
{field.NewFieldConst(15694939331980119296), field.NewFieldConst(8708301222382733590)}, |
|||
{field.NewFieldConst(192757930858294268), field.NewFieldConst(5400388905722847256)}, |
|||
{field.NewFieldConst(17614358883814855964), field.NewFieldConst(11499208634388453518)}, |
|||
{field.NewFieldConst(9523994443422431577), field.NewFieldConst(6835394446482946098)}, |
|||
{field.NewFieldConst(10096606893378243201), field.NewFieldConst(8982086840326369907)}, |
|||
{field.NewFieldConst(7328922720001507777), field.NewFieldConst(17298728994563323488)}, |
|||
{field.NewFieldConst(7038859554184407337), field.NewFieldConst(6498153778103681368)}, |
|||
{field.NewFieldConst(10610651604960433540), field.NewFieldConst(18240735600936975661)}, |
|||
{field.NewFieldConst(4310901749476028644), field.NewFieldConst(17813866938235850894)}, |
|||
{field.NewFieldConst(12456949458361594924), field.NewFieldConst(16541357680870686003)}, |
|||
{field.NewFieldConst(13986559680062429806), field.NewFieldConst(14210541290696888125)}, |
|||
{field.NewFieldConst(10299578396192380820), field.NewFieldConst(18011235767871391546)}, |
|||
{field.NewFieldConst(747566550336808782), field.NewFieldConst(5892109075601553099)}, |
|||
{field.NewFieldConst(11613383633841665100), field.NewFieldConst(3562006923196410047)}, |
|||
{field.NewFieldConst(14971867523312360339), field.NewFieldConst(9835080574905235511)}, |
|||
{field.NewFieldConst(5487884847548072736), field.NewFieldConst(17112808386797082519)}, |
|||
{field.NewFieldConst(1687420180518659740), field.NewFieldConst(14003627304711288225)}, |
|||
{field.NewFieldConst(6760442482244819429), field.NewFieldConst(15796493945480647537)}, |
|||
{field.NewFieldConst(2639939427088481105), field.NewFieldConst(16213109089273184951)}, |
|||
{field.NewFieldConst(6186345082501710713), field.NewFieldConst(2529053005908871239)}, |
|||
{field.NewFieldConst(16270115914931256348), field.NewFieldConst(2789355919627681645)}, |
|||
{field.NewFieldConst(4586999018177783314), field.NewFieldConst(2427837399215959725)}, |
|||
{field.NewFieldConst(18143358622388343317), field.NewFieldConst(2145167333845152043)}, |
|||
{field.NewFieldConst(20367062449222124), field.NewFieldConst(14939961527015734373)}, |
|||
{field.NewFieldConst(16851694158642043266), field.NewFieldConst(5250789952541240163)}, |
|||
{field.NewFieldConst(273375074794411822), field.NewFieldConst(16211897175907793903)}, |
|||
{field.NewFieldConst(8905927930385832568), field.NewFieldConst(6540262589846603524)}, |
|||
{field.NewFieldConst(9283781971254844102), field.NewFieldConst(15115068064900745758)}, |
|||
{field.NewFieldConst(16002987404851668189), field.NewFieldConst(15226686847545140008)}, |
|||
{field.NewFieldConst(17201679792194997813), field.NewFieldConst(589849108691638964)}, |
|||
{field.NewFieldConst(13270753269614250355), field.NewFieldConst(13858862497673084592)}, |
|||
{field.NewFieldConst(3679908279346826560), field.NewFieldConst(10125726541855725943)}, |
|||
{field.NewFieldConst(9493227554592600240), field.NewFieldConst(13229107531594530196)}, |
|||
{field.NewFieldConst(10072423214517113799), field.NewFieldConst(1877804054697703518)}, |
|||
{field.NewFieldConst(9351494680554520560), field.NewFieldConst(12930187723253788505)}, |
|||
{field.NewFieldConst(9537056082833040850), field.NewFieldConst(3947445714701039423)}, |
|||
{field.NewFieldConst(978662253133020143), field.NewFieldConst(17432233037279205717)}, |
|||
{field.NewFieldConst(13408331971471826902), field.NewFieldConst(8338873650278204671)}, |
|||
{field.NewFieldConst(10455530172494355126), field.NewFieldConst(14614842120953588617)}, |
|||
{field.NewFieldConst(3066054670984065145), field.NewFieldConst(11061840675948823020)}, |
|||
{field.NewFieldConst(1215442291812236170), field.NewFieldConst(6970679356502977963)}, |
|||
{field.NewFieldConst(16254140688845356393), field.NewFieldConst(16413217415268481315)}, |
|||
{field.NewFieldConst(5571707217813279614), field.NewFieldConst(2506082641312169038)}, |
|||
{field.NewFieldConst(18179591596294163519), field.NewFieldConst(16131760445397495720)}, |
|||
{field.NewFieldConst(9500821197677833979), field.NewFieldConst(14137570623214003877)}, |
|||
{field.NewFieldConst(18159279414894480072), field.NewFieldConst(316120438770524969)}, |
|||
{field.NewFieldConst(18164288455905080997), field.NewFieldConst(12889510574086616078)}, |
|||
{field.NewFieldConst(7158952489901063870), field.NewFieldConst(8855957421923524202)}, |
|||
{field.NewFieldConst(11785615172910130564), field.NewFieldConst(13242859272114186921)}, |
|||
{field.NewFieldConst(7978627011292316159), field.NewFieldConst(12030929068833787030)}, |
|||
{field.NewFieldConst(5676253512795062173), field.NewFieldConst(9401396509276686822)}, |
|||
{field.NewFieldConst(13934555872940874542), field.NewFieldConst(12262482935570269103)}, |
|||
{field.NewFieldConst(17018864997992880664), field.NewFieldConst(8399037137658253821)}, |
|||
{field.NewFieldConst(1846702834278938262), field.NewFieldConst(13210394651984411322)}, |
|||
{field.NewFieldConst(18406563809882201846), field.NewFieldConst(15807625126691296911)}, |
|||
{field.NewFieldConst(16192554501791210701), field.NewFieldConst(15105514277710825451)}, |
|||
{field.NewFieldConst(16115514979166385045), field.NewFieldConst(5618092869410987045)}, |
|||
{field.NewFieldConst(9816852940756124129), field.NewFieldConst(1617435612712694609)}, |
|||
{field.NewFieldConst(15012743324956680415), field.NewFieldConst(11098953448520716956)}, |
|||
{field.NewFieldConst(7370750057902285338), field.NewFieldConst(15456123684241865136)}, |
|||
{field.NewFieldConst(14924801177398773859), field.NewFieldConst(1116868612459919368)}, |
|||
{field.NewFieldConst(509701279674911901), field.NewFieldConst(8606220700917290973)}, |
|||
{field.NewFieldConst(256371784527067555), field.NewFieldConst(18023759020251995084)}, |
|||
{field.NewFieldConst(4027645791496469270), field.NewFieldConst(6446906876250510281)}, |
|||
{field.NewFieldConst(8190141658485644545), field.NewFieldConst(3259909135802998300)}, |
|||
{field.NewFieldConst(11270185749533517292), field.NewFieldConst(7032460358965516338)}, |
|||
{field.NewFieldConst(12112891112487601597), field.NewFieldConst(3686732542066412082)}, |
|||
{field.NewFieldConst(18143522178445971138), field.NewFieldConst(6066438010126851248)}, |
|||
{field.NewFieldConst(16109160830754618815), field.NewFieldConst(2728516440557525242)}, |
|||
{field.NewFieldConst(14634072837475699881), field.NewFieldConst(423778353213757146)}, |
|||
{field.NewFieldConst(10421081673554059162), field.NewFieldConst(10142208889746521219)}, |
|||
{field.NewFieldConst(12957639310809930956), field.NewFieldConst(1709286023553869935)}, |
|||
{field.NewFieldConst(16217923109113456531), field.NewFieldConst(3257438610376598615)}, |
|||
{field.NewFieldConst(14024104132094810570), field.NewFieldConst(6065015478137587430)}, |
|||
{field.NewFieldConst(7972303368219061571), field.NewFieldConst(5413678307283424945)}, |
|||
{field.NewFieldConst(10367882107777269226), field.NewFieldConst(9366367173763419226)}, |
|||
{field.NewFieldConst(11506720810821148150), field.NewFieldConst(15210537421649867625)}, |
|||
{field.NewFieldConst(10979917526797364486), field.NewFieldConst(3365843489182711842)}, |
|||
{field.NewFieldConst(9176981360155624350), field.NewFieldConst(7315956459698675112)}, |
|||
{field.NewFieldConst(3964217770504101577), field.NewFieldConst(9088242192411952739)}, |
|||
{field.NewFieldConst(16243289324567090937), field.NewFieldConst(13379263550784156456)}, |
|||
{field.NewFieldConst(18105277122985331384), field.NewFieldConst(13639149553905751132)}, |
|||
{field.NewFieldConst(11145583988660932112), field.NewFieldConst(16125114195985557867)}, |
|||
{field.NewFieldConst(18437667738670181477), field.NewFieldConst(8593343353929068644)}, |
|||
{field.NewFieldConst(15549894364614350199), field.NewFieldConst(6234736889764963090)}, |
|||
{field.NewFieldConst(17753837009416762390), field.NewFieldConst(15297774054893249240)}, |
|||
{field.NewFieldConst(1465043006528110247), field.NewFieldConst(11029942851654974974)}, |
|||
{field.NewFieldConst(14312704742949520917), field.NewFieldConst(17324353686056674958)}, |
|||
{field.NewFieldConst(8078333430227959261), field.NewFieldConst(14797545414164578336)}, |
|||
{field.NewFieldConst(3544997838139687150), field.NewFieldConst(8846840377946705678)}, |
|||
{field.NewFieldConst(9981846866090807073), field.NewFieldConst(18142560414179130259)}, |
|||
{field.NewFieldConst(1256577435119993994), field.NewFieldConst(155745544208227129)}, |
|||
{field.NewFieldConst(6040293874299819317), field.NewFieldConst(10483265617246740662)}, |
|||
{field.NewFieldConst(976159477616343697), field.NewFieldConst(6356544693059700239)}, |
|||
{field.NewFieldConst(4771747444846377672), field.NewFieldConst(2466985401424965488)}, |
|||
{field.NewFieldConst(9549711421417753693), field.NewFieldConst(9543806479040458857)}, |
|||
{field.NewFieldConst(5277199124405775998), field.NewFieldConst(6251037001966593402)}, |
|||
{field.NewFieldConst(13103543598051591262), field.NewFieldConst(2001921170471454234)}, |
|||
{field.NewFieldConst(1254878001165263070), field.NewFieldConst(17587272030879777460)}, |
|||
{field.NewFieldConst(2300344156307624878), field.NewFieldConst(14356513038946626528)}, |
|||
{field.NewFieldConst(2482567400777596327), field.NewFieldConst(3314129985687795881)}, |
|||
{field.NewFieldConst(16492046206730922155), field.NewFieldConst(1312905854247159931)}, |
|||
{field.NewFieldConst(3061501132630116372), field.NewFieldConst(13315665946615810001)}, |
|||
{field.NewFieldConst(16415932954051444990), field.NewFieldConst(925217124969456536)}, |
|||
{field.NewFieldConst(9764657158286137619), field.NewFieldConst(16039332713210679567)}, |
|||
{field.NewFieldConst(14993545086997628961), field.NewFieldConst(18010329211070748489)}, |
|||
{field.NewFieldConst(17327862012036619887), field.NewFieldConst(16962349802452905993)}, |
|||
{field.NewFieldConst(4826313026336060985), field.NewFieldConst(3597777099127511952)}, |
|||
} |
|||
|
|||
var publicInputsHash = poseidon.PoseidonHashOut{field.ZERO_F, field.ZERO_F, field.ZERO_F, field.ZERO_F} |
|||
|
|||
var publicInputGateExpectedConstraints = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(5101665081776077058), field.NewFieldConst(13601771238484783081)}, |
|||
{field.NewFieldConst(13763997788502656587), field.NewFieldConst(6068443864169526207)}, |
|||
{field.NewFieldConst(10492880302699453810), field.NewFieldConst(11304418575668616669)}, |
|||
{field.NewFieldConst(2175168501339052813), field.NewFieldConst(3658211467579027796)}, |
|||
} |
|||
|
|||
// BaseSumGate { num_limbs: 63 }), (Base: 2)
|
|||
var baseSumGateExpectedConstraints = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(9928715244459351681), field.NewFieldConst(5344081500364361215)}, |
|||
{field.NewFieldConst(10167164649082076581), field.NewFieldConst(15450889555489725096)}, |
|||
{field.NewFieldConst(3546584706462116594), field.NewFieldConst(1476426705388693036)}, |
|||
{field.NewFieldConst(12648634003162244983), field.NewFieldConst(2239452344495239178)}, |
|||
{field.NewFieldConst(2301087631440580451), field.NewFieldConst(11975672920337250307)}, |
|||
{field.NewFieldConst(14001554463269171732), field.NewFieldConst(6953207277617809048)}, |
|||
{field.NewFieldConst(9895590040747031510), field.NewFieldConst(1356956949635190505)}, |
|||
{field.NewFieldConst(14939964178677988571), field.NewFieldConst(454717738260444218)}, |
|||
{field.NewFieldConst(12201660109699192297), field.NewFieldConst(12502457673278583036)}, |
|||
{field.NewFieldConst(1175543972635147885), field.NewFieldConst(11103026408792334489)}, |
|||
{field.NewFieldConst(3384025741923988904), field.NewFieldConst(2656764746353452717)}, |
|||
{field.NewFieldConst(10849522185534943138), field.NewFieldConst(13172212508084788997)}, |
|||
{field.NewFieldConst(10509522572526523739), field.NewFieldConst(2090707475955491976)}, |
|||
{field.NewFieldConst(13692600715410336206), field.NewFieldConst(7227633217973806771)}, |
|||
{field.NewFieldConst(8471053080480597138), field.NewFieldConst(2646922138422495173)}, |
|||
{field.NewFieldConst(555344530120410083), field.NewFieldConst(13860459564781531385)}, |
|||
{field.NewFieldConst(8748801107049442833), field.NewFieldConst(9263752460533085733)}, |
|||
{field.NewFieldConst(13633964398888639692), field.NewFieldConst(10068133633095351031)}, |
|||
{field.NewFieldConst(6911322073377914708), field.NewFieldConst(17978361073083837803)}, |
|||
{field.NewFieldConst(11223090828346729804), field.NewFieldConst(5006610230932979596)}, |
|||
{field.NewFieldConst(11581626217660221266), field.NewFieldConst(16347470001077006094)}, |
|||
{field.NewFieldConst(2924189901864366701), field.NewFieldConst(4309265474738828848)}, |
|||
{field.NewFieldConst(7275314468944461178), field.NewFieldConst(3109308884739285751)}, |
|||
{field.NewFieldConst(12416988612575693809), field.NewFieldConst(13772367397588066248)}, |
|||
{field.NewFieldConst(15438805794425696237), field.NewFieldConst(5809350894111990599)}, |
|||
{field.NewFieldConst(4275145128501503120), field.NewFieldConst(13230668146909969114)}, |
|||
{field.NewFieldConst(15244699495724739585), field.NewFieldConst(7672322205441472064)}, |
|||
{field.NewFieldConst(5429809680618805220), field.NewFieldConst(3153880467220264060)}, |
|||
{field.NewFieldConst(14715345489518514160), field.NewFieldConst(2246036712337629635)}, |
|||
{field.NewFieldConst(9359342125434211935), field.NewFieldConst(7844760208539761732)}, |
|||
{field.NewFieldConst(17550561700498841003), field.NewFieldConst(10851755490050776878)}, |
|||
{field.NewFieldConst(12192385328855013814), field.NewFieldConst(6629056869404844416)}, |
|||
{field.NewFieldConst(3424745785197724925), field.NewFieldConst(9833599393425172230)}, |
|||
{field.NewFieldConst(8602078107149096927), field.NewFieldConst(6592109323720773368)}, |
|||
{field.NewFieldConst(4109716921881297082), field.NewFieldConst(4396469548700606105)}, |
|||
{field.NewFieldConst(10400304110319417426), field.NewFieldConst(1229823145437740976)}, |
|||
{field.NewFieldConst(14853277673343952974), field.NewFieldConst(7653131044140686982)}, |
|||
{field.NewFieldConst(15831955783787857197), field.NewFieldConst(16541106185743830609)}, |
|||
{field.NewFieldConst(16097830673407036871), field.NewFieldConst(917501749911433098)}, |
|||
{field.NewFieldConst(6819428296662518848), field.NewFieldConst(15325182544903569500)}, |
|||
{field.NewFieldConst(3554857310728040215), field.NewFieldConst(17540168721765377170)}, |
|||
{field.NewFieldConst(7246216899469226885), field.NewFieldConst(3184709231158489554)}, |
|||
{field.NewFieldConst(3462793508732024933), field.NewFieldConst(13410498916934897793)}, |
|||
{field.NewFieldConst(784714181705176804), field.NewFieldConst(8079390288171846846)}, |
|||
{field.NewFieldConst(4592501261546923410), field.NewFieldConst(6046244648190342248)}, |
|||
{field.NewFieldConst(14100558314779073910), field.NewFieldConst(9589305391181830029)}, |
|||
{field.NewFieldConst(7208216654581381179), field.NewFieldConst(16662177305876430630)}, |
|||
{field.NewFieldConst(13442246990998561849), field.NewFieldConst(6359024918649040199)}, |
|||
{field.NewFieldConst(16196376030005699590), field.NewFieldConst(5656446490425854681)}, |
|||
{field.NewFieldConst(16279173216505198700), field.NewFieldConst(6278440230935274234)}, |
|||
{field.NewFieldConst(9299204333782277508), field.NewFieldConst(5539548698065086849)}, |
|||
{field.NewFieldConst(531539748103362347), field.NewFieldConst(17008402782657673980)}, |
|||
{field.NewFieldConst(11956287871118080485), field.NewFieldConst(17776888431041950837)}, |
|||
{field.NewFieldConst(16795401491637949606), field.NewFieldConst(12112971435724505573)}, |
|||
{field.NewFieldConst(10141270150228316653), field.NewFieldConst(8738825159351228227)}, |
|||
{field.NewFieldConst(4249416130151320263), field.NewFieldConst(4171109024390883108)}, |
|||
{field.NewFieldConst(13565954345346642147), field.NewFieldConst(11300077318998472624)}, |
|||
{field.NewFieldConst(6006413348327738680), field.NewFieldConst(17429146764001291339)}, |
|||
{field.NewFieldConst(3009379005164242386), field.NewFieldConst(17911649148503516453)}, |
|||
{field.NewFieldConst(4172202865347441020), field.NewFieldConst(6700979848078030374)}, |
|||
{field.NewFieldConst(9692174554453081047), field.NewFieldConst(16461309050820528716)}, |
|||
{field.NewFieldConst(16012555505188709835), field.NewFieldConst(875036531415994728)}, |
|||
{field.NewFieldConst(14527388813134058525), field.NewFieldConst(13371873777459370318)}, |
|||
{field.NewFieldConst(6493493657980111839), field.NewFieldConst(14874520839734823069)}, |
|||
} |
|||
|
|||
// ArithmeticGate { num_ops: 20 }
|
|||
var arithmeticGateExpectedConstraints = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(8251494922795803874), field.NewFieldConst(7884328911897949424)}, |
|||
{field.NewFieldConst(17545754596575389449), field.NewFieldConst(15111927979676704385)}, |
|||
{field.NewFieldConst(10052040965126353731), field.NewFieldConst(1448153912054014611)}, |
|||
{field.NewFieldConst(3878848318701063854), field.NewFieldConst(15999854355391952993)}, |
|||
{field.NewFieldConst(2194699804496089007), field.NewFieldConst(7489112350095609056)}, |
|||
{field.NewFieldConst(666656317372820215), field.NewFieldConst(8333111246649438880)}, |
|||
{field.NewFieldConst(15500013716804095980), field.NewFieldConst(7739144386812042617)}, |
|||
{field.NewFieldConst(2815612394018416154), field.NewFieldConst(15839168197108305099)}, |
|||
{field.NewFieldConst(12980309813768330187), field.NewFieldConst(12446111953378048591)}, |
|||
{field.NewFieldConst(1389916348936822477), field.NewFieldConst(2080258147396834809)}, |
|||
{field.NewFieldConst(3676770229830052631), field.NewFieldConst(8984521981419906260)}, |
|||
{field.NewFieldConst(4759606161035299488), field.NewFieldConst(18415228017149216426)}, |
|||
{field.NewFieldConst(6849567585629675684), field.NewFieldConst(15231001333591586187)}, |
|||
{field.NewFieldConst(17831496121270832947), field.NewFieldConst(1868580989876710210)}, |
|||
{field.NewFieldConst(12226832860244216901), field.NewFieldConst(12352098694767236965)}, |
|||
{field.NewFieldConst(9795530155924375772), field.NewFieldConst(4833402654226660686)}, |
|||
{field.NewFieldConst(7421277748600887772), field.NewFieldConst(16979590244320625600)}, |
|||
{field.NewFieldConst(4212532134312824848), field.NewFieldConst(7938725153260099101)}, |
|||
{field.NewFieldConst(17718231164451799422), field.NewFieldConst(13363195988334771788)}, |
|||
{field.NewFieldConst(5414385531680474153), field.NewFieldConst(13600409983387272243)}, |
|||
} |
|||
|
|||
// RandomAccessGate { bits: 4, num_copies: 4, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
|
|||
var randomAccessGateExpectedConstraints = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(18367067186009695282), field.NewFieldConst(6227937229941915629)}, |
|||
{field.NewFieldConst(342627832935644960), field.NewFieldConst(11262336464371657587)}, |
|||
{field.NewFieldConst(7711502047853221895), field.NewFieldConst(9814305320358879113)}, |
|||
{field.NewFieldConst(2436675870898619939), field.NewFieldConst(12171743011114835714)}, |
|||
{field.NewFieldConst(9224796650008092960), field.NewFieldConst(197827193844666436)}, |
|||
{field.NewFieldConst(7661651717350955969), field.NewFieldConst(3929163527437938921)}, |
|||
{field.NewFieldConst(11994613277879586781), field.NewFieldConst(2918199453077793278)}, |
|||
{field.NewFieldConst(2133315582796573410), field.NewFieldConst(9920472598641951727)}, |
|||
{field.NewFieldConst(5763420675219782924), field.NewFieldConst(193200772658790662)}, |
|||
{field.NewFieldConst(14322103909897767697), field.NewFieldConst(2455403487869979318)}, |
|||
{field.NewFieldConst(3583177870835306708), field.NewFieldConst(15956920993825363087)}, |
|||
{field.NewFieldConst(15767764327818217757), field.NewFieldConst(17814936958431909187)}, |
|||
{field.NewFieldConst(7224551806569620055), field.NewFieldConst(1191241782303323453)}, |
|||
{field.NewFieldConst(3994846439282900915), field.NewFieldConst(16007298430807731888)}, |
|||
{field.NewFieldConst(1904864531973789879), field.NewFieldConst(9374437322489636375)}, |
|||
{field.NewFieldConst(17617411600595291430), field.NewFieldConst(11804426503917788826)}, |
|||
{field.NewFieldConst(5010213812557284606), field.NewFieldConst(8276410914978849008)}, |
|||
{field.NewFieldConst(13701536021647106057), field.NewFieldConst(5043776904396037625)}, |
|||
{field.NewFieldConst(4336267979289896624), field.NewFieldConst(8771134635816393433)}, |
|||
{field.NewFieldConst(17885926480537171976), field.NewFieldConst(9644095314646547597)}, |
|||
{field.NewFieldConst(17179233085824331332), field.NewFieldConst(6950525108693323209)}, |
|||
{field.NewFieldConst(9461258042008745175), field.NewFieldConst(6766975264204597922)}, |
|||
{field.NewFieldConst(10838154179711471883), field.NewFieldConst(16554457937262927355)}, |
|||
{field.NewFieldConst(5823858951686479642), field.NewFieldConst(10171201631442530906)}, |
|||
{field.NewFieldConst(17476953112985367168), field.NewFieldConst(12062851564787792403)}, |
|||
{field.NewFieldConst(7909573710893929152), field.NewFieldConst(6207515797705444652)}, |
|||
} |
|||
|
|||
// PoseidonGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>
|
|||
var poseidonGateExpectedConstraints = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(15438805794425696237), field.NewFieldConst(5809350894111990599)}, |
|||
{field.NewFieldConst(105238306594298866), field.NewFieldConst(6398155585902798861)}, |
|||
{field.NewFieldConst(5256232026568856387), field.NewFieldConst(9253448664982005262)}, |
|||
{field.NewFieldConst(6559974022172208218), field.NewFieldConst(14478753759394222537)}, |
|||
{field.NewFieldConst(7036928093413865537), field.NewFieldConst(895644692646980845)}, |
|||
{field.NewFieldConst(6350074916129003337), field.NewFieldConst(10418298512623677843)}, |
|||
{field.NewFieldConst(6618288817893266284), field.NewFieldConst(17565920952415773065)}, |
|||
{field.NewFieldConst(7214268149308735221), field.NewFieldConst(17797640553663908886)}, |
|||
{field.NewFieldConst(17038147867485750883), field.NewFieldConst(10766691853641769251)}, |
|||
{field.NewFieldConst(1228066111137794024), field.NewFieldConst(1267834319488006514)}, |
|||
{field.NewFieldConst(15317834050441961579), field.NewFieldConst(13280896488837969140)}, |
|||
{field.NewFieldConst(10135227968960430585), field.NewFieldConst(7096433509203324519)}, |
|||
{field.NewFieldConst(10733417635899979276), field.NewFieldConst(16819459255105516700)}, |
|||
{field.NewFieldConst(4231839251429338586), field.NewFieldConst(3213678047797020863)}, |
|||
{field.NewFieldConst(16271445286187692537), field.NewFieldConst(15377656608157234934)}, |
|||
{field.NewFieldConst(9356442829698587975), field.NewFieldConst(14633910545825415036)}, |
|||
{field.NewFieldConst(13952390018297698734), field.NewFieldConst(16325393355066618599)}, |
|||
{field.NewFieldConst(11399251131586292643), field.NewFieldConst(16257107051968717815)}, |
|||
{field.NewFieldConst(4274092107872068929), field.NewFieldConst(15550597684938436610)}, |
|||
{field.NewFieldConst(13076618331457049912), field.NewFieldConst(4958059540220054374)}, |
|||
{field.NewFieldConst(11650097218963026123), field.NewFieldConst(12070947109214611020)}, |
|||
{field.NewFieldConst(2700303408109034014), field.NewFieldConst(5968338348636871194)}, |
|||
{field.NewFieldConst(11508005723655482353), field.NewFieldConst(15224088756564969467)}, |
|||
{field.NewFieldConst(9328231423353697829), field.NewFieldConst(10577349809783627634)}, |
|||
{field.NewFieldConst(556544259468984890), field.NewFieldConst(13376447539117215836)}, |
|||
{field.NewFieldConst(17319865455991589647), field.NewFieldConst(588985536671201497)}, |
|||
{field.NewFieldConst(9528470026616131077), field.NewFieldConst(7257040911301352274)}, |
|||
{field.NewFieldConst(14316182132889623635), field.NewFieldConst(9589165219691594711)}, |
|||
{field.NewFieldConst(10405802815809041956), field.NewFieldConst(13917007789819955074)}, |
|||
{field.NewFieldConst(12560668105252495616), field.NewFieldConst(3591188232548111694)}, |
|||
{field.NewFieldConst(14765117357942682611), field.NewFieldConst(10757853341059462467)}, |
|||
{field.NewFieldConst(6099902163260965551), field.NewFieldConst(11343816861356056114)}, |
|||
{field.NewFieldConst(1083174255539258286), field.NewFieldConst(7587979659522435417)}, |
|||
{field.NewFieldConst(2882552180249608570), field.NewFieldConst(7966658657757662554)}, |
|||
{field.NewFieldConst(13490914415473336227), field.NewFieldConst(63845168436289811)}, |
|||
{field.NewFieldConst(9459794640071212413), field.NewFieldConst(13417331052474309186)}, |
|||
{field.NewFieldConst(18328090807516092318), field.NewFieldConst(11807085063599693782)}, |
|||
{field.NewFieldConst(281059606944328759), field.NewFieldConst(13352248056867426135)}, |
|||
{field.NewFieldConst(10905177588660050370), field.NewFieldConst(6597328385789442670)}, |
|||
{field.NewFieldConst(8426356906491012567), field.NewFieldConst(17214424336396001022)}, |
|||
{field.NewFieldConst(15696035667318839817), field.NewFieldConst(13285870048485492127)}, |
|||
{field.NewFieldConst(6110244444680672193), field.NewFieldConst(17558548349689468031)}, |
|||
{field.NewFieldConst(14614078615782659381), field.NewFieldConst(13184024850613726857)}, |
|||
{field.NewFieldConst(1541592450520953410), field.NewFieldConst(18339388388315914026)}, |
|||
{field.NewFieldConst(8059386643769157052), field.NewFieldConst(10208764910817462305)}, |
|||
{field.NewFieldConst(7612459820354975117), field.NewFieldConst(7582060685277695926)}, |
|||
{field.NewFieldConst(12515587043516861064), field.NewFieldConst(16099239041553682288)}, |
|||
{field.NewFieldConst(14269196473871652102), field.NewFieldConst(1225067220600668761)}, |
|||
{field.NewFieldConst(12691255077510636187), field.NewFieldConst(14147201911063761532)}, |
|||
{field.NewFieldConst(3001134598446056765), field.NewFieldConst(14313090483058155636)}, |
|||
{field.NewFieldConst(13964993951988177315), field.NewFieldConst(17731737838539414275)}, |
|||
{field.NewFieldConst(2686259154263524343), field.NewFieldConst(12198712301337570859)}, |
|||
{field.NewFieldConst(6730431920128908773), field.NewFieldConst(4325394084875720868)}, |
|||
{field.NewFieldConst(988774723104779817), field.NewFieldConst(8388266879854983623)}, |
|||
{field.NewFieldConst(8233087560647959985), field.NewFieldConst(7751837576340060020)}, |
|||
{field.NewFieldConst(9546113779017699592), field.NewFieldConst(4049920632309298778)}, |
|||
{field.NewFieldConst(3283837251411237060), field.NewFieldConst(13560940050752580093)}, |
|||
{field.NewFieldConst(10388838746951897109), field.NewFieldConst(454393475113110282)}, |
|||
{field.NewFieldConst(2208016536897042313), field.NewFieldConst(17105586471193083308)}, |
|||
{field.NewFieldConst(17683990802267567604), field.NewFieldConst(15398473956537380705)}, |
|||
{field.NewFieldConst(70612752050386177), field.NewFieldConst(12349994002954022957)}, |
|||
{field.NewFieldConst(13794244952989612728), field.NewFieldConst(15888581169565306348)}, |
|||
{field.NewFieldConst(8270800566553141412), field.NewFieldConst(1516938823651329185)}, |
|||
{field.NewFieldConst(643507941153616368), field.NewFieldConst(3893451216814345882)}, |
|||
{field.NewFieldConst(16464837166410943694), field.NewFieldConst(11108183142967610977)}, |
|||
{field.NewFieldConst(9748621820629198396), field.NewFieldConst(3766489907402036319)}, |
|||
{field.NewFieldConst(3115179618981245947), field.NewFieldConst(10160994694067456423)}, |
|||
{field.NewFieldConst(4497210741038443097), field.NewFieldConst(6445446770984515259)}, |
|||
{field.NewFieldConst(5470898125882256227), field.NewFieldConst(8249357863801204908)}, |
|||
{field.NewFieldConst(16762380205819269382), field.NewFieldConst(172510727904060494)}, |
|||
{field.NewFieldConst(7920011253931301350), field.NewFieldConst(9681193995678483756)}, |
|||
{field.NewFieldConst(8258951043315574232), field.NewFieldConst(13137471323476190588)}, |
|||
{field.NewFieldConst(4339364527801481944), field.NewFieldConst(16862579756243326257)}, |
|||
{field.NewFieldConst(8980029737458438570), field.NewFieldConst(14651625524257781922)}, |
|||
{field.NewFieldConst(17935993907375677671), field.NewFieldConst(5318319737405476029)}, |
|||
{field.NewFieldConst(716791501623731831), field.NewFieldConst(18425818060734993303)}, |
|||
{field.NewFieldConst(601549076806364660), field.NewFieldConst(12303919727550310013)}, |
|||
{field.NewFieldConst(18026376178895562118), field.NewFieldConst(14687420532194520529)}, |
|||
{field.NewFieldConst(16943892475592026666), field.NewFieldConst(7451688507369746594)}, |
|||
{field.NewFieldConst(8724072308842121373), field.NewFieldConst(11662986251379699921)}, |
|||
{field.NewFieldConst(3201079129905071298), field.NewFieldConst(11542621183935331871)}, |
|||
{field.NewFieldConst(9889739070824270529), field.NewFieldConst(3891825006545095657)}, |
|||
{field.NewFieldConst(15538978715382418651), field.NewFieldConst(2419672705453973015)}, |
|||
{field.NewFieldConst(3001525234835174062), field.NewFieldConst(17115969716224377534)}, |
|||
{field.NewFieldConst(18001237923148428045), field.NewFieldConst(2198015511953873786)}, |
|||
{field.NewFieldConst(14186741561112601666), field.NewFieldConst(13156405199205086627)}, |
|||
{field.NewFieldConst(10166592177477126663), field.NewFieldConst(13586051001537885658)}, |
|||
{field.NewFieldConst(8678352780562557555), field.NewFieldConst(1968366090049630482)}, |
|||
{field.NewFieldConst(5627999915794840395), field.NewFieldConst(13597556392696072088)}, |
|||
{field.NewFieldConst(9291327714650886898), field.NewFieldConst(2411361999629511024)}, |
|||
{field.NewFieldConst(6824943761729555359), field.NewFieldConst(7484507209360908175)}, |
|||
{field.NewFieldConst(6276580084700132178), field.NewFieldConst(6246691657613415035)}, |
|||
{field.NewFieldConst(10736230409698057656), field.NewFieldConst(7306720219045064925)}, |
|||
{field.NewFieldConst(15442170485732017109), field.NewFieldConst(1739984147692575725)}, |
|||
{field.NewFieldConst(4448878124301402845), field.NewFieldConst(18436455114977877323)}, |
|||
{field.NewFieldConst(638012599023653143), field.NewFieldConst(16265955502846626936)}, |
|||
{field.NewFieldConst(6793907577559820653), field.NewFieldConst(15343551069946118619)}, |
|||
{field.NewFieldConst(17903286158968614509), field.NewFieldConst(9559701571149911252)}, |
|||
{field.NewFieldConst(14652006464960400785), field.NewFieldConst(50421020503848143)}, |
|||
{field.NewFieldConst(9452858006432860845), field.NewFieldConst(2625726945677447428)}, |
|||
{field.NewFieldConst(853640589013584892), field.NewFieldConst(14655161412118141649)}, |
|||
{field.NewFieldConst(12863832006745352780), field.NewFieldConst(14564189651136231029)}, |
|||
{field.NewFieldConst(8551517270810530438), field.NewFieldConst(10859465327758962622)}, |
|||
{field.NewFieldConst(10113468436120661191), field.NewFieldConst(16040944006557911589)}, |
|||
{field.NewFieldConst(4921439225277518643), field.NewFieldConst(8399175422965154512)}, |
|||
{field.NewFieldConst(13068240354812957183), field.NewFieldConst(8520393046894990946)}, |
|||
{field.NewFieldConst(1189183420107219532), field.NewFieldConst(18066897627856601789)}, |
|||
{field.NewFieldConst(3997900004790871153), field.NewFieldConst(1269718920871578117)}, |
|||
{field.NewFieldConst(15438784576472256462), field.NewFieldConst(9577304425687441047)}, |
|||
{field.NewFieldConst(17158083218962275971), field.NewFieldConst(17379790274576244684)}, |
|||
{field.NewFieldConst(3470452736936929010), field.NewFieldConst(12769555113044633230)}, |
|||
{field.NewFieldConst(18389243269515626865), field.NewFieldConst(8023737530782576805)}, |
|||
{field.NewFieldConst(3529213023405995549), field.NewFieldConst(8829896701928525938)}, |
|||
{field.NewFieldConst(14072413770981804653), field.NewFieldConst(9660693090213237836)}, |
|||
{field.NewFieldConst(14369435038913678671), field.NewFieldConst(7659129852562422871)}, |
|||
{field.NewFieldConst(6779301728445724040), field.NewFieldConst(18290152515233036523)}, |
|||
{field.NewFieldConst(8113954200727174254), field.NewFieldConst(16490002532983549952)}, |
|||
{field.NewFieldConst(11465655095604389561), field.NewFieldConst(9066100972825318010)}, |
|||
{field.NewFieldConst(15998691377748321442), field.NewFieldConst(16970045124898180365)}, |
|||
{field.NewFieldConst(8424730626816696233), field.NewFieldConst(17168184083072399403)}, |
|||
{field.NewFieldConst(1941959246552302666), field.NewFieldConst(6751013195867127440)}, |
|||
{field.NewFieldConst(1907519456922228224), field.NewFieldConst(689311996911195932)}, |
|||
{field.NewFieldConst(16277197060525435740), field.NewFieldConst(12018417724719716072)}, |
|||
} |
|||
|
|||
var reducingExtensionGateExpectedConstraints = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(12832102811425062912), field.NewFieldConst(2979695993654444095)}, |
|||
{field.NewFieldConst(4822478941232734654), field.NewFieldConst(2600327308894333341)}, |
|||
{field.NewFieldConst(12450653411048814602), field.NewFieldConst(1161667420593062956)}, |
|||
{field.NewFieldConst(3145631295867407955), field.NewFieldConst(1702059944088737075)}, |
|||
{field.NewFieldConst(4597190091407364771), field.NewFieldConst(4257077286672555409)}, |
|||
{field.NewFieldConst(10177664366491925772), field.NewFieldConst(10489575701186298604)}, |
|||
{field.NewFieldConst(2754621968864722399), field.NewFieldConst(12087963411706301871)}, |
|||
{field.NewFieldConst(534408217555793149), field.NewFieldConst(12559345737194357169)}, |
|||
{field.NewFieldConst(9508765820222303634), field.NewFieldConst(14102461861317982082)}, |
|||
{field.NewFieldConst(15070954032232801974), field.NewFieldConst(2078249670161696735)}, |
|||
{field.NewFieldConst(10465809629504954691), field.NewFieldConst(16223748685835312497)}, |
|||
{field.NewFieldConst(10957196413441800202), field.NewFieldConst(3841214025425953691)}, |
|||
{field.NewFieldConst(18438848195188240825), field.NewFieldConst(5697684145424680565)}, |
|||
{field.NewFieldConst(565455534266129104), field.NewFieldConst(12543354947937779806)}, |
|||
{field.NewFieldConst(16376588778962418386), field.NewFieldConst(1273250903423198860)}, |
|||
{field.NewFieldConst(4128104469872810921), field.NewFieldConst(1433037233801071123)}, |
|||
{field.NewFieldConst(6011337242244377340), field.NewFieldConst(16068106780789397185)}, |
|||
{field.NewFieldConst(4741354504248328629), field.NewFieldConst(3000853646720964165)}, |
|||
{field.NewFieldConst(13064594310789140866), field.NewFieldConst(10950406741883971259)}, |
|||
{field.NewFieldConst(17079026691450750925), field.NewFieldConst(6522027970928818261)}, |
|||
{field.NewFieldConst(13158136237489326416), field.NewFieldConst(7677629162183242732)}, |
|||
{field.NewFieldConst(14741398060174921234), field.NewFieldConst(2960243215156352194)}, |
|||
{field.NewFieldConst(9111161782199179468), field.NewFieldConst(8010960876261510099)}, |
|||
{field.NewFieldConst(1404837029582986528), field.NewFieldConst(9377230983302764181)}, |
|||
{field.NewFieldConst(7086781234814455260), field.NewFieldConst(7571558192372650697)}, |
|||
{field.NewFieldConst(5627013434503229817), field.NewFieldConst(14984048934926143304)}, |
|||
{field.NewFieldConst(2115495655441739405), field.NewFieldConst(1656704965110317534)}, |
|||
{field.NewFieldConst(2311846135199651566), field.NewFieldConst(17438437808346967358)}, |
|||
{field.NewFieldConst(8679806319651401773), field.NewFieldConst(3278538718508560579)}, |
|||
{field.NewFieldConst(7897681105604536660), field.NewFieldConst(10966573925848082711)}, |
|||
{field.NewFieldConst(5451958405177630542), field.NewFieldConst(9207735009647199721)}, |
|||
{field.NewFieldConst(8825486358121162697), field.NewFieldConst(15997852519026522914)}, |
|||
{field.NewFieldConst(475225211669491693), field.NewFieldConst(1907827506180042626)}, |
|||
{field.NewFieldConst(16033031089519343732), field.NewFieldConst(15009948832718035672)}, |
|||
{field.NewFieldConst(5048598591200038865), field.NewFieldConst(156574475928756206)}, |
|||
{field.NewFieldConst(3580311624647961767), field.NewFieldConst(6084715537433906996)}, |
|||
{field.NewFieldConst(9121009921295095324), field.NewFieldConst(18407759801432275235)}, |
|||
{field.NewFieldConst(16569013039730214123), field.NewFieldConst(3930908108224055041)}, |
|||
{field.NewFieldConst(13844066138909451365), field.NewFieldConst(6585754647203519368)}, |
|||
{field.NewFieldConst(14133345335167543367), field.NewFieldConst(3946807387480232364)}, |
|||
{field.NewFieldConst(9876285028806980582), field.NewFieldConst(40898067822033734)}, |
|||
{field.NewFieldConst(6293483059765701407), field.NewFieldConst(16009270905706605849)}, |
|||
{field.NewFieldConst(11635947241393753594), field.NewFieldConst(5053395178858294866)}, |
|||
{field.NewFieldConst(16062194595705166277), field.NewFieldConst(752574348595159408)}, |
|||
{field.NewFieldConst(15607597716340375230), field.NewFieldConst(10428583315124220143)}, |
|||
{field.NewFieldConst(6975301479426228318), field.NewFieldConst(16528136630898216147)}, |
|||
{field.NewFieldConst(16312827398430223622), field.NewFieldConst(17909475722464415780)}, |
|||
{field.NewFieldConst(2273087545743905667), field.NewFieldConst(12405446777919046866)}, |
|||
{field.NewFieldConst(14781933506876191161), field.NewFieldConst(4464109151368149713)}, |
|||
{field.NewFieldConst(4226716729950095934), field.NewFieldConst(8908251769229049654)}, |
|||
{field.NewFieldConst(8310476487592089883), field.NewFieldConst(3834672170570438819)}, |
|||
{field.NewFieldConst(4285568636604940795), field.NewFieldConst(7183765355016179794)}, |
|||
{field.NewFieldConst(14300853697824059506), field.NewFieldConst(16287477445929928328)}, |
|||
{field.NewFieldConst(1238186507267033247), field.NewFieldConst(12357102109973664962)}, |
|||
{field.NewFieldConst(15607388919140050768), field.NewFieldConst(15421065238069253306)}, |
|||
{field.NewFieldConst(12418734453826432586), field.NewFieldConst(12072056126139297564)}, |
|||
{field.NewFieldConst(3924467115116313620), field.NewFieldConst(1212362379653628161)}, |
|||
{field.NewFieldConst(8252514850759544679), field.NewFieldConst(7893938436444134034)}, |
|||
{field.NewFieldConst(711675815009325200), field.NewFieldConst(15678724077367989757)}, |
|||
{field.NewFieldConst(10920573406841924033), field.NewFieldConst(8189696933773246220)}, |
|||
{field.NewFieldConst(9737295100232588618), field.NewFieldConst(13383462338120177171)}, |
|||
{field.NewFieldConst(8983013033045953935), field.NewFieldConst(5301160793103788033)}, |
|||
{field.NewFieldConst(2086512740154274197), field.NewFieldConst(9511985884344255651)}, |
|||
{field.NewFieldConst(7404726366142548080), field.NewFieldConst(11257391295697140486)}, |
|||
{field.NewFieldConst(10045968629671906256), field.NewFieldConst(10721172752468420959)}, |
|||
{field.NewFieldConst(9499240237398016191), field.NewFieldConst(17996498955496851489)}, |
|||
} |
|||
|
|||
// ReducingGate { num_coeffs: 44 }
|
|||
var reducingGateExpectedConstraints = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(4189565386714553574), field.NewFieldConst(14972099283023295929)}, |
|||
{field.NewFieldConst(4811224976739448335), field.NewFieldConst(17901409314576454439)}, |
|||
{field.NewFieldConst(5140059407491502784), field.NewFieldConst(1144330742785924570)}, |
|||
{field.NewFieldConst(7077436393778991453), field.NewFieldConst(13398199711778224412)}, |
|||
{field.NewFieldConst(11213768990622043903), field.NewFieldConst(3886053425349218150)}, |
|||
{field.NewFieldConst(2946099412905029571), field.NewFieldConst(16515307040211357295)}, |
|||
{field.NewFieldConst(11766152895257088950), field.NewFieldConst(12561350435611412995)}, |
|||
{field.NewFieldConst(15559670172179416359), field.NewFieldConst(14246884723129607378)}, |
|||
{field.NewFieldConst(5240707719525548158), field.NewFieldConst(1640773599873992510)}, |
|||
{field.NewFieldConst(14358821079049832289), field.NewFieldConst(2746855687282611080)}, |
|||
{field.NewFieldConst(3214086216088588558), field.NewFieldConst(1520697626094905530)}, |
|||
{field.NewFieldConst(9834748172213967248), field.NewFieldConst(13487010468070558667)}, |
|||
{field.NewFieldConst(1423442768503334248), field.NewFieldConst(10945790255819476518)}, |
|||
{field.NewFieldConst(2308372186436983690), field.NewFieldConst(8803174935784778070)}, |
|||
{field.NewFieldConst(9995833078447025147), field.NewFieldConst(9074310518079663649)}, |
|||
{field.NewFieldConst(14149697874498108875), field.NewFieldConst(15875817120435194028)}, |
|||
{field.NewFieldConst(14564758547073982656), field.NewFieldConst(13386335755835868953)}, |
|||
{field.NewFieldConst(6432745607675418074), field.NewFieldConst(8030247499566565321)}, |
|||
{field.NewFieldConst(17308235779926438117), field.NewFieldConst(16843697410674499818)}, |
|||
{field.NewFieldConst(15507223129386571868), field.NewFieldConst(3935281607585552366)}, |
|||
{field.NewFieldConst(16041402982622709805), field.NewFieldConst(12432717078068957835)}, |
|||
{field.NewFieldConst(6455955094164032063), field.NewFieldConst(2435635342699968412)}, |
|||
{field.NewFieldConst(9814981570869789379), field.NewFieldConst(5009257884262115226)}, |
|||
{field.NewFieldConst(9452031978763862902), field.NewFieldConst(15609083603899848676)}, |
|||
{field.NewFieldConst(13532623109002857304), field.NewFieldConst(7324541443245949391)}, |
|||
{field.NewFieldConst(7899075212455453622), field.NewFieldConst(14276489152002439614)}, |
|||
{field.NewFieldConst(2403019844704266911), field.NewFieldConst(5922544710604013781)}, |
|||
{field.NewFieldConst(9709471021111675830), field.NewFieldConst(5538539165068927028)}, |
|||
{field.NewFieldConst(15700585567216041265), field.NewFieldConst(17893894492159337326)}, |
|||
{field.NewFieldConst(8890003199638063977), field.NewFieldConst(17726621767321974437)}, |
|||
{field.NewFieldConst(389239919653982052), field.NewFieldConst(3497778410650283061)}, |
|||
{field.NewFieldConst(845227572644858827), field.NewFieldConst(7040344997713673855)}, |
|||
{field.NewFieldConst(9861253052349275208), field.NewFieldConst(1880449137233040023)}, |
|||
{field.NewFieldConst(9239454143759318515), field.NewFieldConst(7968256557482935820)}, |
|||
{field.NewFieldConst(12576879243038758854), field.NewFieldConst(9784626207087825707)}, |
|||
{field.NewFieldConst(14811673587164089973), field.NewFieldConst(10785522535030299714)}, |
|||
{field.NewFieldConst(696437091186897361), field.NewFieldConst(13293602092569033065)}, |
|||
{field.NewFieldConst(1240161179290551759), field.NewFieldConst(9542275505416038259)}, |
|||
{field.NewFieldConst(5298553932515957396), field.NewFieldConst(14597738151157731445)}, |
|||
{field.NewFieldConst(8472517818840783225), field.NewFieldConst(7685861056688910111)}, |
|||
{field.NewFieldConst(10067665523858551777), field.NewFieldConst(13019870415534016025)}, |
|||
{field.NewFieldConst(3030966178198674680), field.NewFieldConst(10107838846102885642)}, |
|||
{field.NewFieldConst(6762889891370677550), field.NewFieldConst(16151528872832782368)}, |
|||
{field.NewFieldConst(17207754552662723664), field.NewFieldConst(15168039969859158460)}, |
|||
{field.NewFieldConst(9111161782199179468), field.NewFieldConst(8010960876261510099)}, |
|||
{field.NewFieldConst(1212079098724692260), field.NewFieldConst(3976842077579916925)}, |
|||
{field.NewFieldConst(8111924351272477885), field.NewFieldConst(1472738463707044435)}, |
|||
{field.NewFieldConst(14549763060495382561), field.NewFieldConst(8148654488443197206)}, |
|||
{field.NewFieldConst(9633247645878352168), field.NewFieldConst(4173826759172401145)}, |
|||
{field.NewFieldConst(13429667484612728110), field.NewFieldConst(139708813783643870)}, |
|||
{field.NewFieldConst(11164941208889426013), field.NewFieldConst(3615779386887825309)}, |
|||
{field.NewFieldConst(15733773570058687441), field.NewFieldConst(11172582394325691371)}, |
|||
{field.NewFieldConst(11237663549079845099), field.NewFieldConst(375954911737718734)}, |
|||
{field.NewFieldConst(14815280969174152094), field.NewFieldConst(17903238907570421232)}, |
|||
{field.NewFieldConst(12264332321023153985), field.NewFieldConst(4996015210046477989)}, |
|||
{field.NewFieldConst(5733452693326962912), field.NewFieldConst(15445457134261228447)}, |
|||
{field.NewFieldConst(11339891595047637420), field.NewFieldConst(762619178430884475)}, |
|||
{field.NewFieldConst(10413672060220880988), field.NewFieldConst(2522708614237496949)}, |
|||
{field.NewFieldConst(4759794002943168525), field.NewFieldConst(8366670758049431064)}, |
|||
{field.NewFieldConst(11081128192182141387), field.NewFieldConst(5264843790841556843)}, |
|||
{field.NewFieldConst(16467547707866820269), field.NewFieldConst(10395994280728082037)}, |
|||
{field.NewFieldConst(7372902852922723938), field.NewFieldConst(6597057511414169148)}, |
|||
{field.NewFieldConst(1246550990665510080), field.NewFieldConst(369146659419534786)}, |
|||
{field.NewFieldConst(107137977263990694), field.NewFieldConst(13480217899797734610)}, |
|||
{field.NewFieldConst(9352391006524927052), field.NewFieldConst(16474580549927501346)}, |
|||
{field.NewFieldConst(11475195577527382963), field.NewFieldConst(16771481018793784004)}, |
|||
{field.NewFieldConst(7763817490144412733), field.NewFieldConst(7847907679735875325)}, |
|||
{field.NewFieldConst(6954934416977006194), field.NewFieldConst(1588175103882481774)}, |
|||
{field.NewFieldConst(208699790124989138), field.NewFieldConst(104050776110144395)}, |
|||
{field.NewFieldConst(1999712470949493845), field.NewFieldConst(14640293671425837284)}, |
|||
{field.NewFieldConst(17489389210332023693), field.NewFieldConst(1485853484717956236)}, |
|||
{field.NewFieldConst(13389678828109836153), field.NewFieldConst(12239927773742888217)}, |
|||
{field.NewFieldConst(7279356606052782033), field.NewFieldConst(16889809967345118643)}, |
|||
{field.NewFieldConst(5530632913824527303), field.NewFieldConst(6593916246324540830)}, |
|||
{field.NewFieldConst(6517985275757881887), field.NewFieldConst(1094679265639341934)}, |
|||
{field.NewFieldConst(16005022297334791008), field.NewFieldConst(2231375568117939019)}, |
|||
{field.NewFieldConst(7801581545066110268), field.NewFieldConst(16195585011186011335)}, |
|||
{field.NewFieldConst(2346311239309318787), field.NewFieldConst(10194252071441594046)}, |
|||
{field.NewFieldConst(1333414916806612489), field.NewFieldConst(4078668601880487193)}, |
|||
{field.NewFieldConst(17162202837341088150), field.NewFieldConst(3946492721743094611)}, |
|||
{field.NewFieldConst(2372952988964786162), field.NewFieldConst(14459600129361968991)}, |
|||
{field.NewFieldConst(15958985504784681452), field.NewFieldConst(18297567352909625870)}, |
|||
{field.NewFieldConst(5468110010239944205), field.NewFieldConst(1297673223075459793)}, |
|||
{field.NewFieldConst(5916958362061888790), field.NewFieldConst(12686064186569549334)}, |
|||
{field.NewFieldConst(17141186363273294375), field.NewFieldConst(5330662447468959333)}, |
|||
{field.NewFieldConst(9597329746711776008), field.NewFieldConst(13290917949843243492)}, |
|||
{field.NewFieldConst(9061260430036409956), field.NewFieldConst(10642927510372211646)}, |
|||
{field.NewFieldConst(9766392710518436993), field.NewFieldConst(1864738510099355769)}, |
|||
} |
|||
|
|||
// ArithmeticExtensionGate { num_ops: 10 }
|
|||
var arithmeticExtensionGateExpectedConstraints = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(14556369430662721230), field.NewFieldConst(4131185000258568561)}, |
|||
{field.NewFieldConst(16378466706564867046), field.NewFieldConst(1439052841211884527)}, |
|||
{field.NewFieldConst(8231479592213172392), field.NewFieldConst(8409169031581010782)}, |
|||
{field.NewFieldConst(5465959779370835700), field.NewFieldConst(17016702720873000919)}, |
|||
{field.NewFieldConst(10611951970626560747), field.NewFieldConst(11015475306668399283)}, |
|||
{field.NewFieldConst(6566683434087540889), field.NewFieldConst(7528162900166069532)}, |
|||
{field.NewFieldConst(13167150559619768862), field.NewFieldConst(15618445283750881414)}, |
|||
{field.NewFieldConst(14768578132422983729), field.NewFieldConst(13938407401080069149)}, |
|||
{field.NewFieldConst(18415232841919605685), field.NewFieldConst(15088528771916927003)}, |
|||
{field.NewFieldConst(1305736199568141897), field.NewFieldConst(16885250849392919438)}, |
|||
{field.NewFieldConst(1425549592953864549), field.NewFieldConst(1074162823816629148)}, |
|||
{field.NewFieldConst(12616210534513128803), field.NewFieldConst(8618852250387339753)}, |
|||
{field.NewFieldConst(16775588216530426832), field.NewFieldConst(16358913853138883160)}, |
|||
{field.NewFieldConst(236831045676808583), field.NewFieldConst(16231688985959438642)}, |
|||
{field.NewFieldConst(264831195814170716), field.NewFieldConst(9852325877887114505)}, |
|||
{field.NewFieldConst(14065541678187010167), field.NewFieldConst(5594602585697559035)}, |
|||
{field.NewFieldConst(2354884863196165822), field.NewFieldConst(12715102096346587892)}, |
|||
{field.NewFieldConst(5881791209743274427), field.NewFieldConst(1913490798645218291)}, |
|||
{field.NewFieldConst(3621056055759314065), field.NewFieldConst(15076066883455218113)}, |
|||
{field.NewFieldConst(15382741815013668685), field.NewFieldConst(5674166256062091576)}, |
|||
} |
|||
|
|||
// MulExtensionGate { num_ops: 13 }
|
|||
var mulExtensionGateExpectedConstraints = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(14558272317822654580), field.NewFieldConst(833215892324477732)}, |
|||
{field.NewFieldConst(9214806296346539012), field.NewFieldConst(7798842673847612486)}, |
|||
{field.NewFieldConst(4933313819253472884), field.NewFieldConst(17115399133104593821)}, |
|||
{field.NewFieldConst(6382294466663581729), field.NewFieldConst(8863722647290983592)}, |
|||
{field.NewFieldConst(5274430631758054179), field.NewFieldConst(1761561038204031519)}, |
|||
{field.NewFieldConst(6975818216493368257), field.NewFieldConst(3643153118790582585)}, |
|||
{field.NewFieldConst(9382708770545050748), field.NewFieldConst(2040988809014144797)}, |
|||
{field.NewFieldConst(7526300035416853327), field.NewFieldConst(8692405747344509879)}, |
|||
{field.NewFieldConst(6092157877842311771), field.NewFieldConst(5767914690949635280)}, |
|||
{field.NewFieldConst(3636879736078164520), field.NewFieldConst(454792903724498694)}, |
|||
{field.NewFieldConst(5982213211108308130), field.NewFieldConst(3906161453783544349)}, |
|||
{field.NewFieldConst(1353999567434327832), field.NewFieldConst(3912356165392315450)}, |
|||
{field.NewFieldConst(3866250282554618990), field.NewFieldConst(14215790041865539111)}, |
|||
{field.NewFieldConst(16972659905821970574), field.NewFieldConst(2550277288305104044)}, |
|||
{field.NewFieldConst(6739526869755283609), field.NewFieldConst(4676222628249438354)}, |
|||
{field.NewFieldConst(18314541579046409607), field.NewFieldConst(13871312232745645647)}, |
|||
{field.NewFieldConst(13309435341537760906), field.NewFieldConst(10879629980202564460)}, |
|||
{field.NewFieldConst(8149445702527176593), field.NewFieldConst(12079787385488004774)}, |
|||
{field.NewFieldConst(141936326832390573), field.NewFieldConst(9852981409020916366)}, |
|||
{field.NewFieldConst(1174277439708011834), field.NewFieldConst(11084240604056156653)}, |
|||
{field.NewFieldConst(3890191667424476902), field.NewFieldConst(1428130379783403165)}, |
|||
{field.NewFieldConst(18264002552181363059), field.NewFieldConst(17855293364353531924)}, |
|||
{field.NewFieldConst(1657518282890904146), field.NewFieldConst(14874491364689193658)}, |
|||
{field.NewFieldConst(9091236796792826297), field.NewFieldConst(18232800981045995203)}, |
|||
{field.NewFieldConst(7965395014621568897), field.NewFieldConst(15643014489741966811)}, |
|||
{field.NewFieldConst(14048129594584036134), field.NewFieldConst(8880723489474532129)}, |
|||
} |
|||
|
|||
// CosetInterpolationGate { subgroup_bits: 4, degree: 6, barycentric_weights: [17293822565076172801, 18374686475376656385, 18446744069413535745, 281474976645120, 17592186044416, 18446744069414584577, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 18446744069415632897, 18446462594437939201, 18446726477228539905, 18446744069414584065, 68719476720, 4294967296], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
|
|||
var cosetInterpolationGateExpectedConstraints = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(4489474937116132272), field.NewFieldConst(17966585078409280607)}, |
|||
{field.NewFieldConst(6284821823752419954), field.NewFieldConst(15732864946173560339)}, |
|||
{field.NewFieldConst(12879723719779486283), field.NewFieldConst(983649133858104142)}, |
|||
{field.NewFieldConst(17293136937393925432), field.NewFieldConst(4033193666483141970)}, |
|||
{field.NewFieldConst(10809912963683055710), field.NewFieldConst(3166226310305151244)}, |
|||
{field.NewFieldConst(13051854837169808452), field.NewFieldConst(12636844243964449888)}, |
|||
{field.NewFieldConst(15180422697988222141), field.NewFieldConst(3172471974421734205)}, |
|||
{field.NewFieldConst(7715327263429433235), field.NewFieldConst(14269461688353925342)}, |
|||
{field.NewFieldConst(7348198793616724228), field.NewFieldConst(11426363269581761252)}, |
|||
{field.NewFieldConst(6529761710182712179), field.NewFieldConst(15370899814178958348)}, |
|||
{field.NewFieldConst(1312640305437468539), field.NewFieldConst(7416725026793550034)}, |
|||
{field.NewFieldConst(7435934314089172319), field.NewFieldConst(8931511780309647479)}, |
|||
} |
|||
|
|||
// PoseidonMdsGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>"
|
|||
var poseidonMdsGateExpectedConstraints = []field.QuadraticExtension{ |
|||
{field.NewFieldConst(7821764612044984890), field.NewFieldConst(11645399715550800761)}, |
|||
{field.NewFieldConst(7054686226368496581), field.NewFieldConst(3456599659382547499)}, |
|||
{field.NewFieldConst(9932401212201586910), field.NewFieldConst(15935184283784595275)}, |
|||
{field.NewFieldConst(14850232436396031573), field.NewFieldConst(10054869170615550942)}, |
|||
{field.NewFieldConst(17859784214232634920), field.NewFieldConst(3141019307077014353)}, |
|||
{field.NewFieldConst(1316926243065869924), field.NewFieldConst(5447399801288094074)}, |
|||
{field.NewFieldConst(12198784876096903918), field.NewFieldConst(10976551553233951532)}, |
|||
{field.NewFieldConst(3280500541526908156), field.NewFieldConst(1813330468204166522)}, |
|||
{field.NewFieldConst(6788483962196012692), field.NewFieldConst(15983747071745976199)}, |
|||
{field.NewFieldConst(3372073447943379816), field.NewFieldConst(9356836818900551936)}, |
|||
{field.NewFieldConst(13834815153351545489), field.NewFieldConst(1073963211629459057)}, |
|||
{field.NewFieldConst(15376716257200419051), field.NewFieldConst(16044430964768811142)}, |
|||
{field.NewFieldConst(16752138206727891451), field.NewFieldConst(6303059651352280564)}, |
|||
{field.NewFieldConst(17195959285241102556), field.NewFieldConst(10990140109461952122)}, |
|||
{field.NewFieldConst(16812594260057394716), field.NewFieldConst(5841834090350584793)}, |
|||
{field.NewFieldConst(17706037262140285164), field.NewFieldConst(8626184557677598926)}, |
|||
{field.NewFieldConst(6826825357492466350), field.NewFieldConst(17865947929743097490)}, |
|||
{field.NewFieldConst(13679887869755160737), field.NewFieldConst(16481628195512675795)}, |
|||
{field.NewFieldConst(7881296289635150478), field.NewFieldConst(15368930380652981390)}, |
|||
{field.NewFieldConst(12075171536836315078), field.NewFieldConst(12900345753644751245)}, |
|||
{field.NewFieldConst(11461113822534614109), field.NewFieldConst(2937306395206947398)}, |
|||
{field.NewFieldConst(18365572828001780476), field.NewFieldConst(4309067613742479326)}, |
|||
{field.NewFieldConst(9460729461000852035), field.NewFieldConst(9232487430983842586)}, |
|||
{field.NewFieldConst(9920817005263779727), field.NewFieldConst(16326126591726196229)}, |
|||
} |
|||
|
|||
type TestGateCircuit struct { |
|||
testGate gates.Gate |
|||
ExpectedConstraints []field.QuadraticExtension |
|||
} |
|||
|
|||
func (circuit *TestGateCircuit) Define(api frontend.API) error { |
|||
commonCircuitData := utils.DeserializeCommonCircuitData("../../data/decode_block/common_circuit_data.json") |
|||
numSelectors := commonCircuitData.SelectorsInfo.NumSelectors() |
|||
|
|||
fieldAPI := field.NewFieldAPI(api) |
|||
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI) |
|||
|
|||
vars := gates.NewEvaluationVars(localConstants[numSelectors:], localWires, publicInputsHash) |
|||
|
|||
constraints := circuit.testGate.EvalUnfiltered(api, qeAPI, *vars) |
|||
|
|||
if len(constraints) != len(circuit.ExpectedConstraints) { |
|||
return errors.New("gate constraints length mismatch") |
|||
} |
|||
for i := 0; i < len(constraints); i++ { |
|||
qeAPI.AssertIsEqual(constraints[i], circuit.ExpectedConstraints[i]) |
|||
} |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func TestGates(t *testing.T) { |
|||
assert := test.NewAssert(t) |
|||
|
|||
testCase := func(testGate gates.Gate, expectedConstraints []field.QuadraticExtension) { |
|||
circuit := &TestGateCircuit{testGate: testGate, ExpectedConstraints: expectedConstraints} |
|||
witness := &TestGateCircuit{testGate: testGate, ExpectedConstraints: expectedConstraints} |
|||
err := test.IsSolved(circuit, witness, field.TEST_CURVE.ScalarField()) |
|||
assert.NoError(err) |
|||
} |
|||
|
|||
type gateTest struct { |
|||
testGate gates.Gate |
|||
expectedConstraints []field.QuadraticExtension |
|||
} |
|||
|
|||
gateTests := []gateTest{ |
|||
{gates.NewPublicInputGate(), publicInputGateExpectedConstraints}, |
|||
{gates.NewBaseSumGate(63, 2), baseSumGateExpectedConstraints}, |
|||
{gates.NewArithmeticGate(20), arithmeticGateExpectedConstraints}, |
|||
{gates.NewRandomAccessGate(4, 4, 2), randomAccessGateExpectedConstraints}, |
|||
{gates.NewPoseidonGate(), poseidonGateExpectedConstraints}, |
|||
{gates.NewArithmeticExtensionGate(10), arithmeticExtensionGateExpectedConstraints}, |
|||
{gates.NewMultiplicationExtensionGate(13), mulExtensionGateExpectedConstraints}, |
|||
{gates.NewReducingExtensionGate(33), reducingExtensionGateExpectedConstraints}, |
|||
{gates.NewReducingGate(44), reducingGateExpectedConstraints}, |
|||
{gates.NewCosetInterpolationGate( |
|||
4, |
|||
6, |
|||
[]goldilocks.Element{ |
|||
goldilocks.NewElement(17293822565076172801), |
|||
goldilocks.NewElement(18374686475376656385), |
|||
goldilocks.NewElement(18446744069413535745), |
|||
goldilocks.NewElement(281474976645120), |
|||
goldilocks.NewElement(17592186044416), |
|||
goldilocks.NewElement(18446744069414584577), |
|||
goldilocks.NewElement(18446744000695107601), |
|||
goldilocks.NewElement(18446744065119617025), |
|||
goldilocks.NewElement(1152921504338411520), |
|||
goldilocks.NewElement(72057594037927936), |
|||
goldilocks.NewElement(18446744069415632897), |
|||
goldilocks.NewElement(18446462594437939201), |
|||
goldilocks.NewElement(18446726477228539905), |
|||
goldilocks.NewElement(18446744069414584065), |
|||
goldilocks.NewElement(68719476720), |
|||
goldilocks.NewElement(4294967296), |
|||
}, |
|||
), cosetInterpolationGateExpectedConstraints}, |
|||
{&gates.PoseidonMdsGate{}, poseidonMdsGateExpectedConstraints}, |
|||
} |
|||
|
|||
for _, test := range gateTests { |
|||
testCase( |
|||
test.testGate, |
|||
test.expectedConstraints, |
|||
) |
|||
} |
|||
} |
|||
@ -1,160 +0,0 @@ |
|||
package plonk |
|||
|
|||
import ( |
|||
"fmt" |
|||
|
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/field" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/fri" |
|||
) |
|||
|
|||
type ChallengerChip struct { |
|||
api frontend.API `gnark:"-"` |
|||
field field.FieldAPI `gnark:"-"` |
|||
poseidonChip *poseidon.PoseidonChip |
|||
poseidonBN128Chip *poseidon.PoseidonBN128Chip |
|||
spongeState [poseidon.SPONGE_WIDTH]frontend.Variable |
|||
inputBuffer []field.F |
|||
outputBuffer []field.F |
|||
} |
|||
|
|||
func NewChallengerChip(api frontend.API, fieldAPI field.FieldAPI, poseidonChip *poseidon.PoseidonChip, poseidonBN128Chip *poseidon.PoseidonBN128Chip) *ChallengerChip { |
|||
var spongeState [poseidon.SPONGE_WIDTH]frontend.Variable |
|||
var inputBuffer []field.F |
|||
var outputBuffer []field.F |
|||
|
|||
for i := 0; i < poseidon.SPONGE_WIDTH; i++ { |
|||
spongeState[i] = frontend.Variable(0) |
|||
} |
|||
|
|||
return &ChallengerChip{ |
|||
api: api, |
|||
field: fieldAPI, |
|||
poseidonChip: poseidonChip, |
|||
poseidonBN128Chip: poseidonBN128Chip, |
|||
spongeState: spongeState, |
|||
inputBuffer: inputBuffer, |
|||
outputBuffer: outputBuffer, |
|||
} |
|||
} |
|||
|
|||
func (c *ChallengerChip) ObserveElement(element field.F) { |
|||
c.outputBuffer = clearBuffer(c.outputBuffer) |
|||
c.inputBuffer = append(c.inputBuffer, element) |
|||
if len(c.inputBuffer) == poseidon.SPONGE_RATE { |
|||
c.duplexing() |
|||
} |
|||
} |
|||
|
|||
func (c *ChallengerChip) ObserveElements(elements []field.F) { |
|||
for i := 0; i < len(elements); i++ { |
|||
c.ObserveElement(elements[i]) |
|||
} |
|||
} |
|||
|
|||
func (c *ChallengerChip) ObserveHash(hash poseidon.PoseidonHashOut) { |
|||
elements := c.poseidonChip.ToVec(hash) |
|||
c.ObserveElements(elements) |
|||
} |
|||
|
|||
func (c *ChallengerChip) ObserveBN128Hash(hash poseidon.PoseidonBN128HashOut) { |
|||
elements := c.poseidonBN128Chip.ToVec(hash) |
|||
c.ObserveElements(elements) |
|||
} |
|||
|
|||
func (c *ChallengerChip) ObserveCap(cap []poseidon.PoseidonBN128HashOut) { |
|||
for i := 0; i < len(cap); i++ { |
|||
c.ObserveBN128Hash(cap[i]) |
|||
} |
|||
} |
|||
|
|||
func (c *ChallengerChip) ObserveExtensionElement(element field.QuadraticExtension) { |
|||
c.ObserveElements(element[:]) |
|||
} |
|||
|
|||
func (c *ChallengerChip) ObserveExtensionElements(elements []field.QuadraticExtension) { |
|||
for i := 0; i < len(elements); i++ { |
|||
c.ObserveExtensionElement(elements[i]) |
|||
} |
|||
} |
|||
|
|||
func (c *ChallengerChip) ObserveOpenings(openings fri.FriOpenings) { |
|||
for i := 0; i < len(openings.Batches); i++ { |
|||
c.ObserveExtensionElements(openings.Batches[i].Values) |
|||
} |
|||
} |
|||
|
|||
func (c *ChallengerChip) GetChallenge() field.F { |
|||
if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 { |
|||
c.duplexing() |
|||
} |
|||
|
|||
challenge := c.outputBuffer[len(c.outputBuffer)-1] |
|||
c.outputBuffer = c.outputBuffer[:len(c.outputBuffer)-1] |
|||
|
|||
return challenge |
|||
} |
|||
|
|||
func (c *ChallengerChip) GetNChallenges(n uint64) []field.F { |
|||
challenges := make([]field.F, n) |
|||
for i := uint64(0); i < n; i++ { |
|||
challenges[i] = c.GetChallenge() |
|||
} |
|||
return challenges |
|||
} |
|||
|
|||
func (c *ChallengerChip) GetExtensionChallenge() field.QuadraticExtension { |
|||
values := c.GetNChallenges(2) |
|||
return field.QuadraticExtension{values[0], values[1]} |
|||
} |
|||
|
|||
func (c *ChallengerChip) GetHash() poseidon.PoseidonHashOut { |
|||
return [4]field.F{c.GetChallenge(), c.GetChallenge(), c.GetChallenge(), c.GetChallenge()} |
|||
} |
|||
|
|||
func (c *ChallengerChip) GetFriChallenges(commitPhaseMerkleCaps []common.MerkleCap, finalPoly common.PolynomialCoeffs, powWitness field.F, degreeBits uint64, config common.FriConfig) common.FriChallenges { |
|||
numFriQueries := config.NumQueryRounds |
|||
friAlpha := c.GetExtensionChallenge() |
|||
|
|||
var friBetas []field.QuadraticExtension |
|||
for i := 0; i < len(commitPhaseMerkleCaps); i++ { |
|||
c.ObserveCap(commitPhaseMerkleCaps[i]) |
|||
friBetas = append(friBetas, c.GetExtensionChallenge()) |
|||
} |
|||
|
|||
c.ObserveExtensionElements(finalPoly.Coeffs) |
|||
c.ObserveElement(powWitness) |
|||
|
|||
friPowResponse := c.GetChallenge() |
|||
friQueryIndices := c.GetNChallenges(numFriQueries) |
|||
|
|||
return common.FriChallenges{ |
|||
FriAlpha: friAlpha, |
|||
FriBetas: friBetas, |
|||
FriPowResponse: friPowResponse, |
|||
FriQueryIndices: friQueryIndices, |
|||
} |
|||
} |
|||
|
|||
func clearBuffer(buffer []field.F) []field.F { |
|||
return make([]field.F, 0) |
|||
} |
|||
|
|||
func (c *ChallengerChip) duplexing() { |
|||
if len(c.inputBuffer) > poseidon.SPONGE_RATE { |
|||
fmt.Println(len(c.inputBuffer)) |
|||
panic("something went wrong") |
|||
} |
|||
|
|||
for i := 0; i < len(c.inputBuffer); i++ { |
|||
c.spongeState[i] = c.field.Reduce(c.inputBuffer[i]).Limbs[0] |
|||
} |
|||
c.inputBuffer = clearBuffer(c.inputBuffer) |
|||
c.spongeState = c.poseidonChip.Poseidon(c.spongeState) |
|||
clearBuffer(c.outputBuffer) |
|||
for i := 0; i < poseidon.SPONGE_RATE; i++ { |
|||
c.outputBuffer = append(c.outputBuffer, c.field.NewElement(c.spongeState[i])) |
|||
} |
|||
} |
|||
@ -1,227 +0,0 @@ |
|||
package plonk |
|||
|
|||
import ( |
|||
"math/big" |
|||
"testing" |
|||
|
|||
"github.com/consensys/gnark/backend/groth16" |
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/consensys/gnark/frontend/cs/r1cs" |
|||
"github.com/consensys/gnark/test" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/field" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/fri" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils" |
|||
) |
|||
|
|||
type TestChallengerCircuit struct { |
|||
commonCircuitDataFilename string `gnark:"-"` |
|||
|
|||
CircuitDigest frontend.Variable `gnark:",public"` |
|||
PublicInputs []field.F `gnark:",public"` |
|||
WiresCap []frontend.Variable |
|||
PlonkZsPartialProductsCap []frontend.Variable |
|||
QuotientPolysCap []frontend.Variable |
|||
FriOpenings fri.FriOpenings |
|||
CommitPhaseMerkleCaps [][]frontend.Variable |
|||
FinalPoly common.PolynomialCoeffs |
|||
PowWitness field.F |
|||
} |
|||
|
|||
func (circuit *TestChallengerCircuit) Define(api frontend.API) error { |
|||
commonCircuitData := utils.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename) |
|||
|
|||
config := commonCircuitData.Config |
|||
numChallenges := config.NumChallenges |
|||
fieldAPI := field.NewFieldAPI(api) |
|||
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI) |
|||
poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI, qeAPI) |
|||
poseidonBN128Chip := poseidon.NewPoseidonBN128Chip(api, fieldAPI) |
|||
challenger := NewChallengerChip(api, fieldAPI, poseidonChip, poseidonBN128Chip) |
|||
|
|||
challenger.ObserveBN128Hash(circuit.CircuitDigest) |
|||
challenger.ObserveHash(poseidonChip.HashNoPad(circuit.PublicInputs)) |
|||
challenger.ObserveCap(circuit.WiresCap) |
|||
plonkBetas := challenger.GetNChallenges(numChallenges) |
|||
plonkGammas := challenger.GetNChallenges(numChallenges) |
|||
|
|||
challenger.ObserveCap(circuit.PlonkZsPartialProductsCap) |
|||
plonkAlphas := challenger.GetNChallenges(numChallenges) |
|||
|
|||
challenger.ObserveCap(circuit.QuotientPolysCap) |
|||
plonkZeta := challenger.GetExtensionChallenge() |
|||
|
|||
challenger.ObserveOpenings(circuit.FriOpenings) |
|||
|
|||
friChallenges := challenger.GetFriChallenges( |
|||
circuit.CommitPhaseMerkleCaps, |
|||
circuit.FinalPoly, |
|||
circuit.PowWitness, |
|||
commonCircuitData.DegreeBits, |
|||
config.FriConfig, |
|||
) |
|||
|
|||
expectedPlonkBetas := [2]field.F{ |
|||
field.NewFieldConstFromString("17615363392879944733"), |
|||
field.NewFieldConstFromString("9422446877322953047"), |
|||
} |
|||
|
|||
expectedPlonkGammas := [2]field.F{ |
|||
field.NewFieldConstFromString("15174493176564484303"), |
|||
field.NewFieldConstFromString("6175150444166239851"), |
|||
} |
|||
|
|||
for i := 0; i < 2; i++ { |
|||
fieldAPI.AssertIsEqual(plonkBetas[i], expectedPlonkBetas[i]) |
|||
fieldAPI.AssertIsEqual(plonkGammas[i], expectedPlonkGammas[i]) |
|||
} |
|||
|
|||
expectedPlonkAlphas := [2]field.F{ |
|||
field.NewFieldConstFromString("9276470834414745550"), |
|||
field.NewFieldConstFromString("5302812342351431915"), |
|||
} |
|||
|
|||
for i := 0; i < 2; i++ { |
|||
fieldAPI.AssertIsEqual(plonkAlphas[i], expectedPlonkAlphas[i]) |
|||
} |
|||
|
|||
expectedPlonkZeta := field.QuadraticExtension{ |
|||
field.NewFieldConstFromString("3892795992421241388"), |
|||
field.NewFieldConstFromString("15786647757418200302"), |
|||
} |
|||
|
|||
for i := 0; i < 2; i++ { |
|||
fieldAPI.AssertIsEqual(plonkZeta[i], expectedPlonkZeta[i]) |
|||
} |
|||
|
|||
fieldAPI.AssertIsEqual(friChallenges.FriAlpha[0], field.NewFieldConst(885535811531859621)) |
|||
|
|||
fieldAPI.AssertIsEqual(friChallenges.FriBetas[0][0], field.NewFieldConst(5231781384587895507)) |
|||
|
|||
fieldAPI.AssertIsEqual(friChallenges.FriPowResponse, field.NewFieldConst(70715523064019)) |
|||
|
|||
fieldAPI.AssertIsEqual(friChallenges.FriQueryIndices[0], field.NewFieldConst(11890500485816111017)) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func StringToBN128Hash(hashStr string) poseidon.PoseidonBN128HashOut { |
|||
hashBigInt, ok := new(big.Int).SetString(hashStr, 10) |
|||
if !(ok) { |
|||
panic("Invalid hash: " + hashStr) |
|||
} |
|||
|
|||
hashVar := frontend.Variable(*hashBigInt) |
|||
return poseidon.PoseidonBN128HashOut(hashVar) |
|||
} |
|||
|
|||
func TestChallengerWitness(t *testing.T) { |
|||
assert := test.NewAssert(t) |
|||
|
|||
testCase := func() { |
|||
proofWithPis := utils.DeserializeProofWithPublicInputs("../../data/decode_block/proof_with_public_inputs.json") |
|||
verifierData := utils.DeserializeVerifierOnlyCircuitData("../../data/decode_block/verifier_only_circuit_data.json") |
|||
|
|||
circuit := TestChallengerCircuit{ |
|||
commonCircuitDataFilename: "../../data/decode_block/common_circuit_data.json", |
|||
|
|||
CircuitDigest: verifierData.CircuitDigest, |
|||
PublicInputs: proofWithPis.PublicInputs, |
|||
WiresCap: proofWithPis.Proof.WiresCap, |
|||
PlonkZsPartialProductsCap: proofWithPis.Proof.PlonkZsPartialProductsCap, |
|||
QuotientPolysCap: proofWithPis.Proof.QuotientPolysCap, |
|||
FriOpenings: fri.ToFriOpenings(proofWithPis.Proof.Openings), |
|||
CommitPhaseMerkleCaps: proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps, |
|||
FinalPoly: proofWithPis.Proof.OpeningProof.FinalPoly, |
|||
PowWitness: proofWithPis.Proof.OpeningProof.PowWitness, |
|||
} |
|||
witness := TestChallengerCircuit{ |
|||
CircuitDigest: verifierData.CircuitDigest, |
|||
PublicInputs: proofWithPis.PublicInputs, |
|||
WiresCap: proofWithPis.Proof.WiresCap, |
|||
PlonkZsPartialProductsCap: proofWithPis.Proof.PlonkZsPartialProductsCap, |
|||
QuotientPolysCap: proofWithPis.Proof.QuotientPolysCap, |
|||
FriOpenings: fri.ToFriOpenings(proofWithPis.Proof.Openings), |
|||
CommitPhaseMerkleCaps: proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps, |
|||
FinalPoly: proofWithPis.Proof.OpeningProof.FinalPoly, |
|||
PowWitness: proofWithPis.Proof.OpeningProof.PowWitness, |
|||
} |
|||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField()) |
|||
assert.NoError(err) |
|||
} |
|||
|
|||
testCase() |
|||
} |
|||
|
|||
func TestChallengerProver(t *testing.T) { |
|||
proofWithPis := utils.DeserializeProofWithPublicInputs("../../data/decode_block/proof_with_public_inputs.json") |
|||
verifierData := utils.DeserializeVerifierOnlyCircuitData("../../data/decode_block/verifier_only_circuit_data.json") |
|||
|
|||
circuit := TestChallengerCircuit{ |
|||
commonCircuitDataFilename: "../../data/decode_block/common_circuit_data.json", |
|||
|
|||
CircuitDigest: verifierData.CircuitDigest, |
|||
PublicInputs: proofWithPis.PublicInputs, |
|||
WiresCap: proofWithPis.Proof.WiresCap, |
|||
PlonkZsPartialProductsCap: proofWithPis.Proof.PlonkZsPartialProductsCap, |
|||
QuotientPolysCap: proofWithPis.Proof.QuotientPolysCap, |
|||
FriOpenings: fri.ToFriOpenings(proofWithPis.Proof.Openings), |
|||
CommitPhaseMerkleCaps: proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps, |
|||
FinalPoly: proofWithPis.Proof.OpeningProof.FinalPoly, |
|||
PowWitness: proofWithPis.Proof.OpeningProof.PowWitness, |
|||
} |
|||
|
|||
proofWithPis = utils.DeserializeProofWithPublicInputs("../../data/decode_block/proof_with_public_inputs.json") |
|||
verifierData = utils.DeserializeVerifierOnlyCircuitData("../../data/decode_block/verifier_only_circuit_data.json") |
|||
|
|||
assignment := TestChallengerCircuit{ |
|||
commonCircuitDataFilename: "../../data/decode_block/common_circuit_data.json", |
|||
|
|||
CircuitDigest: verifierData.CircuitDigest, |
|||
PublicInputs: proofWithPis.PublicInputs, |
|||
WiresCap: proofWithPis.Proof.WiresCap, |
|||
PlonkZsPartialProductsCap: proofWithPis.Proof.PlonkZsPartialProductsCap, |
|||
QuotientPolysCap: proofWithPis.Proof.QuotientPolysCap, |
|||
FriOpenings: fri.ToFriOpenings(proofWithPis.Proof.Openings), |
|||
CommitPhaseMerkleCaps: proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps, |
|||
FinalPoly: proofWithPis.Proof.OpeningProof.FinalPoly, |
|||
PowWitness: proofWithPis.Proof.OpeningProof.PowWitness, |
|||
} |
|||
|
|||
r1cs, err := frontend.Compile(field.TEST_CURVE.ScalarField(), r1cs.NewBuilder, &circuit) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
println("num constraints is ", r1cs.GetNbConstraints()) |
|||
|
|||
assert := test.NewAssert(t) |
|||
err = test.IsSolved(&circuit, &assignment, field.TEST_CURVE.ScalarField()) |
|||
assert.NoError(err) |
|||
|
|||
witness, err := frontend.NewWitness(&assignment, field.TEST_CURVE.ScalarField()) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
pk, vk, err := groth16.Setup(r1cs) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
proof, err := groth16.Prove(r1cs, pk, witness) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
publicWitness, err := witness.Public() |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
err = groth16.Verify(proof, vk, publicWitness) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
package plonk |
|||
|
|||
import "github.com/succinctlabs/gnark-plonky2-verifier/field" |
|||
|
|||
type OpeningSet struct { |
|||
Constants []field.QuadraticExtension |
|||
PlonkSigmas []field.QuadraticExtension |
|||
Wires []field.QuadraticExtension |
|||
PlonkZs []field.QuadraticExtension |
|||
PlonkZsNext []field.QuadraticExtension |
|||
PartialProducts []field.QuadraticExtension |
|||
QuotientPolys []field.QuadraticExtension |
|||
} |
|||
@ -1,28 +0,0 @@ |
|||
package verifier |
|||
|
|||
import ( |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/field" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/plonk" |
|||
) |
|||
|
|||
type Proof struct { |
|||
WiresCap common.MerkleCap |
|||
PlonkZsPartialProductsCap common.MerkleCap |
|||
QuotientPolysCap common.MerkleCap |
|||
Openings plonk.OpeningSet |
|||
OpeningProof common.FriProof |
|||
} |
|||
|
|||
type ProofWithPublicInputs struct { |
|||
Proof Proof |
|||
PublicInputs []field.F |
|||
} |
|||
|
|||
type ProofChallenges struct { |
|||
PlonkBetas []field.F |
|||
PlonkGammas []field.F |
|||
PlonkAlphas []field.F |
|||
PlonkZeta field.QuadraticExtension |
|||
FriChallenges common.FriChallenges |
|||
} |
|||