mirror of
https://github.com/arnaucube/gnark-plonky2-verifier.git
synced 2026-01-12 09:01:32 +01:00
26
field/field.go
Normal file
26
field/field.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package field
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/consensys/gnark-crypto/ecc"
|
||||||
|
"github.com/consensys/gnark/frontend"
|
||||||
|
"github.com/consensys/gnark/std/math/emulated"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EmulatedField = emulated.Goldilocks
|
||||||
|
type F = emulated.Element[EmulatedField]
|
||||||
|
type QuadraticExtension = [2]F
|
||||||
|
type Hash = [4]F
|
||||||
|
|
||||||
|
var TEST_CURVE = ecc.BN254
|
||||||
|
|
||||||
|
func NewFieldElement(x uint64) F {
|
||||||
|
return emulated.NewElement[EmulatedField](x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFieldAPI(api frontend.API) frontend.API {
|
||||||
|
field, err := emulated.NewField[EmulatedField](api)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return field
|
||||||
|
}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package goldilocks
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/consensys/gnark/frontend"
|
|
||||||
"github.com/consensys/gnark/std/math/emulated"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GoldilocksElement = emulated.Element[emulated.Goldilocks]
|
|
||||||
|
|
||||||
func NewGoldilocksElement(x uint64) GoldilocksElement {
|
|
||||||
return GoldilocksElement(emulated.NewElement[emulated.Goldilocks](x))
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGoldilocksAPI(api frontend.API) frontend.API {
|
|
||||||
goldilocks, err := emulated.NewField[emulated.Goldilocks](api)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return goldilocks
|
|
||||||
}
|
|
||||||
@@ -2,9 +2,8 @@ package plonky2_verifier
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
. "gnark-ed25519/goldilocks"
|
. "gnark-ed25519/field"
|
||||||
"gnark-ed25519/poseidon"
|
"gnark-ed25519/poseidon"
|
||||||
. "gnark-ed25519/poseidon"
|
|
||||||
|
|
||||||
"github.com/consensys/gnark/frontend"
|
"github.com/consensys/gnark/frontend"
|
||||||
)
|
)
|
||||||
@@ -12,16 +11,16 @@ import (
|
|||||||
type ChallengerChip struct {
|
type ChallengerChip struct {
|
||||||
api frontend.API
|
api frontend.API
|
||||||
field frontend.API
|
field frontend.API
|
||||||
poseidonChip PoseidonChip
|
poseidonChip poseidon.PoseidonChip
|
||||||
spongeState [SPONGE_WIDTH]GoldilocksElement
|
spongeState [poseidon.SPONGE_WIDTH]F
|
||||||
inputBuffer []GoldilocksElement
|
inputBuffer []F
|
||||||
outputBuffer []GoldilocksElement
|
outputBuffer []F
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewChallengerChip(api frontend.API, field frontend.API, poseidonChip PoseidonChip) *ChallengerChip {
|
func NewChallengerChip(api frontend.API, field frontend.API, poseidonChip poseidon.PoseidonChip) *ChallengerChip {
|
||||||
var spongeState [SPONGE_WIDTH]GoldilocksElement
|
var spongeState [poseidon.SPONGE_WIDTH]F
|
||||||
var inputBuffer []GoldilocksElement
|
var inputBuffer []F
|
||||||
var outputBuffer []GoldilocksElement
|
var outputBuffer []F
|
||||||
return &ChallengerChip{
|
return &ChallengerChip{
|
||||||
api: api,
|
api: api,
|
||||||
field: field,
|
field: field,
|
||||||
@@ -32,31 +31,47 @@ func NewChallengerChip(api frontend.API, field frontend.API, poseidonChip Poseid
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ChallengerChip) ObserveElement(element GoldilocksElement) {
|
func (c *ChallengerChip) ObserveElement(element F) {
|
||||||
c.outputBuffer = clearBuffer(c.outputBuffer)
|
c.outputBuffer = clearBuffer(c.outputBuffer)
|
||||||
c.inputBuffer = append(c.inputBuffer, element)
|
c.inputBuffer = append(c.inputBuffer, element)
|
||||||
if len(c.inputBuffer) == SPONGE_RATE {
|
if len(c.inputBuffer) == poseidon.SPONGE_RATE {
|
||||||
c.duplexing()
|
c.duplexing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ChallengerChip) ObserveElements(elements []GoldilocksElement) {
|
func (c *ChallengerChip) ObserveElements(elements []F) {
|
||||||
for i := 0; i < len(elements); i++ {
|
for i := 0; i < len(elements); i++ {
|
||||||
c.ObserveElement(elements[i])
|
c.ObserveElement(elements[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ChallengerChip) ObserveHash(hash HashOutput) {
|
func (c *ChallengerChip) ObserveHash(hash Hash) {
|
||||||
c.ObserveElements(hash[:])
|
c.ObserveElements(hash[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ChallengerChip) ObserveCap(cap []HashOutput) {
|
func (c *ChallengerChip) ObserveCap(cap []Hash) {
|
||||||
for i := 0; i < len(cap); i++ {
|
for i := 0; i < len(cap); i++ {
|
||||||
c.ObserveHash(cap[i])
|
c.ObserveHash(cap[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ChallengerChip) GetChallenge() GoldilocksElement {
|
func (c *ChallengerChip) ObserveExtensionElement(element QuadraticExtension) {
|
||||||
|
c.ObserveElements(element[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ChallengerChip) ObserveExtensionElements(elements []QuadraticExtension) {
|
||||||
|
for i := 0; i < len(elements); i++ {
|
||||||
|
c.ObserveExtensionElement(elements[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ChallengerChip) ObserveOpenings(openings FriOpenings) {
|
||||||
|
for i := 0; i < len(openings.Batches); i++ {
|
||||||
|
c.ObserveExtensionElements(openings.Batches[i].values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ChallengerChip) GetChallenge() F {
|
||||||
if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 {
|
if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 {
|
||||||
c.duplexing()
|
c.duplexing()
|
||||||
}
|
}
|
||||||
@@ -67,20 +82,63 @@ func (c *ChallengerChip) GetChallenge() GoldilocksElement {
|
|||||||
return challenge
|
return challenge
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ChallengerChip) GetNChallenges(n int) []GoldilocksElement {
|
func (c *ChallengerChip) GetNChallenges(n uint64) []F {
|
||||||
challenges := make([]GoldilocksElement, n)
|
challenges := make([]F, n)
|
||||||
for i := 0; i < n; i++ {
|
for i := uint64(0); i < n; i++ {
|
||||||
challenges[i] = c.GetChallenge()
|
challenges[i] = c.GetChallenge()
|
||||||
}
|
}
|
||||||
return challenges
|
return challenges
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearBuffer(buffer []GoldilocksElement) []GoldilocksElement {
|
func (c *ChallengerChip) GetExtensionChallenge() QuadraticExtension {
|
||||||
return make([]GoldilocksElement, 0)
|
values := c.GetNChallenges(2)
|
||||||
|
return QuadraticExtension{values[0], values[1]}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ChallengerChip) GetHash() Hash {
|
||||||
|
return [4]F{c.GetChallenge(), c.GetChallenge(), c.GetChallenge(), c.GetChallenge()}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ChallengerChip) GetFriChallenges(commitPhaseMerkleCaps []MerkleCap, finalPoly PolynomialCoeffs, powWitness F, degreeBits uint64, config struct {
|
||||||
|
RateBits uint64 "json:\"rate_bits\""
|
||||||
|
CapHeight uint64 "json:\"cap_height\""
|
||||||
|
ProofOfWorkBits uint64 "json:\"proof_of_work_bits\""
|
||||||
|
ReductionStrategy struct {
|
||||||
|
ConstantArityBits []int "json:\"ConstantArityBits\""
|
||||||
|
} "json:\"reduction_strategy\""
|
||||||
|
NumQueryRounds uint64 "json:\"num_query_rounds\""
|
||||||
|
}) FriChallenges {
|
||||||
|
numFriQueries := config.NumQueryRounds
|
||||||
|
friAlpha := c.GetExtensionChallenge()
|
||||||
|
|
||||||
|
var friBetas []QuadraticExtension
|
||||||
|
for i := 0; i < len(commitPhaseMerkleCaps); i++ {
|
||||||
|
c.ObserveCap(commitPhaseMerkleCaps[i])
|
||||||
|
friBetas = append(friBetas, c.GetExtensionChallenge())
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ObserveExtensionElements(finalPoly.Coeffs)
|
||||||
|
|
||||||
|
hash := c.GetHash()
|
||||||
|
powInputs := append(hash[:], powWitness)
|
||||||
|
|
||||||
|
friPowResponse := c.poseidonChip.HashNoPad(powInputs)[0]
|
||||||
|
friQueryIndices := c.GetNChallenges(numFriQueries)
|
||||||
|
|
||||||
|
return FriChallenges{
|
||||||
|
FriAlpha: friAlpha,
|
||||||
|
FriBetas: friBetas,
|
||||||
|
FriPowResponse: friPowResponse,
|
||||||
|
FriQueryIndicies: friQueryIndices,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func clearBuffer(buffer []F) []F {
|
||||||
|
return make([]F, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ChallengerChip) duplexing() {
|
func (c *ChallengerChip) duplexing() {
|
||||||
if len(c.inputBuffer) > SPONGE_RATE {
|
if len(c.inputBuffer) > poseidon.SPONGE_RATE {
|
||||||
fmt.Println(len(c.inputBuffer))
|
fmt.Println(len(c.inputBuffer))
|
||||||
panic("something went wrong")
|
panic("something went wrong")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
package plonky2_verifier
|
package plonky2_verifier
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "gnark-ed25519/goldilocks"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"gnark-ed25519/field"
|
||||||
|
. "gnark-ed25519/field"
|
||||||
. "gnark-ed25519/poseidon"
|
. "gnark-ed25519/poseidon"
|
||||||
"gnark-ed25519/utils"
|
"gnark-ed25519/utils"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/consensys/gnark-crypto/ecc"
|
|
||||||
"github.com/consensys/gnark/frontend"
|
"github.com/consensys/gnark/frontend"
|
||||||
"github.com/consensys/gnark/test"
|
"github.com/consensys/gnark/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testCurve = ecc.BN254
|
|
||||||
|
|
||||||
type TestChallengerCircuit struct {
|
type TestChallengerCircuit struct {
|
||||||
PublicInputs [3]frontend.Variable
|
PublicInputs [3]frontend.Variable
|
||||||
CircuitDigest [4]frontend.Variable
|
CircuitDigest [4]frontend.Variable
|
||||||
@@ -20,65 +22,76 @@ type TestChallengerCircuit struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (circuit *TestChallengerCircuit) Define(api frontend.API) error {
|
func (circuit *TestChallengerCircuit) Define(api frontend.API) error {
|
||||||
goldilocksApi := NewGoldilocksAPI(api)
|
field := field.NewFieldAPI(api)
|
||||||
poseidonChip := NewPoseidonChip(api, goldilocksApi)
|
poseidonChip := NewPoseidonChip(api, field)
|
||||||
challengerChip := NewChallengerChip(api, goldilocksApi, *poseidonChip)
|
challengerChip := NewChallengerChip(api, field, *poseidonChip)
|
||||||
|
|
||||||
var circuitDigestGoldilocks [4]GoldilocksElement
|
var circuitDigest [4]F
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < len(circuitDigest); i++ {
|
||||||
circuitDigestGoldilocks[i] = goldilocksApi.FromBinary(api.ToBinary(circuit.CircuitDigest[i], 64)).(GoldilocksElement)
|
circuitDigest[i] = field.FromBinary(api.ToBinary(circuit.CircuitDigest[i], 64)).(F)
|
||||||
}
|
}
|
||||||
|
|
||||||
var publicInputsGoldilocks [3]GoldilocksElement
|
var publicInputs [3]F
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < len(publicInputs); i++ {
|
||||||
publicInputsGoldilocks[i] = goldilocksApi.FromBinary(api.ToBinary(circuit.PublicInputs[i], 64)).(GoldilocksElement)
|
publicInputs[i] = field.FromBinary(api.ToBinary(circuit.PublicInputs[i], 64)).(F)
|
||||||
}
|
}
|
||||||
|
|
||||||
var wiresCapGoldilocks [16][4]GoldilocksElement
|
var wiresCap [16][4]F
|
||||||
for i := 0; i < 16; i++ {
|
for i := 0; i < len(wiresCap); i++ {
|
||||||
for j := 0; j < 4; j++ {
|
for j := 0; j < len(wiresCap[0]); j++ {
|
||||||
wiresCapGoldilocks[i][j] = goldilocksApi.FromBinary(api.ToBinary(circuit.WiresCap[i][j], 64)).(GoldilocksElement)
|
wiresCap[i][j] = field.FromBinary(api.ToBinary(circuit.WiresCap[i][j], 64)).(F)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
publicInputHash := poseidonChip.HashNoPad(publicInputsGoldilocks[:])
|
publicInputHash := poseidonChip.HashNoPad(publicInputs[:])
|
||||||
challengerChip.ObserveHash(circuitDigestGoldilocks)
|
challengerChip.ObserveHash(circuitDigest)
|
||||||
challengerChip.ObserveHash(publicInputHash)
|
challengerChip.ObserveHash(publicInputHash)
|
||||||
challengerChip.ObserveCap(wiresCapGoldilocks[:])
|
challengerChip.ObserveCap(wiresCap[:])
|
||||||
|
|
||||||
nbChallenges := 2
|
numChallenges := uint64(2)
|
||||||
plonkBetas := challengerChip.GetNChallenges(nbChallenges)
|
plonkBetas := challengerChip.GetNChallenges(numChallenges)
|
||||||
plonkGammas := challengerChip.GetNChallenges(nbChallenges)
|
plonkGammas := challengerChip.GetNChallenges(numChallenges)
|
||||||
|
|
||||||
var expectedPlonkBetas [2]frontend.Variable
|
expectedPlonkBetas := [2]frontend.Variable{
|
||||||
expectedPlonkBetas[0] = frontend.Variable("4678728155650926271")
|
frontend.Variable("4678728155650926271"),
|
||||||
expectedPlonkBetas[1] = frontend.Variable("13611962404289024887")
|
frontend.Variable("13611962404289024887"),
|
||||||
|
}
|
||||||
var expectedPlonkGammas [2]frontend.Variable
|
expectedPlonkGammas := [2]frontend.Variable{
|
||||||
expectedPlonkGammas[0] = frontend.Variable("13237663823305715949")
|
frontend.Variable("13237663823305715949"),
|
||||||
expectedPlonkGammas[1] = frontend.Variable("15389314098328235145")
|
frontend.Variable("15389314098328235145"),
|
||||||
|
}
|
||||||
|
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
goldilocksApi.AssertIsEqual(
|
field.AssertIsEqual(plonkBetas[i], field.FromBinary(api.ToBinary(expectedPlonkBetas[i])).(F))
|
||||||
plonkBetas[i],
|
field.AssertIsEqual(plonkGammas[i], field.FromBinary(api.ToBinary(expectedPlonkGammas[i])).(F))
|
||||||
goldilocksApi.FromBinary(api.ToBinary(expectedPlonkBetas[i])).(GoldilocksElement),
|
|
||||||
)
|
|
||||||
goldilocksApi.AssertIsEqual(
|
|
||||||
plonkGammas[i],
|
|
||||||
goldilocksApi.FromBinary(api.ToBinary(expectedPlonkGammas[i])).(GoldilocksElement),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDeserializationOfPlonky2Proof(t *testing.T) {
|
||||||
|
fibonacciProofPath := "./fibonacci_proof.json"
|
||||||
|
jsonFile, err := os.Open(fibonacciProofPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
defer jsonFile.Close()
|
||||||
|
|
||||||
|
byteValue, _ := ioutil.ReadAll(jsonFile)
|
||||||
|
|
||||||
|
var result Proof
|
||||||
|
json.Unmarshal(byteValue, &result)
|
||||||
|
|
||||||
|
fmt.Println(result.WiresCap)
|
||||||
|
}
|
||||||
|
|
||||||
func TestChallengerWitness(t *testing.T) {
|
func TestChallengerWitness(t *testing.T) {
|
||||||
assert := test.NewAssert(t)
|
assert := test.NewAssert(t)
|
||||||
|
|
||||||
testCase := func(publicInputs [3]frontend.Variable, circuitDigest [4]frontend.Variable, wiresCap [16][4]frontend.Variable) {
|
testCase := func(publicInputs [3]frontend.Variable, circuitDigest [4]frontend.Variable, wiresCap [16][4]frontend.Variable) {
|
||||||
circuit := TestChallengerCircuit{PublicInputs: publicInputs, CircuitDigest: circuitDigest, WiresCap: wiresCap}
|
circuit := TestChallengerCircuit{PublicInputs: publicInputs, CircuitDigest: circuitDigest, WiresCap: wiresCap}
|
||||||
witness := TestChallengerCircuit{PublicInputs: publicInputs, CircuitDigest: circuitDigest, WiresCap: wiresCap}
|
witness := TestChallengerCircuit{PublicInputs: publicInputs, CircuitDigest: circuitDigest, WiresCap: wiresCap}
|
||||||
err := test.IsSolved(&circuit, &witness, testCurve.ScalarField())
|
err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField())
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
75
plonky2_verifier/data/common_circuit_data.json
Normal file
75
plonky2_verifier/data/common_circuit_data.json
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"num_wires": 135,
|
||||||
|
"num_routed_wires": 80,
|
||||||
|
"num_constants": 2,
|
||||||
|
"use_base_arithmetic_gate": true,
|
||||||
|
"security_bits": 100,
|
||||||
|
"num_challenges": 2,
|
||||||
|
"zero_knowledge": false,
|
||||||
|
"max_quotient_degree_factor": 8,
|
||||||
|
"fri_config": {
|
||||||
|
"rate_bits": 3,
|
||||||
|
"cap_height": 4,
|
||||||
|
"proof_of_work_bits": 16,
|
||||||
|
"reduction_strategy": { "ConstantArityBits": [4, 5] },
|
||||||
|
"num_query_rounds": 28
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fri_params": {
|
||||||
|
"config": {
|
||||||
|
"rate_bits": 3,
|
||||||
|
"cap_height": 4,
|
||||||
|
"proof_of_work_bits": 16,
|
||||||
|
"reduction_strategy": { "ConstantArityBits": [4, 5] },
|
||||||
|
"num_query_rounds": 28
|
||||||
|
},
|
||||||
|
"hiding": false,
|
||||||
|
"degree_bits": 3,
|
||||||
|
"reduction_arity_bits": []
|
||||||
|
},
|
||||||
|
"degree_bits": 3,
|
||||||
|
"selectors_info": {
|
||||||
|
"selector_indices": [0, 0, 0, 1],
|
||||||
|
"groups": [
|
||||||
|
{ "start": 0, "end": 3 },
|
||||||
|
{ "start": 3, "end": 4 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"quotient_degree_factor": 8,
|
||||||
|
"num_gate_constraints": 123,
|
||||||
|
"num_constants": 4,
|
||||||
|
"num_public_inputs": 3,
|
||||||
|
"k_is": [
|
||||||
|
1, 7, 49, 343, 2401, 16807, 117649, 823543, 5764801, 40353607, 282475249,
|
||||||
|
1977326743, 13841287201, 96889010407, 678223072849, 4747561509943,
|
||||||
|
33232930569601, 232630513987207, 1628413597910449, 11398895185373143,
|
||||||
|
79792266297612001, 558545864083284007, 3909821048582988049,
|
||||||
|
8922003270666332022, 7113790686420571191, 12903046666114829695,
|
||||||
|
16534350385145470581, 5059988279530788141, 16973173887300932666,
|
||||||
|
8131752794619022736, 1582037354089406189, 11074261478625843323,
|
||||||
|
3732854072722565977, 7683234439643377518, 16889152938674473984,
|
||||||
|
7543606154233811962, 15911754940807515092, 701820169165099718,
|
||||||
|
4912741184155698026, 15942444219675301861, 916645121239607101,
|
||||||
|
6416515848677249707, 8022122801911579307, 814627405137302186,
|
||||||
|
5702391835961115302, 3023254712898638472, 2716038920875884983,
|
||||||
|
565528376716610560, 3958698637016273920, 9264146389699333119,
|
||||||
|
9508792519651578870, 11221315429317299127, 4762231727562756605,
|
||||||
|
14888878023524711914, 11988425817600061793, 10132004445542095267,
|
||||||
|
15583798910550913906, 16852872026783475737, 7289639770996824233,
|
||||||
|
14133990258148600989, 6704211459967285318, 10035992080941828584,
|
||||||
|
14911712358349047125, 12148266161370408270, 11250886851934520606,
|
||||||
|
4969231685883306958, 16337877731768564385, 3684679705892444769,
|
||||||
|
7346013871832529062, 14528608963998534792, 9466542400916821939,
|
||||||
|
10925564598174000610, 2691975909559666986, 397087297503084581,
|
||||||
|
2779611082521592067, 1010533508236560148, 7073734557655921036,
|
||||||
|
12622653764762278610, 14571600075677612986, 9767480182670369297
|
||||||
|
],
|
||||||
|
"num_partial_products": 9,
|
||||||
|
"circuit_digest": {
|
||||||
|
"elements": [
|
||||||
|
7754113318730736048, 18436136620016916513, 18054530212389526288,
|
||||||
|
5893739326632906028
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
6286
plonky2_verifier/data/proof_with_public_inputs.json
Normal file
6286
plonky2_verifier/data/proof_with_public_inputs.json
Normal file
File diff suppressed because it is too large
Load Diff
100
plonky2_verifier/data/verifier_only_circuit_data.json
Normal file
100
plonky2_verifier/data/verifier_only_circuit_data.json
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
{
|
||||||
|
"constants_sigmas_cap": [
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
2913805118787558759, 15605217703384212484, 9293436862297178555,
|
||||||
|
10529947991695419448
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
1937331278189251620, 17537260089483183877, 10458485670158100707,
|
||||||
|
4116443229550247591
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
8142760542024755709, 3845244796524514577, 16191049345326767258,
|
||||||
|
7348433903875207214
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
18274477257392359471, 9341197367296335592, 14314312946600883535,
|
||||||
|
17431979896521737468
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
12713790163422286570, 9838614764658999419, 3024549327814176904,
|
||||||
|
6544549858431318793
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
17461063081201329467, 1929790214678747830, 14738190695567211833,
|
||||||
|
4502436664569676311
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
17446087997043032816, 17518692693064701003, 4915378766449394412,
|
||||||
|
10675325761198739044
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
11349186227918507635, 7105572536043210156, 13296927306801261929,
|
||||||
|
6138189381388819111
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
17427080957162886576, 4310228111529328877, 16109317445338921222,
|
||||||
|
11923676504992192083
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
11292141569337462929, 7213981967192374125, 4837353949249389782,
|
||||||
|
13157524938508720907
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
17221477633935993097, 7905315334616496868, 2950048088611741910,
|
||||||
|
16851660641249290423
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
1918571898367258879, 14473285549490778842, 16456257732802770188,
|
||||||
|
16611801325745795527
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
7880989808200689690, 16935107633380717766, 8956194191973051375,
|
||||||
|
1103945341495739535
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
4501339912027744074, 12142665268233044767, 9270990890291324944,
|
||||||
|
45374981263348191
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
13657768796246999470, 2899654677720502418, 7228867285602519410,
|
||||||
|
3363587770111123806
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
18227101298896629706, 12986849723013952028, 16815808278639394978,
|
||||||
|
16460725848109409638
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
232
plonky2_verifier/deserialize.go
Normal file
232
plonky2_verifier/deserialize.go
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
package plonky2_verifier
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
. "gnark-ed25519/field"
|
||||||
|
"gnark-ed25519/utils"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProofWithPublicInputsRaw struct {
|
||||||
|
Proof struct {
|
||||||
|
WiresCap []struct {
|
||||||
|
Elements []uint64 `json:"elements"`
|
||||||
|
} `json:"wires_cap"`
|
||||||
|
PlonkZsPartialProductsCap []struct {
|
||||||
|
Elements []uint64 `json:"elements"`
|
||||||
|
} `json:"plonk_zs_partial_products_cap"`
|
||||||
|
QuotientPolysCap []struct {
|
||||||
|
Elements []uint64 `json:"elements"`
|
||||||
|
} `json:"quotient_polys_cap"`
|
||||||
|
Openings struct {
|
||||||
|
Constants [][]uint64 `json:"constants"`
|
||||||
|
PlonkSigmas [][]uint64 `json:"plonk_sigmas"`
|
||||||
|
Wires [][]uint64 `json:"wires"`
|
||||||
|
PlonkZs [][]uint64 `json:"plonk_zs"`
|
||||||
|
PlonkZsNext [][]uint64 `json:"plonk_zs_next"`
|
||||||
|
PartialProducts [][]uint64 `json:"partial_products"`
|
||||||
|
QuotientPolys [][]uint64 `json:"quotient_polys"`
|
||||||
|
} `json:"openings"`
|
||||||
|
OpeningProof struct {
|
||||||
|
CommitPhaseMerkleCaps []interface{} `json:"commit_phase_merkle_caps"`
|
||||||
|
QueryRoundProofs []struct {
|
||||||
|
InitialTreesProof struct {
|
||||||
|
EvalsProofs [][]interface{} `json:"evals_proofs"`
|
||||||
|
} `json:"initial_trees_proof"`
|
||||||
|
Steps []interface{} `json:"steps"`
|
||||||
|
} `json:"query_round_proofs"`
|
||||||
|
FinalPoly struct {
|
||||||
|
Coeffs [][]uint64 `json:"coeffs"`
|
||||||
|
} `json:"final_poly"`
|
||||||
|
PowWitness uint64 `json:"pow_witness"`
|
||||||
|
} `json:"opening_proof"`
|
||||||
|
} `json:"proof"`
|
||||||
|
PublicInputs []interface{} `json:"public_inputs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommonCircuitDataRaw struct {
|
||||||
|
Config struct {
|
||||||
|
NumWires uint64 `json:"num_wires"`
|
||||||
|
NumRoutedWires uint64 `json:"num_routed_wires"`
|
||||||
|
NumConstants uint64 `json:"num_constants"`
|
||||||
|
UseBaseArithmeticGate bool `json:"use_base_arithmetic_gate"`
|
||||||
|
SecurityBits uint64 `json:"security_bits"`
|
||||||
|
NumChallenges uint64 `json:"num_challenges"`
|
||||||
|
ZeroKnowledge bool `json:"zero_knowledge"`
|
||||||
|
MaxQuotientDegreeFactor uint64 `json:"max_quotient_degree_factor"`
|
||||||
|
FriConfig struct {
|
||||||
|
RateBits uint64 `json:"rate_bits"`
|
||||||
|
CapHeight uint64 `json:"cap_height"`
|
||||||
|
ProofOfWorkBits uint64 `json:"proof_of_work_bits"`
|
||||||
|
ReductionStrategy struct {
|
||||||
|
ConstantArityBits []int `json:"ConstantArityBits"`
|
||||||
|
} `json:"reduction_strategy"`
|
||||||
|
NumQueryRounds uint64 `json:"num_query_rounds"`
|
||||||
|
} `json:"fri_config"`
|
||||||
|
} `json:"config"`
|
||||||
|
FriParams struct {
|
||||||
|
Config struct {
|
||||||
|
RateBits uint64 `json:"rate_bits"`
|
||||||
|
CapHeight uint64 `json:"cap_height"`
|
||||||
|
ProofOfWorkBits uint64 `json:"proof_of_work_bits"`
|
||||||
|
ReductionStrategy struct {
|
||||||
|
ConstantArityBits []uint64 `json:"ConstantArityBits"`
|
||||||
|
} `json:"reduction_strategy"`
|
||||||
|
NumQueryRounds uint64 `json:"num_query_rounds"`
|
||||||
|
} `json:"config"`
|
||||||
|
Hiding bool `json:"hiding"`
|
||||||
|
DegreeBits uint64 `json:"degree_bits"`
|
||||||
|
ReductionArityBits []interface{} `json:"reduction_arity_bits"`
|
||||||
|
} `json:"fri_params"`
|
||||||
|
DegreeBits uint64 `json:"degree_bits"`
|
||||||
|
SelectorsInfo struct {
|
||||||
|
SelectorIndices []uint64 `json:"selector_indices"`
|
||||||
|
Groups []struct {
|
||||||
|
Start uint64 `json:"start"`
|
||||||
|
End uint64 `json:"end"`
|
||||||
|
} `json:"groups"`
|
||||||
|
} `json:"selectors_info"`
|
||||||
|
QuotientDegreeFactor uint64 `json:"quotient_degree_factor"`
|
||||||
|
NumGateConstraints uint64 `json:"num_gate_constraints"`
|
||||||
|
NumConstants uint64 `json:"num_constants"`
|
||||||
|
NumPublicInputs uint64 `json:"num_public_inputs"`
|
||||||
|
KIs []uint64 `json:"k_is"`
|
||||||
|
NumPartialProducts uint64 `json:"num_partial_products"`
|
||||||
|
CircuitDigest struct {
|
||||||
|
Elements []uint64 `json:"elements"`
|
||||||
|
} `json:"circuit_digest"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VerifierOnlyCircuitDataRaw struct {
|
||||||
|
ConstantsSigmasCap []struct {
|
||||||
|
Elements []uint64 `json:"elements"`
|
||||||
|
} `json:"constants_sigmas_cap"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeserializeMerkleCap(merkleCapRaw []struct{ Elements []uint64 }) MerkleCap {
|
||||||
|
n := len(merkleCapRaw)
|
||||||
|
merkleCap := make([]Hash, n)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
copy(merkleCap[i][:], utils.Uint64ArrayToFArray(merkleCapRaw[i].Elements))
|
||||||
|
}
|
||||||
|
return merkleCap
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeserializeOpeningSet(openingSetRaw struct {
|
||||||
|
Constants [][]uint64
|
||||||
|
PlonkSigmas [][]uint64
|
||||||
|
Wires [][]uint64
|
||||||
|
PlonkZs [][]uint64
|
||||||
|
PlonkZsNext [][]uint64
|
||||||
|
PartialProducts [][]uint64
|
||||||
|
QuotientPolys [][]uint64
|
||||||
|
}) OpeningSet {
|
||||||
|
return OpeningSet{
|
||||||
|
Constants: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Constants),
|
||||||
|
PlonkSigmas: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkSigmas),
|
||||||
|
Wires: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Wires),
|
||||||
|
PlonkZs: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZs),
|
||||||
|
PlonkZsNext: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZsNext),
|
||||||
|
PartialProducts: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PartialProducts),
|
||||||
|
QuotientPolys: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.QuotientPolys),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeserializeFriProof(openingProofRaw struct {
|
||||||
|
CommitPhaseMerkleCaps []interface{}
|
||||||
|
QueryRoundProofs []struct {
|
||||||
|
InitialTreesProof struct {
|
||||||
|
EvalsProofs [][]interface{}
|
||||||
|
}
|
||||||
|
Steps []interface{}
|
||||||
|
}
|
||||||
|
FinalPoly struct {
|
||||||
|
Coeffs [][]uint64
|
||||||
|
}
|
||||||
|
PowWitness uint64
|
||||||
|
}) FriProof {
|
||||||
|
var openingProof FriProof
|
||||||
|
openingProof.PowWitness = NewFieldElement(openingProofRaw.PowWitness)
|
||||||
|
openingProof.FinalPoly.Coeffs = utils.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs)
|
||||||
|
return openingProof
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeserializeProofWithPublicInputs(path string) ProofWithPublicInputs {
|
||||||
|
jsonFile, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer jsonFile.Close()
|
||||||
|
rawBytes, _ := ioutil.ReadAll(jsonFile)
|
||||||
|
|
||||||
|
var raw ProofWithPublicInputsRaw
|
||||||
|
err = json.Unmarshal(rawBytes, &raw)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var proofWithPis ProofWithPublicInputs
|
||||||
|
proofWithPis.Proof.WiresCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.Proof.WiresCap))
|
||||||
|
proofWithPis.Proof.PlonkZsPartialProductsCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.Proof.PlonkZsPartialProductsCap))
|
||||||
|
proofWithPis.Proof.QuotientPolysCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.Proof.QuotientPolysCap))
|
||||||
|
proofWithPis.Proof.Openings = DeserializeOpeningSet(struct {
|
||||||
|
Constants [][]uint64
|
||||||
|
PlonkSigmas [][]uint64
|
||||||
|
Wires [][]uint64
|
||||||
|
PlonkZs [][]uint64
|
||||||
|
PlonkZsNext [][]uint64
|
||||||
|
PartialProducts [][]uint64
|
||||||
|
QuotientPolys [][]uint64
|
||||||
|
}(raw.Proof.Openings))
|
||||||
|
proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct {
|
||||||
|
CommitPhaseMerkleCaps []interface{}
|
||||||
|
QueryRoundProofs []struct {
|
||||||
|
InitialTreesProof struct{ EvalsProofs [][]interface{} }
|
||||||
|
Steps []interface{}
|
||||||
|
}
|
||||||
|
FinalPoly struct{ Coeffs [][]uint64 }
|
||||||
|
PowWitness uint64
|
||||||
|
}(raw.Proof.OpeningProof))
|
||||||
|
|
||||||
|
return proofWithPis
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeserializeCommonCircuitData(path string) CommonCircuitDataRaw {
|
||||||
|
jsonFile, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer jsonFile.Close()
|
||||||
|
rawBytes, _ := ioutil.ReadAll(jsonFile)
|
||||||
|
|
||||||
|
var raw CommonCircuitDataRaw
|
||||||
|
err = json.Unmarshal(rawBytes, &raw)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return raw
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeserializeVerifierOnlyCircuitData(path string) VerifierOnlyCircuitData {
|
||||||
|
jsonFile, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer jsonFile.Close()
|
||||||
|
rawBytes, _ := ioutil.ReadAll(jsonFile)
|
||||||
|
|
||||||
|
var raw VerifierOnlyCircuitDataRaw
|
||||||
|
err = json.Unmarshal(rawBytes, &raw)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return VerifierOnlyCircuitData{
|
||||||
|
ConstantSigmasCap: DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.ConstantsSigmasCap)),
|
||||||
|
}
|
||||||
|
}
|
||||||
24
plonky2_verifier/deserialize_test.go
Normal file
24
plonky2_verifier/deserialize_test.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package plonky2_verifier
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDeserializeProofWithPublicInputs(t *testing.T) {
|
||||||
|
proofWithPis := DeserializeProofWithPublicInputs("./data/proof_with_public_inputs.json")
|
||||||
|
fmt.Printf("%+v\n", proofWithPis)
|
||||||
|
panic("look at stdout")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeserializeCommonCircuitData(t *testing.T) {
|
||||||
|
proofWithPis := DeserializeCommonCircuitData("./data/common_circuit_data.json")
|
||||||
|
fmt.Printf("%+v\n", proofWithPis)
|
||||||
|
panic("look at stdout")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeserializeVerifierOnlyCircuitData(t *testing.T) {
|
||||||
|
proofWithPis := DeserializeVerifierOnlyCircuitData("./data/verifier_only_circuit_data.json")
|
||||||
|
fmt.Printf("%+v\n", proofWithPis)
|
||||||
|
panic("look at stdout")
|
||||||
|
}
|
||||||
25
plonky2_verifier/fri.go
Normal file
25
plonky2_verifier/fri.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package plonky2_verifier
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "gnark-ed25519/field"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FriOpeningBatch struct {
|
||||||
|
values []QuadraticExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
type FriOpenings struct {
|
||||||
|
Batches []FriOpeningBatch
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OpeningSet) ToFriOpenings() FriOpenings {
|
||||||
|
values := c.Constants
|
||||||
|
values = append(values, c.PlonkSigmas...)
|
||||||
|
values = append(values, c.Wires...)
|
||||||
|
values = append(values, c.PlonkZs...)
|
||||||
|
values = append(values, c.PartialProducts...)
|
||||||
|
values = append(values, c.QuotientPolys...)
|
||||||
|
zetaBatch := FriOpeningBatch{values: values}
|
||||||
|
zetaNextBatch := FriOpeningBatch{values: c.PlonkZsNext}
|
||||||
|
return FriOpenings{Batches: []FriOpeningBatch{zetaBatch, zetaNextBatch}}
|
||||||
|
}
|
||||||
123
plonky2_verifier/structs.go
Normal file
123
plonky2_verifier/structs.go
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
package plonky2_verifier
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "gnark-ed25519/field"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MerkleCap = []Hash
|
||||||
|
|
||||||
|
type MerkleProof struct {
|
||||||
|
Siblings []Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
type EvalProof struct {
|
||||||
|
Elements []F
|
||||||
|
MerkleProof MerkleProof
|
||||||
|
}
|
||||||
|
|
||||||
|
type FriInitialTreeProof struct {
|
||||||
|
EvalsProofs []EvalProof
|
||||||
|
}
|
||||||
|
|
||||||
|
type FriQueryStep struct {
|
||||||
|
Evals []QuadraticExtension
|
||||||
|
MerkleProof MerkleProof
|
||||||
|
}
|
||||||
|
|
||||||
|
type FriQueryRound struct {
|
||||||
|
InitialTreesProof FriInitialTreeProof
|
||||||
|
Steps []FriQueryStep
|
||||||
|
}
|
||||||
|
|
||||||
|
type PolynomialCoeffs struct {
|
||||||
|
Coeffs []QuadraticExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
type FriProof struct {
|
||||||
|
CommitPhaseMerkleCaps []MerkleCap
|
||||||
|
QueryRoundProofs FriQueryRound
|
||||||
|
FinalPoly PolynomialCoeffs
|
||||||
|
PowWitness F
|
||||||
|
}
|
||||||
|
|
||||||
|
type OpeningSet struct {
|
||||||
|
Constants []QuadraticExtension
|
||||||
|
PlonkSigmas []QuadraticExtension
|
||||||
|
Wires []QuadraticExtension
|
||||||
|
PlonkZs []QuadraticExtension
|
||||||
|
PlonkZsNext []QuadraticExtension
|
||||||
|
PartialProducts []QuadraticExtension
|
||||||
|
QuotientPolys []QuadraticExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
type Proof struct {
|
||||||
|
WiresCap MerkleCap
|
||||||
|
PlonkZsPartialProductsCap MerkleCap
|
||||||
|
QuotientPolysCap MerkleCap
|
||||||
|
Openings OpeningSet
|
||||||
|
OpeningProof FriProof
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProofWithPublicInputs struct {
|
||||||
|
Proof Proof
|
||||||
|
PublicInputs []F
|
||||||
|
}
|
||||||
|
|
||||||
|
type VerifierOnlyCircuitData struct {
|
||||||
|
ConstantSigmasCap MerkleCap
|
||||||
|
}
|
||||||
|
|
||||||
|
type FriConfig struct {
|
||||||
|
RateBits uint64
|
||||||
|
CapHeight uint64
|
||||||
|
ProofOfWorkBits uint64
|
||||||
|
NumQueryRounds uint64
|
||||||
|
// TODO: add FriReductionStrategy
|
||||||
|
}
|
||||||
|
|
||||||
|
type FriParams struct {
|
||||||
|
Config FriConfig
|
||||||
|
Hiding bool
|
||||||
|
DegreeBits uint64
|
||||||
|
ReductionArityBits []uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type CircuitConfig struct {
|
||||||
|
NumWires uint64
|
||||||
|
NumRoutedWires uint64
|
||||||
|
NumConstants uint64
|
||||||
|
UseBaseArithmeticGate bool
|
||||||
|
SecurityBits uint64
|
||||||
|
NumChallenges uint64
|
||||||
|
ZeroKnowledge bool
|
||||||
|
MaxQuotientDegreeFactor uint64
|
||||||
|
FriConfig FriConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommonCircuitData struct {
|
||||||
|
Config CircuitConfig
|
||||||
|
FriParams FriParams
|
||||||
|
DegreeBits uint64
|
||||||
|
QuotientDegreeFactor uint64
|
||||||
|
NumGateConstraints uint64
|
||||||
|
NumConstants uint64
|
||||||
|
NumPublicInputs uint64
|
||||||
|
KIs []F
|
||||||
|
NumPartialProducts uint64
|
||||||
|
CircuitDigest Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProofChallenges struct {
|
||||||
|
PlonkBetas []F
|
||||||
|
PlonkGammas []F
|
||||||
|
PlonkAlphas []F
|
||||||
|
PlonkZeta QuadraticExtension
|
||||||
|
FriChallenges FriChallenges
|
||||||
|
}
|
||||||
|
|
||||||
|
type FriChallenges struct {
|
||||||
|
FriAlpha QuadraticExtension
|
||||||
|
FriBetas []QuadraticExtension
|
||||||
|
FriPowResponse F
|
||||||
|
FriQueryIndicies []F
|
||||||
|
}
|
||||||
62
plonky2_verifier/verifier.go
Normal file
62
plonky2_verifier/verifier.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package plonky2_verifier
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
. "gnark-ed25519/field"
|
||||||
|
"gnark-ed25519/poseidon"
|
||||||
|
"gnark-ed25519/utils"
|
||||||
|
|
||||||
|
"github.com/consensys/gnark/frontend"
|
||||||
|
)
|
||||||
|
|
||||||
|
type VerifierChip struct {
|
||||||
|
api frontend.API
|
||||||
|
field frontend.API
|
||||||
|
poseidonChip poseidon.PoseidonChip
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *VerifierChip) GetPublicInputsHash(publicInputs []F) Hash {
|
||||||
|
return c.poseidonChip.HashNoPad(publicInputs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *VerifierChip) GetChallenges(proofWithPis ProofWithPublicInputs, publicInputsHash Hash, commonData CommonCircuitDataRaw) ProofChallenges {
|
||||||
|
config := commonData.Config
|
||||||
|
numChallenges := config.NumChallenges
|
||||||
|
challenger := NewChallengerChip(c.api, c.field, c.poseidonChip)
|
||||||
|
|
||||||
|
var circuitDigest Hash
|
||||||
|
copy(circuitDigest[:], utils.Uint64ArrayToFArray(commonData.CircuitDigest.Elements))
|
||||||
|
challenger.ObserveHash(circuitDigest)
|
||||||
|
challenger.ObserveHash(publicInputsHash)
|
||||||
|
challenger.ObserveCap(proofWithPis.Proof.WiresCap)
|
||||||
|
plonkBetas := challenger.GetNChallenges(numChallenges)
|
||||||
|
plonkGammas := challenger.GetNChallenges(numChallenges)
|
||||||
|
|
||||||
|
challenger.ObserveCap(proofWithPis.Proof.PlonkZsPartialProductsCap)
|
||||||
|
plonkAlphas := challenger.GetNChallenges(numChallenges)
|
||||||
|
|
||||||
|
challenger.ObserveCap(proofWithPis.Proof.QuotientPolysCap)
|
||||||
|
plonkZeta := challenger.GetExtensionChallenge()
|
||||||
|
|
||||||
|
challenger.ObserveOpenings(proofWithPis.Proof.Openings.ToFriOpenings())
|
||||||
|
|
||||||
|
return ProofChallenges{
|
||||||
|
PlonkBetas: plonkBetas,
|
||||||
|
PlonkGammas: plonkGammas,
|
||||||
|
PlonkAlphas: plonkAlphas,
|
||||||
|
PlonkZeta: plonkZeta,
|
||||||
|
FriChallenges: challenger.GetFriChallenges(
|
||||||
|
proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
|
||||||
|
proofWithPis.Proof.OpeningProof.FinalPoly,
|
||||||
|
proofWithPis.Proof.OpeningProof.PowWitness,
|
||||||
|
commonData.DegreeBits,
|
||||||
|
config.FriConfig,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *VerifierChip) Verify(proofWithPis ProofWithPublicInputs, verifierData VerifierOnlyCircuitData, commonData CommonCircuitDataRaw) {
|
||||||
|
publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs)
|
||||||
|
proofChallenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData)
|
||||||
|
fmt.Printf("%+v\n", proofChallenges)
|
||||||
|
}
|
||||||
37
plonky2_verifier/verifier_test.go
Normal file
37
plonky2_verifier/verifier_test.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package plonky2_verifier
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "gnark-ed25519/field"
|
||||||
|
. "gnark-ed25519/poseidon"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/consensys/gnark/frontend"
|
||||||
|
"github.com/consensys/gnark/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestVerifierCircuit struct{}
|
||||||
|
|
||||||
|
func (circuit *TestVerifierCircuit) Define(api frontend.API) error {
|
||||||
|
field := NewFieldAPI(api)
|
||||||
|
poseidonChip := NewPoseidonChip(api, field)
|
||||||
|
verifierChip := VerifierChip{api: api, field: field, poseidonChip: *poseidonChip}
|
||||||
|
proofWithPis := DeserializeProofWithPublicInputs("./data/proof_with_public_inputs.json")
|
||||||
|
commonCircuitData := DeserializeCommonCircuitData("./data/common_circuit_data.json")
|
||||||
|
verfierOnlyCircuitData := DeserializeVerifierOnlyCircuitData("./data/verifier_only_circuit_data.json")
|
||||||
|
verifierChip.Verify(proofWithPis, verfierOnlyCircuitData, commonCircuitData)
|
||||||
|
panic("look at stdout")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVerifierWitness(t *testing.T) {
|
||||||
|
assert := test.NewAssert(t)
|
||||||
|
|
||||||
|
testCase := func() {
|
||||||
|
circuit := TestVerifierCircuit{}
|
||||||
|
witness := TestVerifierCircuit{}
|
||||||
|
err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField())
|
||||||
|
assert.NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testCase()
|
||||||
|
}
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
package poseidon
|
package poseidon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "gnark-ed25519/goldilocks"
|
. "gnark-ed25519/field"
|
||||||
|
|
||||||
"github.com/consensys/gnark/frontend"
|
"github.com/consensys/gnark/frontend"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Note: This package assumes usage of the BN254 curve in various places. */
|
|
||||||
|
|
||||||
const HALF_N_FULL_ROUNDS = 4
|
const HALF_N_FULL_ROUNDS = 4
|
||||||
const N_FULL_ROUNDS_TOTAL = 2 * HALF_N_FULL_ROUNDS
|
const N_FULL_ROUNDS_TOTAL = 2 * HALF_N_FULL_ROUNDS
|
||||||
const N_PARTIAL_ROUNDS = 22
|
const N_PARTIAL_ROUNDS = 22
|
||||||
@@ -17,8 +15,7 @@ const WIDTH = 12
|
|||||||
const SPONGE_WIDTH = 12
|
const SPONGE_WIDTH = 12
|
||||||
const SPONGE_RATE = 8
|
const SPONGE_RATE = 8
|
||||||
|
|
||||||
type PoseidonState = [WIDTH]GoldilocksElement
|
type PoseidonState = [WIDTH]F
|
||||||
type HashOutput = [4]GoldilocksElement
|
|
||||||
type PoseidonChip struct {
|
type PoseidonChip struct {
|
||||||
api frontend.API
|
api frontend.API
|
||||||
field frontend.API
|
field frontend.API
|
||||||
@@ -37,7 +34,7 @@ func (c *PoseidonChip) Poseidon(input PoseidonState) PoseidonState {
|
|||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PoseidonChip) HashNToMNoPad(input []GoldilocksElement, nbOutputs int) []GoldilocksElement {
|
func (c *PoseidonChip) HashNToMNoPad(input []F, nbOutputs int) []F {
|
||||||
var state PoseidonState
|
var state PoseidonState
|
||||||
|
|
||||||
for i := 0; i < len(input); i += SPONGE_RATE {
|
for i := 0; i < len(input); i += SPONGE_RATE {
|
||||||
@@ -49,7 +46,7 @@ func (c *PoseidonChip) HashNToMNoPad(input []GoldilocksElement, nbOutputs int) [
|
|||||||
state = c.Poseidon(state)
|
state = c.Poseidon(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
var outputs []GoldilocksElement
|
var outputs []F
|
||||||
|
|
||||||
for {
|
for {
|
||||||
for i := 0; i < SPONGE_RATE; i++ {
|
for i := 0; i < SPONGE_RATE; i++ {
|
||||||
@@ -62,8 +59,8 @@ func (c *PoseidonChip) HashNToMNoPad(input []GoldilocksElement, nbOutputs int) [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PoseidonChip) HashNoPad(input []GoldilocksElement) HashOutput {
|
func (c *PoseidonChip) HashNoPad(input []F) Hash {
|
||||||
var hash [4]GoldilocksElement
|
var hash Hash
|
||||||
copy(hash[:], c.HashNToMNoPad(input, 4))
|
copy(hash[:], c.HashNToMNoPad(input, 4))
|
||||||
return hash
|
return hash
|
||||||
}
|
}
|
||||||
@@ -87,7 +84,7 @@ func (c *PoseidonChip) partialRounds(state PoseidonState, roundCounter *int) Pos
|
|||||||
|
|
||||||
for i := 0; i < N_PARTIAL_ROUNDS; i++ {
|
for i := 0; i < N_PARTIAL_ROUNDS; i++ {
|
||||||
state[0] = c.sBoxMonomial(state[0])
|
state[0] = c.sBoxMonomial(state[0])
|
||||||
state[0] = c.field.Add(state[0], FAST_PARTIAL_ROUND_CONSTANTS[i]).(GoldilocksElement)
|
state[0] = c.field.Add(state[0], FAST_PARTIAL_ROUND_CONSTANTS[i]).(F)
|
||||||
state = c.mdsPartialLayerFast(state, i)
|
state = c.mdsPartialLayerFast(state, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,8 +96,8 @@ func (c *PoseidonChip) partialRounds(state PoseidonState, roundCounter *int) Pos
|
|||||||
func (c *PoseidonChip) constantLayer(state PoseidonState, roundCounter *int) PoseidonState {
|
func (c *PoseidonChip) constantLayer(state PoseidonState, roundCounter *int) PoseidonState {
|
||||||
for i := 0; i < 12; i++ {
|
for i := 0; i < 12; i++ {
|
||||||
if i < WIDTH {
|
if i < WIDTH {
|
||||||
roundConstant := NewGoldilocksElement(ALL_ROUND_CONSTANTS[i+WIDTH*(*roundCounter)])
|
roundConstant := NewFieldElement(ALL_ROUND_CONSTANTS[i+WIDTH*(*roundCounter)])
|
||||||
state[i] = c.field.Add(state[i], roundConstant).(GoldilocksElement)
|
state[i] = c.field.Add(state[i], roundConstant).(F)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return state
|
return state
|
||||||
@@ -115,11 +112,11 @@ func (c *PoseidonChip) sBoxLayer(state PoseidonState) PoseidonState {
|
|||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PoseidonChip) sBoxMonomial(x GoldilocksElement) GoldilocksElement {
|
func (c *PoseidonChip) sBoxMonomial(x F) F {
|
||||||
x2 := c.field.Mul(x, x)
|
x2 := c.field.Mul(x, x)
|
||||||
x4 := c.field.Mul(x2, x2)
|
x4 := c.field.Mul(x2, x2)
|
||||||
x3 := c.field.Mul(x2, x)
|
x3 := c.field.Mul(x2, x)
|
||||||
return c.field.Mul(x3, x4).(GoldilocksElement)
|
return c.field.Mul(x3, x4).(F)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PoseidonChip) mdsRowShf(r int, v [WIDTH]frontend.Variable) frontend.Variable {
|
func (c *PoseidonChip) mdsRowShf(r int, v [WIDTH]frontend.Variable) frontend.Variable {
|
||||||
@@ -139,7 +136,7 @@ func (c *PoseidonChip) mdsRowShf(r int, v [WIDTH]frontend.Variable) frontend.Var
|
|||||||
func (c *PoseidonChip) mdsLayer(state_ PoseidonState) PoseidonState {
|
func (c *PoseidonChip) mdsLayer(state_ PoseidonState) PoseidonState {
|
||||||
var result PoseidonState
|
var result PoseidonState
|
||||||
for i := 0; i < WIDTH; i++ {
|
for i := 0; i < WIDTH; i++ {
|
||||||
result[i] = NewGoldilocksElement(0)
|
result[i] = NewFieldElement(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
var state [WIDTH]frontend.Variable
|
var state [WIDTH]frontend.Variable
|
||||||
@@ -151,7 +148,7 @@ func (c *PoseidonChip) mdsLayer(state_ PoseidonState) PoseidonState {
|
|||||||
if r < WIDTH {
|
if r < WIDTH {
|
||||||
sum := c.mdsRowShf(r, state)
|
sum := c.mdsRowShf(r, state)
|
||||||
bits := c.api.ToBinary(sum)
|
bits := c.api.ToBinary(sum)
|
||||||
result[r] = c.field.FromBinary(bits).(GoldilocksElement)
|
result[r] = c.field.FromBinary(bits).(F)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +158,7 @@ func (c *PoseidonChip) mdsLayer(state_ PoseidonState) PoseidonState {
|
|||||||
func (c *PoseidonChip) partialFirstConstantLayer(state PoseidonState) PoseidonState {
|
func (c *PoseidonChip) partialFirstConstantLayer(state PoseidonState) PoseidonState {
|
||||||
for i := 0; i < 12; i++ {
|
for i := 0; i < 12; i++ {
|
||||||
if i < WIDTH {
|
if i < WIDTH {
|
||||||
state[i] = c.field.Add(state[i], NewGoldilocksElement(FAST_PARTIAL_FIRST_ROUND_CONSTANT[i])).(GoldilocksElement)
|
state[i] = c.field.Add(state[i], NewFieldElement(FAST_PARTIAL_FIRST_ROUND_CONSTANT[i])).(F)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return state
|
return state
|
||||||
@@ -170,7 +167,7 @@ func (c *PoseidonChip) partialFirstConstantLayer(state PoseidonState) PoseidonSt
|
|||||||
func (c *PoseidonChip) mdsPartialLayerInit(state PoseidonState) PoseidonState {
|
func (c *PoseidonChip) mdsPartialLayerInit(state PoseidonState) PoseidonState {
|
||||||
var result PoseidonState
|
var result PoseidonState
|
||||||
for i := 0; i < 12; i++ {
|
for i := 0; i < 12; i++ {
|
||||||
result[i] = NewGoldilocksElement(0)
|
result[i] = NewFieldElement(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
result[0] = state[0]
|
result[0] = state[0]
|
||||||
@@ -179,8 +176,8 @@ func (c *PoseidonChip) mdsPartialLayerInit(state PoseidonState) PoseidonState {
|
|||||||
if r < WIDTH {
|
if r < WIDTH {
|
||||||
for d := 1; d < 12; d++ {
|
for d := 1; d < 12; d++ {
|
||||||
if d < WIDTH {
|
if d < WIDTH {
|
||||||
t := NewGoldilocksElement(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1])
|
t := NewFieldElement(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1])
|
||||||
result[d] = c.field.Add(result[d], c.field.Mul(state[r], t)).(GoldilocksElement)
|
result[d] = c.field.Add(result[d], c.field.Mul(state[r], t)).(F)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,15 +203,15 @@ func (c *PoseidonChip) mdsPartialLayerFast(state PoseidonState, r int) PoseidonS
|
|||||||
|
|
||||||
var result PoseidonState
|
var result PoseidonState
|
||||||
for i := 0; i < WIDTH; i++ {
|
for i := 0; i < WIDTH; i++ {
|
||||||
result[i] = NewGoldilocksElement(0)
|
result[i] = NewFieldElement(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
result[0] = d.(GoldilocksElement)
|
result[0] = d.(F)
|
||||||
|
|
||||||
for i := 1; i < 12; i++ {
|
for i := 1; i < 12; i++ {
|
||||||
if i < WIDTH {
|
if i < WIDTH {
|
||||||
t := NewGoldilocksElement(FAST_PARTIAL_ROUND_VS[r][i-1])
|
t := NewFieldElement(FAST_PARTIAL_ROUND_VS[r][i-1])
|
||||||
result[i] = c.field.Add(state[i], c.field.Mul(state[0], t)).(GoldilocksElement)
|
result[i] = c.field.Add(state[i], c.field.Mul(state[0], t)).(F)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package poseidon
|
package poseidon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "gnark-ed25519/goldilocks"
|
"gnark-ed25519/field"
|
||||||
|
. "gnark-ed25519/field"
|
||||||
"gnark-ed25519/utils"
|
"gnark-ed25519/utils"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -17,22 +18,20 @@ type TestPoseidonCircuit struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (circuit *TestPoseidonCircuit) Define(api frontend.API) error {
|
func (circuit *TestPoseidonCircuit) Define(api frontend.API) error {
|
||||||
goldilocksApi := NewGoldilocksAPI(api)
|
goldilocksApi := field.NewFieldAPI(api)
|
||||||
|
|
||||||
// BN254 -> Binary(64) -> GoldilocksElement
|
|
||||||
var input PoseidonState
|
var input PoseidonState
|
||||||
for i := 0; i < 12; i++ {
|
for i := 0; i < 12; i++ {
|
||||||
input[i] = goldilocksApi.FromBinary(api.ToBinary(circuit.In[i], 64)).(GoldilocksElement)
|
input[i] = goldilocksApi.FromBinary(api.ToBinary(circuit.In[i], 64)).(F)
|
||||||
}
|
}
|
||||||
|
|
||||||
chip := NewPoseidonChip(api, goldilocksApi)
|
poseidonChip := NewPoseidonChip(api, goldilocksApi)
|
||||||
output := chip.Poseidon(input)
|
output := poseidonChip.Poseidon(input)
|
||||||
|
|
||||||
// Check that output is correct
|
|
||||||
for i := 0; i < 12; i++ {
|
for i := 0; i < 12; i++ {
|
||||||
goldilocksApi.AssertIsEqual(
|
goldilocksApi.AssertIsEqual(
|
||||||
output[i],
|
output[i],
|
||||||
goldilocksApi.FromBinary(api.ToBinary(circuit.Out[i])).(GoldilocksElement),
|
goldilocksApi.FromBinary(api.ToBinary(circuit.Out[i])).(F),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +44,7 @@ func TestPoseidonWitness(t *testing.T) {
|
|||||||
testCase := func(in [12]frontend.Variable, out [12]frontend.Variable) {
|
testCase := func(in [12]frontend.Variable, out [12]frontend.Variable) {
|
||||||
circuit := TestPoseidonCircuit{In: in, Out: out}
|
circuit := TestPoseidonCircuit{In: in, Out: out}
|
||||||
witness := TestPoseidonCircuit{In: in, Out: out}
|
witness := TestPoseidonCircuit{In: in, Out: out}
|
||||||
err := test.IsSolved(&circuit, &witness, testCurve.ScalarField())
|
err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField())
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,12 +78,12 @@ func TestPoseidonProof(t *testing.T) {
|
|||||||
circuit := TestPoseidonCircuit{In: in, Out: out}
|
circuit := TestPoseidonCircuit{In: in, Out: out}
|
||||||
assignment := TestPoseidonCircuit{In: in, Out: out}
|
assignment := TestPoseidonCircuit{In: in, Out: out}
|
||||||
|
|
||||||
r1cs, err := frontend.Compile(testCurve.ScalarField(), r1cs.NewBuilder, &circuit)
|
r1cs, err := frontend.Compile(TEST_CURVE.ScalarField(), r1cs.NewBuilder, &circuit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
witness, err := frontend.NewWitness(&assignment, testCurve.ScalarField())
|
witness, err := frontend.NewWitness(&assignment, TEST_CURVE.ScalarField())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -94,7 +93,7 @@ func TestPoseidonProof(t *testing.T) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = test.IsSolved(&circuit, &assignment, testCurve.ScalarField())
|
err = test.IsSolved(&circuit, &assignment, TEST_CURVE.ScalarField())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package poseidon
|
package poseidon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "gnark-ed25519/goldilocks"
|
. "gnark-ed25519/field"
|
||||||
"gnark-ed25519/utils"
|
"gnark-ed25519/utils"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -18,22 +18,22 @@ type TestPublicInputsHashCircuit struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (circuit *TestPublicInputsHashCircuit) Define(api frontend.API) error {
|
func (circuit *TestPublicInputsHashCircuit) Define(api frontend.API) error {
|
||||||
goldilocksApi := NewGoldilocksAPI(api)
|
field := NewFieldAPI(api)
|
||||||
|
|
||||||
// BN254 -> Binary(64) -> GoldilocksElement
|
// BN254 -> Binary(64) -> F
|
||||||
var input [3]GoldilocksElement
|
var input [3]F
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
input[i] = goldilocksApi.FromBinary(api.ToBinary(circuit.In[i], 64)).(GoldilocksElement)
|
input[i] = field.FromBinary(api.ToBinary(circuit.In[i], 64)).(F)
|
||||||
}
|
}
|
||||||
|
|
||||||
poseidonChip := &PoseidonChip{api: api, field: goldilocksApi}
|
poseidonChip := &PoseidonChip{api: api, field: field}
|
||||||
output := poseidonChip.HashNoPad(input[:])
|
output := poseidonChip.HashNoPad(input[:])
|
||||||
|
|
||||||
// Check that output is correct
|
// Check that output is correct
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
goldilocksApi.AssertIsEqual(
|
field.AssertIsEqual(
|
||||||
output[i],
|
output[i],
|
||||||
goldilocksApi.FromBinary(api.ToBinary(circuit.Out[i])).(GoldilocksElement),
|
field.FromBinary(api.ToBinary(circuit.Out[i])).(F),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
. "gnark-ed25519/field"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/consensys/gnark/frontend"
|
"github.com/consensys/gnark/frontend"
|
||||||
@@ -23,3 +24,19 @@ func StrArrayToFrontendVariableArray(input []string) []frontend.Variable {
|
|||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Uint64ArrayToFArray(input []uint64) []F {
|
||||||
|
var output []F
|
||||||
|
for i := 0; i < len(input); i++ {
|
||||||
|
output = append(output, NewFieldElement(input[i]))
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
func Uint64ArrayToQuadraticExtensionArray(input [][]uint64) []QuadraticExtension {
|
||||||
|
var output []QuadraticExtension
|
||||||
|
for i := 0; i < len(input); i++ {
|
||||||
|
output = append(output, [2]F{NewFieldElement(input[i][0]), NewFieldElement(input[i][1])})
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user