small refactor of names

This commit is contained in:
jtguibas
2022-10-10 17:59:55 -07:00
parent 7367106b04
commit a058df6099
10 changed files with 236 additions and 323 deletions

View File

@@ -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
}

View File

@@ -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,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.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) 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 +66,20 @@ func (c *ChallengerChip) GetChallenge() GoldilocksElement {
return challenge return challenge
} }
func (c *ChallengerChip) GetNChallenges(n int) []GoldilocksElement { func (c *ChallengerChip) GetNChallenges(n int) []F {
challenges := make([]GoldilocksElement, n) challenges := make([]F, n)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
challenges[i] = c.GetChallenge() challenges[i] = c.GetChallenge()
} }
return challenges return challenges
} }
func clearBuffer(buffer []GoldilocksElement) []GoldilocksElement { func clearBuffer(buffer []F) []F {
return make([]GoldilocksElement, 0) 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")
} }

View File

@@ -3,20 +3,18 @@ package plonky2_verifier
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
. "gnark-ed25519/goldilocks" "gnark-ed25519/field"
. "gnark-ed25519/field"
. "gnark-ed25519/poseidon" . "gnark-ed25519/poseidon"
"gnark-ed25519/utils" "gnark-ed25519/utils"
"io/ioutil" "io/ioutil"
"os" "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
@@ -24,53 +22,48 @@ 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) poseidon := NewPoseidonChip(api, field)
challengerChip := NewChallengerChip(api, goldilocksApi, *poseidonChip) challenger := NewChallengerChip(api, field, *poseidon)
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 := poseidon.HashNoPad(publicInputs[:])
challengerChip.ObserveHash(circuitDigestGoldilocks) challenger.ObserveHash(circuitDigest)
challengerChip.ObserveHash(publicInputHash) challenger.ObserveHash(publicInputHash)
challengerChip.ObserveCap(wiresCapGoldilocks[:]) challenger.ObserveCap(wiresCap[:])
nbChallenges := 2 nbChallenges := 2
plonkBetas := challengerChip.GetNChallenges(nbChallenges) plonkBetas := challenger.GetNChallenges(nbChallenges)
plonkGammas := challengerChip.GetNChallenges(nbChallenges) plonkGammas := challenger.GetNChallenges(nbChallenges)
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
@@ -98,7 +91,7 @@ func TestChallengerWitness(t *testing.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)
} }

111
plonky2_verifier/proof.go Normal file
View File

@@ -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
}

View File

@@ -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"`
}

View File

@@ -1,47 +1,43 @@
package plonky2_verifier package plonky2_verifier
import ( // import (
. "gnark-ed25519/goldilocks" // . "gnark-ed25519/field"
"gnark-ed25519/poseidon" // "gnark-ed25519/poseidon"
"gnark-ed25519/utils"
"github.com/consensys/gnark/frontend" // "github.com/consensys/gnark/frontend"
) // )
type VerifierChip struct { // type VerifierChip struct {
api frontend.API // api frontend.API
field frontend.API // field frontend.API
poseidonChip poseidon.PoseidonChip // poseidonChip poseidon.PoseidonChip
} // }
func (c *VerifierChip) GetPublicInputsHash(publicInputs []GoldilocksElement) poseidon.HashOutput { // func (c *VerifierChip) GetPublicInputsHash(publicInputs []F) poseidon.HashOutput {
return c.poseidonChip.HashNoPad(publicInputs) // return c.poseidonChip.HashNoPad(publicInputs)
} // }
func (c *VerifierChip) GetChallenges(proofWithPis ProofWithPublicInputs, publicInputsHash Hash, commonData CommonCircuitData) { // func (c *VerifierChip) GetChallenges(proofWithPis ProofWithPublicInputs, publicInputsHash Hash, commonData CommonCircuitData) {
config := commonData.Config // config := commonData.Config
numChallenges := int(config.NumChallenges) // numChallenges := int(config.NumChallenges)
challenger := NewChallengerChip(c.api, c.field, c.poseidonChip) // challenger := NewChallengerChip(c.api, c.field, c.poseidonChip)
var circuitDigest Hash // challenger.ObserveHash(commonData.CircuitDigest)
copy(circuitDigest[:], utils.Uint64ArrayToGoldilocksElementArray(commonData.CircuitDigest.Elements)) // challenger.ObserveHash(publicInputsHash)
// challenger.ObserveCap(proofWithPis.Proof.WiresCap)
// plonkBetas := challenger.GetNChallenges(numChallenges)
// plonkGammas := challenger.GetNChallenges(numChallenges)
challenger.ObserveHash(circuitDigest) // challenger.ObserveCap(proofWithPis.Proof.PlonkZsPartialProductsCap)
challenger.ObserveHash(publicInputsHash) // plonkAlphas := challenger.GetNChallenges(numChallenges)
challenger.ObserveCap(proofWithPis.Proof.WiresCap)
plonkBetas := challenger.GetNChallenges(numChallenges)
plonkGammas := challenger.GetNChallenges(numChallenges)
challenger.ObserveCap(proofWithPis.Proof.PlonkZsPartialProductsCap) // challenger.ObserveCap(proofWithPis.Proof.QuotientPolysCap)
plonkAlphas := challenger.GetNChallenges(numChallenges) // plonkZeta := challenger.GetNChallenges(numChallenges)
challenger.ObserveCap(proofWithPis.Proof.QuotientPolysCap) // challenger.ObserveOpenings(proofWithPis.Proof.Openings)
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)
func (c *VerifierChip) Verify(proofWithPis ProofWithPublicInputs, verifierData VerifierOnlyCircuitData, commonData CommonCircuitData) { // }
publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs)
challenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData)
}

View File

@@ -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)
} }
} }

View File

@@ -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) chip := NewPoseidonChip(api, goldilocksApi)
output := chip.Poseidon(input) output := chip.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)
} }

View File

@@ -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),
) )
} }

View File

@@ -1,7 +1,7 @@
package utils package utils
import ( import (
. "gnark-ed25519/goldilocks" . "gnark-ed25519/field"
"math/big" "math/big"
"github.com/consensys/gnark/frontend" "github.com/consensys/gnark/frontend"
@@ -26,8 +26,8 @@ func StrArrayToFrontendVariableArray(input []string) []frontend.Variable {
return output return output
} }
func Uint64ArrayToGoldilocksElementArray(input []uint64) []GoldilocksElement { func Uint64ArrayToFArray(input []uint64) []F {
var output []GoldilocksElement var output []F
for i := 0; i < len(input); i++ { for i := 0; i < len(input); i++ {
output = append(output, emulated.NewElement[emulated.Goldilocks](input[i])) output = append(output, emulated.NewElement[emulated.Goldilocks](input[i]))
} }