* 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 ( |
import ( |
||||
"fmt" |
"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 |
|
||||
} |
|
||||