From a058df60992cade468db0f6545d8006219fdf7c5 Mon Sep 17 00:00:00 2001 From: jtguibas Date: Mon, 10 Oct 2022 17:59:55 -0700 Subject: [PATCH] small refactor of names --- goldilocks/goldilocks.go | 20 ---- plonky2_verifier/challenger.go | 41 ++++--- plonky2_verifier/challenger_test.go | 71 ++++++------ plonky2_verifier/proof.go | 111 +++++++++++++++++++ plonky2_verifier/structs.go | 162 ---------------------------- plonky2_verifier/verifier.go | 86 +++++++-------- poseidon/poseidon.go | 45 ++++---- poseidon/poseidon_test.go | 19 ++-- poseidon/public_inputs_hash_test.go | 16 +-- utils/utils.go | 6 +- 10 files changed, 245 insertions(+), 332 deletions(-) delete mode 100644 goldilocks/goldilocks.go create mode 100644 plonky2_verifier/proof.go delete mode 100644 plonky2_verifier/structs.go diff --git a/goldilocks/goldilocks.go b/goldilocks/goldilocks.go deleted file mode 100644 index 3dead4a..0000000 --- a/goldilocks/goldilocks.go +++ /dev/null @@ -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 -} diff --git a/plonky2_verifier/challenger.go b/plonky2_verifier/challenger.go index cf052e2..1010661 100644 --- a/plonky2_verifier/challenger.go +++ b/plonky2_verifier/challenger.go @@ -2,9 +2,8 @@ package plonky2_verifier import ( "fmt" - . "gnark-ed25519/goldilocks" + . "gnark-ed25519/field" "gnark-ed25519/poseidon" - . "gnark-ed25519/poseidon" "github.com/consensys/gnark/frontend" ) @@ -12,16 +11,16 @@ import ( type ChallengerChip struct { api frontend.API field frontend.API - poseidonChip PoseidonChip - spongeState [SPONGE_WIDTH]GoldilocksElement - inputBuffer []GoldilocksElement - outputBuffer []GoldilocksElement + poseidonChip poseidon.PoseidonChip + spongeState [poseidon.SPONGE_WIDTH]F + inputBuffer []F + outputBuffer []F } -func NewChallengerChip(api frontend.API, field frontend.API, poseidonChip PoseidonChip) *ChallengerChip { - var spongeState [SPONGE_WIDTH]GoldilocksElement - var inputBuffer []GoldilocksElement - var outputBuffer []GoldilocksElement +func NewChallengerChip(api frontend.API, field frontend.API, poseidonChip poseidon.PoseidonChip) *ChallengerChip { + var spongeState [poseidon.SPONGE_WIDTH]F + var inputBuffer []F + var outputBuffer []F return &ChallengerChip{ api: api, field: field, @@ -32,31 +31,31 @@ 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.inputBuffer = append(c.inputBuffer, element) - if len(c.inputBuffer) == SPONGE_RATE { + if len(c.inputBuffer) == poseidon.SPONGE_RATE { c.duplexing() } } -func (c *ChallengerChip) ObserveElements(elements []GoldilocksElement) { +func (c *ChallengerChip) ObserveElements(elements []F) { for i := 0; i < len(elements); i++ { c.ObserveElement(elements[i]) } } -func (c *ChallengerChip) ObserveHash(hash HashOutput) { +func (c *ChallengerChip) ObserveHash(hash Hash) { c.ObserveElements(hash[:]) } -func (c *ChallengerChip) ObserveCap(cap []HashOutput) { +func (c *ChallengerChip) ObserveCap(cap []Hash) { for i := 0; i < len(cap); i++ { c.ObserveHash(cap[i]) } } -func (c *ChallengerChip) GetChallenge() GoldilocksElement { +func (c *ChallengerChip) GetChallenge() F { if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 { c.duplexing() } @@ -67,20 +66,20 @@ func (c *ChallengerChip) GetChallenge() GoldilocksElement { return challenge } -func (c *ChallengerChip) GetNChallenges(n int) []GoldilocksElement { - challenges := make([]GoldilocksElement, n) +func (c *ChallengerChip) GetNChallenges(n int) []F { + challenges := make([]F, n) for i := 0; i < n; i++ { challenges[i] = c.GetChallenge() } return challenges } -func clearBuffer(buffer []GoldilocksElement) []GoldilocksElement { - return make([]GoldilocksElement, 0) +func clearBuffer(buffer []F) []F { + return make([]F, 0) } func (c *ChallengerChip) duplexing() { - if len(c.inputBuffer) > SPONGE_RATE { + if len(c.inputBuffer) > poseidon.SPONGE_RATE { fmt.Println(len(c.inputBuffer)) panic("something went wrong") } diff --git a/plonky2_verifier/challenger_test.go b/plonky2_verifier/challenger_test.go index ec6aefc..b351c9f 100644 --- a/plonky2_verifier/challenger_test.go +++ b/plonky2_verifier/challenger_test.go @@ -3,20 +3,18 @@ package plonky2_verifier import ( "encoding/json" "fmt" - . "gnark-ed25519/goldilocks" + "gnark-ed25519/field" + . "gnark-ed25519/field" . "gnark-ed25519/poseidon" "gnark-ed25519/utils" "io/ioutil" "os" "testing" - "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/test" ) -var testCurve = ecc.BN254 - type TestChallengerCircuit struct { PublicInputs [3]frontend.Variable CircuitDigest [4]frontend.Variable @@ -24,53 +22,48 @@ type TestChallengerCircuit struct { } func (circuit *TestChallengerCircuit) Define(api frontend.API) error { - goldilocksApi := NewGoldilocksAPI(api) - poseidonChip := NewPoseidonChip(api, goldilocksApi) - challengerChip := NewChallengerChip(api, goldilocksApi, *poseidonChip) + field := field.NewFieldAPI(api) + poseidon := NewPoseidonChip(api, field) + challenger := NewChallengerChip(api, field, *poseidon) - var circuitDigestGoldilocks [4]GoldilocksElement - for i := 0; i < 4; i++ { - circuitDigestGoldilocks[i] = goldilocksApi.FromBinary(api.ToBinary(circuit.CircuitDigest[i], 64)).(GoldilocksElement) + var circuitDigest [4]F + for i := 0; i < len(circuitDigest); i++ { + circuitDigest[i] = field.FromBinary(api.ToBinary(circuit.CircuitDigest[i], 64)).(F) } - var publicInputsGoldilocks [3]GoldilocksElement - for i := 0; i < 3; i++ { - publicInputsGoldilocks[i] = goldilocksApi.FromBinary(api.ToBinary(circuit.PublicInputs[i], 64)).(GoldilocksElement) + var publicInputs [3]F + for i := 0; i < len(publicInputs); i++ { + publicInputs[i] = field.FromBinary(api.ToBinary(circuit.PublicInputs[i], 64)).(F) } - var wiresCapGoldilocks [16][4]GoldilocksElement - for i := 0; i < 16; i++ { - for j := 0; j < 4; j++ { - wiresCapGoldilocks[i][j] = goldilocksApi.FromBinary(api.ToBinary(circuit.WiresCap[i][j], 64)).(GoldilocksElement) + var wiresCap [16][4]F + for i := 0; i < len(wiresCap); i++ { + for j := 0; j < len(wiresCap[0]); j++ { + wiresCap[i][j] = field.FromBinary(api.ToBinary(circuit.WiresCap[i][j], 64)).(F) } } - publicInputHash := poseidonChip.HashNoPad(publicInputsGoldilocks[:]) - challengerChip.ObserveHash(circuitDigestGoldilocks) - challengerChip.ObserveHash(publicInputHash) - challengerChip.ObserveCap(wiresCapGoldilocks[:]) + publicInputHash := poseidon.HashNoPad(publicInputs[:]) + challenger.ObserveHash(circuitDigest) + challenger.ObserveHash(publicInputHash) + challenger.ObserveCap(wiresCap[:]) nbChallenges := 2 - plonkBetas := challengerChip.GetNChallenges(nbChallenges) - plonkGammas := challengerChip.GetNChallenges(nbChallenges) - - var expectedPlonkBetas [2]frontend.Variable - expectedPlonkBetas[0] = frontend.Variable("4678728155650926271") - expectedPlonkBetas[1] = frontend.Variable("13611962404289024887") + plonkBetas := challenger.GetNChallenges(nbChallenges) + plonkGammas := challenger.GetNChallenges(nbChallenges) - var expectedPlonkGammas [2]frontend.Variable - expectedPlonkGammas[0] = frontend.Variable("13237663823305715949") - expectedPlonkGammas[1] = frontend.Variable("15389314098328235145") + expectedPlonkBetas := [2]frontend.Variable{ + frontend.Variable("4678728155650926271"), + frontend.Variable("13611962404289024887"), + } + expectedPlonkGammas := [2]frontend.Variable{ + frontend.Variable("13237663823305715949"), + frontend.Variable("15389314098328235145"), + } for i := 0; i < 2; i++ { - goldilocksApi.AssertIsEqual( - plonkBetas[i], - goldilocksApi.FromBinary(api.ToBinary(expectedPlonkBetas[i])).(GoldilocksElement), - ) - goldilocksApi.AssertIsEqual( - plonkGammas[i], - goldilocksApi.FromBinary(api.ToBinary(expectedPlonkGammas[i])).(GoldilocksElement), - ) + field.AssertIsEqual(plonkBetas[i], field.FromBinary(api.ToBinary(expectedPlonkBetas[i])).(F)) + field.AssertIsEqual(plonkGammas[i], field.FromBinary(api.ToBinary(expectedPlonkGammas[i])).(F)) } return nil @@ -98,7 +91,7 @@ func TestChallengerWitness(t *testing.T) { testCase := func(publicInputs [3]frontend.Variable, circuitDigest [4]frontend.Variable, wiresCap [16][4]frontend.Variable) { circuit := 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) } diff --git a/plonky2_verifier/proof.go b/plonky2_verifier/proof.go new file mode 100644 index 0000000..6bb5863 --- /dev/null +++ b/plonky2_verifier/proof.go @@ -0,0 +1,111 @@ +package plonky2_verifier + +import ( + . "gnark-ed25519/field" +) + +type QuadraticExtension = [2]F + +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 []F +} + +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 + // TODO: add SelectorsInfo and Gates +} diff --git a/plonky2_verifier/structs.go b/plonky2_verifier/structs.go deleted file mode 100644 index 8e97b3f..0000000 --- a/plonky2_verifier/structs.go +++ /dev/null @@ -1,162 +0,0 @@ -package plonky2_verifier - -import ( - . "gnark-ed25519/goldilocks" -) - -type Hash = [4]GoldilocksElement -type QuadraticExtension = [2]GoldilocksElement -type MerkleCap = []Hash - -type MerkleProof struct { - Siblings []Hash -} - -type EvalProof struct { - Elements []GoldilocksElement - 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 []GoldilocksElement -} - -type FriProof struct { - CommitPhaseMerkleCaps []MerkleCap - QueryRoundProofs FriQueryRound - FinalPoly PolynomialCoeffs - PowWitness GoldilocksElement -} - -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 []GoldilocksElement -} - -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 []uint64 `json:"public_inputs"` -} - -type CommonCircuitData 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 []uint64 `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 []interface{} `json:"k_is"` - NumPartialProducts uint64 `json:"num_partial_products"` - CircuitDigest struct { - Elements []uint64 `json:"elements"` - } `json:"circuit_digest"` -} - -type VerifierOnlyCircuitData struct { - ConstantsSigmasCap []struct { - Elements []uint64 `json:"elements"` - } `json:"constants_sigmas_cap"` -} diff --git a/plonky2_verifier/verifier.go b/plonky2_verifier/verifier.go index 98c23df..c9f3d48 100644 --- a/plonky2_verifier/verifier.go +++ b/plonky2_verifier/verifier.go @@ -1,47 +1,43 @@ package plonky2_verifier -import ( - . "gnark-ed25519/goldilocks" - "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 []GoldilocksElement) poseidon.HashOutput { - return c.poseidonChip.HashNoPad(publicInputs) -} - -func (c *VerifierChip) GetChallenges(proofWithPis ProofWithPublicInputs, publicInputsHash Hash, commonData CommonCircuitData) { - config := commonData.Config - numChallenges := int(config.NumChallenges) - challenger := NewChallengerChip(c.api, c.field, c.poseidonChip) - - var circuitDigest Hash - copy(circuitDigest[:], utils.Uint64ArrayToGoldilocksElementArray(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.GetNChallenges(numChallenges) - - challenger.ObserveOpenings(proofWithPis.Proof.Openings) -} - -func (c *VerifierChip) Verify(proofWithPis ProofWithPublicInputs, verifierData VerifierOnlyCircuitData, commonData CommonCircuitData) { - publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs) - challenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData) -} +// import ( +// . "gnark-ed25519/field" +// "gnark-ed25519/poseidon" + +// "github.com/consensys/gnark/frontend" +// ) + +// type VerifierChip struct { +// api frontend.API +// field frontend.API +// poseidonChip poseidon.PoseidonChip +// } + +// func (c *VerifierChip) GetPublicInputsHash(publicInputs []F) poseidon.HashOutput { +// return c.poseidonChip.HashNoPad(publicInputs) +// } + +// func (c *VerifierChip) GetChallenges(proofWithPis ProofWithPublicInputs, publicInputsHash Hash, commonData CommonCircuitData) { +// config := commonData.Config +// numChallenges := int(config.NumChallenges) +// challenger := NewChallengerChip(c.api, c.field, c.poseidonChip) + +// challenger.ObserveHash(commonData.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.GetNChallenges(numChallenges) + +// challenger.ObserveOpenings(proofWithPis.Proof.Openings) +// } + +// func (c *VerifierChip) Verify(proofWithPis ProofWithPublicInputs, verifierData VerifierOnlyCircuitData, commonData CommonCircuitData) { +// publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs) +// challenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData) +// } diff --git a/poseidon/poseidon.go b/poseidon/poseidon.go index a77df7f..b4eaf68 100644 --- a/poseidon/poseidon.go +++ b/poseidon/poseidon.go @@ -1,13 +1,11 @@ package poseidon import ( - . "gnark-ed25519/goldilocks" + . "gnark-ed25519/field" "github.com/consensys/gnark/frontend" ) -/* Note: This package assumes usage of the BN254 curve in various places. */ - const HALF_N_FULL_ROUNDS = 4 const N_FULL_ROUNDS_TOTAL = 2 * HALF_N_FULL_ROUNDS const N_PARTIAL_ROUNDS = 22 @@ -17,8 +15,7 @@ const WIDTH = 12 const SPONGE_WIDTH = 12 const SPONGE_RATE = 8 -type PoseidonState = [WIDTH]GoldilocksElement -type HashOutput = [4]GoldilocksElement +type PoseidonState = [WIDTH]F type PoseidonChip struct { api frontend.API field frontend.API @@ -37,7 +34,7 @@ func (c *PoseidonChip) Poseidon(input PoseidonState) PoseidonState { return state } -func (c *PoseidonChip) HashNToMNoPad(input []GoldilocksElement, nbOutputs int) []GoldilocksElement { +func (c *PoseidonChip) HashNToMNoPad(input []F, nbOutputs int) []F { var state PoseidonState 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) } - var outputs []GoldilocksElement + var outputs []F for { 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 { - var hash [4]GoldilocksElement +func (c *PoseidonChip) HashNoPad(input []F) Hash { + var hash Hash copy(hash[:], c.HashNToMNoPad(input, 4)) return hash } @@ -87,7 +84,7 @@ func (c *PoseidonChip) partialRounds(state PoseidonState, roundCounter *int) Pos for i := 0; i < N_PARTIAL_ROUNDS; i++ { state[0] = c.sBoxMonomial(state[0]) - state[0] = c.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) } @@ -99,8 +96,8 @@ func (c *PoseidonChip) partialRounds(state PoseidonState, roundCounter *int) Pos func (c *PoseidonChip) constantLayer(state PoseidonState, roundCounter *int) PoseidonState { for i := 0; i < 12; i++ { if i < WIDTH { - roundConstant := NewGoldilocksElement(ALL_ROUND_CONSTANTS[i+WIDTH*(*roundCounter)]) - state[i] = c.field.Add(state[i], roundConstant).(GoldilocksElement) + roundConstant := NewFieldElement(ALL_ROUND_CONSTANTS[i+WIDTH*(*roundCounter)]) + state[i] = c.field.Add(state[i], roundConstant).(F) } } return state @@ -115,11 +112,11 @@ func (c *PoseidonChip) sBoxLayer(state PoseidonState) PoseidonState { return state } -func (c *PoseidonChip) sBoxMonomial(x GoldilocksElement) GoldilocksElement { +func (c *PoseidonChip) sBoxMonomial(x F) F { x2 := c.field.Mul(x, x) x4 := c.field.Mul(x2, x2) 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 { @@ -139,7 +136,7 @@ func (c *PoseidonChip) mdsRowShf(r int, v [WIDTH]frontend.Variable) frontend.Var func (c *PoseidonChip) mdsLayer(state_ PoseidonState) PoseidonState { var result PoseidonState for i := 0; i < WIDTH; i++ { - result[i] = NewGoldilocksElement(0) + result[i] = NewFieldElement(0) } var state [WIDTH]frontend.Variable @@ -151,7 +148,7 @@ func (c *PoseidonChip) mdsLayer(state_ PoseidonState) PoseidonState { if r < WIDTH { sum := c.mdsRowShf(r, state) 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 { for i := 0; i < 12; i++ { 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 @@ -170,7 +167,7 @@ func (c *PoseidonChip) partialFirstConstantLayer(state PoseidonState) PoseidonSt func (c *PoseidonChip) mdsPartialLayerInit(state PoseidonState) PoseidonState { var result PoseidonState for i := 0; i < 12; i++ { - result[i] = NewGoldilocksElement(0) + result[i] = NewFieldElement(0) } result[0] = state[0] @@ -179,8 +176,8 @@ func (c *PoseidonChip) mdsPartialLayerInit(state PoseidonState) PoseidonState { if r < WIDTH { for d := 1; d < 12; d++ { if d < WIDTH { - t := NewGoldilocksElement(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1]) - result[d] = c.field.Add(result[d], c.field.Mul(state[r], t)).(GoldilocksElement) + t := NewFieldElement(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1]) + 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 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++ { if i < WIDTH { - t := NewGoldilocksElement(FAST_PARTIAL_ROUND_VS[r][i-1]) - result[i] = c.field.Add(state[i], c.field.Mul(state[0], t)).(GoldilocksElement) + t := NewFieldElement(FAST_PARTIAL_ROUND_VS[r][i-1]) + result[i] = c.field.Add(state[i], c.field.Mul(state[0], t)).(F) } } diff --git a/poseidon/poseidon_test.go b/poseidon/poseidon_test.go index ecd7253..1271b60 100644 --- a/poseidon/poseidon_test.go +++ b/poseidon/poseidon_test.go @@ -1,7 +1,8 @@ package poseidon import ( - . "gnark-ed25519/goldilocks" + "gnark-ed25519/field" + . "gnark-ed25519/field" "gnark-ed25519/utils" "testing" @@ -17,22 +18,20 @@ type TestPoseidonCircuit struct { } func (circuit *TestPoseidonCircuit) Define(api frontend.API) error { - goldilocksApi := NewGoldilocksAPI(api) + goldilocksApi := field.NewFieldAPI(api) - // BN254 -> Binary(64) -> GoldilocksElement var input PoseidonState 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) output := chip.Poseidon(input) - // Check that output is correct for i := 0; i < 12; i++ { goldilocksApi.AssertIsEqual( 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) { circuit := 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) } @@ -79,12 +78,12 @@ func TestPoseidonProof(t *testing.T) { circuit := 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 { panic(err) } - witness, err := frontend.NewWitness(&assignment, testCurve.ScalarField()) + witness, err := frontend.NewWitness(&assignment, TEST_CURVE.ScalarField()) if err != nil { panic(err) } @@ -94,7 +93,7 @@ func TestPoseidonProof(t *testing.T) { panic(err) } - err = test.IsSolved(&circuit, &assignment, testCurve.ScalarField()) + err = test.IsSolved(&circuit, &assignment, TEST_CURVE.ScalarField()) if err != nil { panic(err) } diff --git a/poseidon/public_inputs_hash_test.go b/poseidon/public_inputs_hash_test.go index b7de618..503b737 100644 --- a/poseidon/public_inputs_hash_test.go +++ b/poseidon/public_inputs_hash_test.go @@ -1,7 +1,7 @@ package poseidon import ( - . "gnark-ed25519/goldilocks" + . "gnark-ed25519/field" "gnark-ed25519/utils" "testing" @@ -18,22 +18,22 @@ type TestPublicInputsHashCircuit struct { } func (circuit *TestPublicInputsHashCircuit) Define(api frontend.API) error { - goldilocksApi := NewGoldilocksAPI(api) + field := NewFieldAPI(api) - // BN254 -> Binary(64) -> GoldilocksElement - var input [3]GoldilocksElement + // BN254 -> Binary(64) -> F + var input [3]F 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[:]) // Check that output is correct for i := 0; i < 4; i++ { - goldilocksApi.AssertIsEqual( + field.AssertIsEqual( output[i], - goldilocksApi.FromBinary(api.ToBinary(circuit.Out[i])).(GoldilocksElement), + field.FromBinary(api.ToBinary(circuit.Out[i])).(F), ) } diff --git a/utils/utils.go b/utils/utils.go index 33a498e..f2e2f91 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,7 +1,7 @@ package utils import ( - . "gnark-ed25519/goldilocks" + . "gnark-ed25519/field" "math/big" "github.com/consensys/gnark/frontend" @@ -26,8 +26,8 @@ func StrArrayToFrontendVariableArray(input []string) []frontend.Variable { return output } -func Uint64ArrayToGoldilocksElementArray(input []uint64) []GoldilocksElement { - var output []GoldilocksElement +func Uint64ArrayToFArray(input []uint64) []F { + var output []F for i := 0; i < len(input); i++ { output = append(output, emulated.NewElement[emulated.Goldilocks](input[i])) }