Rearranged files (#17)

* removed unused file

* change field import

* change import of field package

* changed field import

* moved hash to poseidon and some changes to the field package

* changed file structure
This commit is contained in:
Kevin Jue
2023-05-19 19:49:14 -07:00
committed by GitHub
parent a415c95f6f
commit cf84b032e2
72 changed files with 2376 additions and 2228 deletions

53
poseidon/hash.go Normal file
View File

@@ -0,0 +1,53 @@
package poseidon
import (
"github.com/consensys/gnark/frontend"
"github.com/succinctlabs/gnark-plonky2-verifier/field"
)
type Hash = [4]field.F
type HashAPI struct {
fieldAPI frontend.API
}
func NewHashAPI(
fieldAPI frontend.API,
) *HashAPI {
return &HashAPI{
fieldAPI: fieldAPI,
}
}
func (h *HashAPI) SelectHash(bit frontend.Variable, leftHash, rightHash Hash) Hash {
var returnHash Hash
for i := 0; i < 4; i++ {
returnHash[i] = h.fieldAPI.Select(bit, leftHash[i], rightHash[i]).(field.F)
}
return returnHash
}
func (h *HashAPI) Lookup2Hash(b0 frontend.Variable, b1 frontend.Variable, h0, h1, h2, h3 Hash) Hash {
var returnHash Hash
for i := 0; i < 4; i++ {
returnHash[i] = h.fieldAPI.Lookup2(b0, b1, h0[i], h1[i], h2[i], h3[i]).(field.F)
}
return returnHash
}
func (h *HashAPI) AssertIsEqualHash(h1, h2 Hash) {
for i := 0; i < 4; i++ {
h.fieldAPI.AssertIsEqual(h1[0], h2[0])
}
}
func Uint64ArrayToHashArray(input [][]uint64) []Hash {
var output []Hash
for i := 0; i < len(input); i++ {
output = append(output, [4]field.F{field.NewFieldElement(input[i][0]), field.NewFieldElement(input[i][1]), field.NewFieldElement(input[i][2]), field.NewFieldElement(input[i][3])})
}
return output
}

View File

@@ -1,9 +1,8 @@
package poseidon
import (
. "gnark-plonky2-verifier/field"
"github.com/consensys/gnark/frontend"
"github.com/succinctlabs/gnark-plonky2-verifier/field"
)
const HALF_N_FULL_ROUNDS = 4
@@ -14,16 +13,16 @@ const MAX_WIDTH = 12
const SPONGE_WIDTH = 12
const SPONGE_RATE = 8
type PoseidonState = [SPONGE_WIDTH]F
type PoseidonStateExtension = [SPONGE_WIDTH]QuadraticExtension
type PoseidonState = [SPONGE_WIDTH]field.F
type PoseidonStateExtension = [SPONGE_WIDTH]field.QuadraticExtension
type PoseidonChip struct {
api frontend.API `gnark:"-"`
fieldAPI frontend.API `gnark:"-"`
qeAPI *QuadraticExtensionAPI `gnark:"-"`
api frontend.API `gnark:"-"`
fieldAPI frontend.API `gnark:"-"`
qeAPI *field.QuadraticExtensionAPI `gnark:"-"`
}
func NewPoseidonChip(api frontend.API, fieldAPI frontend.API, qeAPI *QuadraticExtensionAPI) *PoseidonChip {
func NewPoseidonChip(api frontend.API, fieldAPI frontend.API, qeAPI *field.QuadraticExtensionAPI) *PoseidonChip {
return &PoseidonChip{api: api, fieldAPI: fieldAPI, qeAPI: qeAPI}
}
@@ -36,11 +35,11 @@ func (c *PoseidonChip) Poseidon(input PoseidonState) PoseidonState {
return state
}
func (c *PoseidonChip) HashNToMNoPad(input []F, nbOutputs int) []F {
func (c *PoseidonChip) HashNToMNoPad(input []field.F, nbOutputs int) []field.F {
var state PoseidonState
for i := 0; i < SPONGE_WIDTH; i++ {
state[i] = ZERO_F
state[i] = field.ZERO_F
}
for i := 0; i < len(input); i += SPONGE_RATE {
@@ -52,7 +51,7 @@ func (c *PoseidonChip) HashNToMNoPad(input []F, nbOutputs int) []F {
state = c.Poseidon(state)
}
var outputs []F
var outputs []field.F
for {
for i := 0; i < SPONGE_RATE; i++ {
@@ -65,7 +64,7 @@ func (c *PoseidonChip) HashNToMNoPad(input []F, nbOutputs int) []F {
}
}
func (c *PoseidonChip) HashNoPad(input []F) Hash {
func (c *PoseidonChip) HashNoPad(input []field.F) Hash {
var hash Hash
copy(hash[:], c.HashNToMNoPad(input, 4))
return hash
@@ -87,7 +86,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.fieldAPI.Add(state[0], FAST_PARTIAL_ROUND_CONSTANTS[i]).(F)
state[0] = c.fieldAPI.Add(state[0], FAST_PARTIAL_ROUND_CONSTANTS[i]).(field.F)
state = c.MdsPartialLayerFast(state, i)
}
@@ -99,8 +98,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 < SPONGE_WIDTH {
roundConstant := NewFieldElement(ALL_ROUND_CONSTANTS[i+SPONGE_WIDTH*(*roundCounter)])
state[i] = c.fieldAPI.Add(state[i], roundConstant).(F)
roundConstant := field.NewFieldElement(ALL_ROUND_CONSTANTS[i+SPONGE_WIDTH*(*roundCounter)])
state[i] = c.fieldAPI.Add(state[i], roundConstant).(field.F)
}
}
return state
@@ -109,21 +108,21 @@ func (c *PoseidonChip) ConstantLayer(state PoseidonState, roundCounter *int) Pos
func (c *PoseidonChip) ConstantLayerExtension(state PoseidonStateExtension, roundCounter *int) PoseidonStateExtension {
for i := 0; i < 12; i++ {
if i < SPONGE_WIDTH {
roundConstant := c.qeAPI.FieldToQE(NewFieldElement(ALL_ROUND_CONSTANTS[i+SPONGE_WIDTH*(*roundCounter)]))
roundConstant := c.qeAPI.FieldToQE(field.NewFieldElement(ALL_ROUND_CONSTANTS[i+SPONGE_WIDTH*(*roundCounter)]))
state[i] = c.qeAPI.AddExtension(state[i], roundConstant)
}
}
return state
}
func (c *PoseidonChip) SBoxMonomial(x F) F {
func (c *PoseidonChip) SBoxMonomial(x field.F) field.F {
x2 := c.fieldAPI.Mul(x, x)
x4 := c.fieldAPI.Mul(x2, x2)
x3 := c.fieldAPI.Mul(x, x2)
return c.fieldAPI.Mul(x3, x4).(F)
return c.fieldAPI.Mul(x3, x4).(field.F)
}
func (c *PoseidonChip) SBoxMonomialExtension(x QuadraticExtension) QuadraticExtension {
func (c *PoseidonChip) SBoxMonomialExtension(x field.QuadraticExtension) field.QuadraticExtension {
x2 := c.qeAPI.SquareExtension(x)
x4 := c.qeAPI.SquareExtension(x2)
x3 := c.qeAPI.MulExtension(x, x2)
@@ -162,18 +161,18 @@ func (c *PoseidonChip) MdsRowShf(r int, v [SPONGE_WIDTH]frontend.Variable) front
return res
}
func (c *PoseidonChip) MdsRowShfExtension(r int, v [SPONGE_WIDTH]QuadraticExtension) QuadraticExtension {
res := c.qeAPI.FieldToQE(NewFieldElement(0))
func (c *PoseidonChip) MdsRowShfExtension(r int, v [SPONGE_WIDTH]field.QuadraticExtension) field.QuadraticExtension {
res := c.qeAPI.FieldToQE(field.NewFieldElement(0))
for i := 0; i < 12; i++ {
if i < SPONGE_WIDTH {
matrixVal := c.qeAPI.FieldToQE(NewFieldElement(MDS_MATRIX_CIRC[i]))
matrixVal := c.qeAPI.FieldToQE(field.NewFieldElement(MDS_MATRIX_CIRC[i]))
res1 := c.qeAPI.MulExtension(v[(i+r)%SPONGE_WIDTH], matrixVal)
res = c.qeAPI.AddExtension(res, res1)
}
}
matrixVal := c.qeAPI.FieldToQE(NewFieldElement(MDS_MATRIX_DIAG[r]))
matrixVal := c.qeAPI.FieldToQE(field.NewFieldElement(MDS_MATRIX_DIAG[r]))
res = c.qeAPI.AddExtension(res, c.qeAPI.MulExtension(v[r], matrixVal))
return res
}
@@ -181,7 +180,7 @@ func (c *PoseidonChip) MdsRowShfExtension(r int, v [SPONGE_WIDTH]QuadraticExtens
func (c *PoseidonChip) MdsLayer(state_ PoseidonState) PoseidonState {
var result PoseidonState
for i := 0; i < SPONGE_WIDTH; i++ {
result[i] = NewFieldElement(0)
result[i] = field.NewFieldElement(0)
}
var state [SPONGE_WIDTH]frontend.Variable
@@ -193,7 +192,7 @@ func (c *PoseidonChip) MdsLayer(state_ PoseidonState) PoseidonState {
if r < SPONGE_WIDTH {
sum := c.MdsRowShf(r, state)
bits := c.api.ToBinary(sum)
result[r] = c.fieldAPI.FromBinary(bits).(F)
result[r] = c.fieldAPI.FromBinary(bits).(field.F)
}
}
@@ -216,7 +215,7 @@ func (c *PoseidonChip) MdsLayerExtension(state_ PoseidonStateExtension) Poseidon
func (c *PoseidonChip) PartialFirstConstantLayer(state PoseidonState) PoseidonState {
for i := 0; i < 12; i++ {
if i < SPONGE_WIDTH {
state[i] = c.fieldAPI.Add(state[i], NewFieldElement(FAST_PARTIAL_FIRST_ROUND_CONSTANT[i])).(F)
state[i] = c.fieldAPI.Add(state[i], field.NewFieldElement(FAST_PARTIAL_FIRST_ROUND_CONSTANT[i])).(field.F)
}
}
return state
@@ -225,7 +224,7 @@ func (c *PoseidonChip) PartialFirstConstantLayer(state PoseidonState) PoseidonSt
func (c *PoseidonChip) PartialFirstConstantLayerExtension(state PoseidonStateExtension) PoseidonStateExtension {
for i := 0; i < 12; i++ {
if i < SPONGE_WIDTH {
state[i] = c.qeAPI.AddExtension(state[i], c.qeAPI.FieldToQE(NewFieldElement(FAST_PARTIAL_FIRST_ROUND_CONSTANT[i])))
state[i] = c.qeAPI.AddExtension(state[i], c.qeAPI.FieldToQE(field.NewFieldElement(FAST_PARTIAL_FIRST_ROUND_CONSTANT[i])))
}
}
return state
@@ -234,7 +233,7 @@ func (c *PoseidonChip) PartialFirstConstantLayerExtension(state PoseidonStateExt
func (c *PoseidonChip) MdsPartialLayerInit(state PoseidonState) PoseidonState {
var result PoseidonState
for i := 0; i < 12; i++ {
result[i] = NewFieldElement(0)
result[i] = field.NewFieldElement(0)
}
result[0] = state[0]
@@ -243,8 +242,8 @@ func (c *PoseidonChip) MdsPartialLayerInit(state PoseidonState) PoseidonState {
if r < SPONGE_WIDTH {
for d := 1; d < 12; d++ {
if d < SPONGE_WIDTH {
t := NewFieldElement(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1])
result[d] = c.fieldAPI.Add(result[d], c.fieldAPI.Mul(state[r], t)).(F)
t := field.NewFieldElement(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1])
result[d] = c.fieldAPI.Add(result[d], c.fieldAPI.Mul(state[r], t)).(field.F)
}
}
}
@@ -256,7 +255,7 @@ func (c *PoseidonChip) MdsPartialLayerInit(state PoseidonState) PoseidonState {
func (c *PoseidonChip) MdsPartialLayerInitExtension(state PoseidonStateExtension) PoseidonStateExtension {
var result PoseidonStateExtension
for i := 0; i < 12; i++ {
result[i] = c.qeAPI.FieldToQE(NewFieldElement(0))
result[i] = c.qeAPI.FieldToQE(field.NewFieldElement(0))
}
result[0] = state[0]
@@ -265,7 +264,7 @@ func (c *PoseidonChip) MdsPartialLayerInitExtension(state PoseidonStateExtension
if r < SPONGE_WIDTH {
for d := 1; d < 12; d++ {
if d < SPONGE_WIDTH {
t := c.qeAPI.FieldToQE(NewFieldElement(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1]))
t := c.qeAPI.FieldToQE(field.NewFieldElement(FAST_PARTIAL_ROUND_INITIAL_MATRIX[r-1][d-1]))
result[d] = c.qeAPI.AddExtension(result[d], c.qeAPI.MulExtension(state[r], t))
}
}
@@ -292,15 +291,15 @@ func (c *PoseidonChip) MdsPartialLayerFast(state PoseidonState, r int) PoseidonS
var result PoseidonState
for i := 0; i < SPONGE_WIDTH; i++ {
result[i] = NewFieldElement(0)
result[i] = field.NewFieldElement(0)
}
result[0] = d.(F)
result[0] = d.(field.F)
for i := 1; i < 12; i++ {
if i < SPONGE_WIDTH {
t := NewFieldElement(FAST_PARTIAL_ROUND_VS[r][i-1])
result[i] = c.fieldAPI.Add(state[i], c.fieldAPI.Mul(state[0], t)).(F)
t := field.NewFieldElement(FAST_PARTIAL_ROUND_VS[r][i-1])
result[i] = c.fieldAPI.Add(state[i], c.fieldAPI.Mul(state[0], t)).(field.F)
}
}
@@ -309,11 +308,11 @@ func (c *PoseidonChip) MdsPartialLayerFast(state PoseidonState, r int) PoseidonS
func (c *PoseidonChip) MdsPartialLayerFastExtension(state PoseidonStateExtension, r int) PoseidonStateExtension {
s0 := state[0]
mds0to0 := c.qeAPI.FieldToQE(NewFieldElement(MDS_MATRIX_CIRC[0] + MDS_MATRIX_DIAG[0]))
mds0to0 := c.qeAPI.FieldToQE(field.NewFieldElement(MDS_MATRIX_CIRC[0] + MDS_MATRIX_DIAG[0]))
d := c.qeAPI.MulExtension(s0, mds0to0)
for i := 1; i < 12; i++ {
if i < SPONGE_WIDTH {
t := c.qeAPI.FieldToQE(NewFieldElement(FAST_PARTIAL_ROUND_W_HATS[r][i-1]))
t := c.qeAPI.FieldToQE(field.NewFieldElement(FAST_PARTIAL_ROUND_W_HATS[r][i-1]))
d = c.qeAPI.AddExtension(d, c.qeAPI.MulExtension(state[i], t))
}
}
@@ -322,7 +321,7 @@ func (c *PoseidonChip) MdsPartialLayerFastExtension(state PoseidonStateExtension
result[0] = d
for i := 1; i < 12; i++ {
if i < SPONGE_WIDTH {
t := c.qeAPI.FieldToQE(NewFieldElement(FAST_PARTIAL_ROUND_VS[r][i-1]))
t := c.qeAPI.FieldToQE(field.NewFieldElement(FAST_PARTIAL_ROUND_VS[r][i-1]))
result[i] = c.qeAPI.AddExtension(c.qeAPI.MulExtension(state[0], t), state[i])
}
}

View File

@@ -1,15 +1,14 @@
package poseidon
import (
"gnark-plonky2-verifier/field"
. "gnark-plonky2-verifier/field"
"gnark-plonky2-verifier/utils"
"testing"
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/frontend/cs/r1cs"
"github.com/consensys/gnark/test"
"github.com/succinctlabs/gnark-plonky2-verifier/field"
"github.com/succinctlabs/gnark-plonky2-verifier/utils"
)
type TestPoseidonCircuit struct {
@@ -19,11 +18,11 @@ type TestPoseidonCircuit struct {
func (circuit *TestPoseidonCircuit) Define(api frontend.API) error {
goldilocksApi := field.NewFieldAPI(api)
qeAPI := NewQuadraticExtensionAPI(goldilocksApi, 3)
qeAPI := field.NewQuadraticExtensionAPI(goldilocksApi, 3)
var input PoseidonState
for i := 0; i < 12; i++ {
input[i] = goldilocksApi.FromBinary(api.ToBinary(circuit.In[i], 64)).(F)
input[i] = goldilocksApi.FromBinary(api.ToBinary(circuit.In[i], 64)).(field.F)
}
poseidonChip := NewPoseidonChip(api, goldilocksApi, qeAPI)
@@ -32,7 +31,7 @@ func (circuit *TestPoseidonCircuit) Define(api frontend.API) error {
for i := 0; i < 12; i++ {
goldilocksApi.AssertIsEqual(
output[i],
goldilocksApi.FromBinary(api.ToBinary(circuit.Out[i])).(F),
goldilocksApi.FromBinary(api.ToBinary(circuit.Out[i])).(field.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, TEST_CURVE.ScalarField())
err := test.IsSolved(&circuit, &witness, field.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(TEST_CURVE.ScalarField(), r1cs.NewBuilder, &circuit)
r1cs, err := frontend.Compile(field.TEST_CURVE.ScalarField(), r1cs.NewBuilder, &circuit)
if err != nil {
panic(err)
}
witness, err := frontend.NewWitness(&assignment, TEST_CURVE.ScalarField())
witness, err := frontend.NewWitness(&assignment, field.TEST_CURVE.ScalarField())
if err != nil {
panic(err)
}
@@ -94,7 +93,7 @@ func TestPoseidonProof(t *testing.T) {
panic(err)
}
err = test.IsSolved(&circuit, &assignment, TEST_CURVE.ScalarField())
err = test.IsSolved(&circuit, &assignment, field.TEST_CURVE.ScalarField())
if err != nil {
panic(err)
}

View File

@@ -1,13 +1,13 @@
package poseidon
import (
. "gnark-plonky2-verifier/field"
"gnark-plonky2-verifier/utils"
"testing"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/test"
"github.com/succinctlabs/gnark-plonky2-verifier/field"
"github.com/succinctlabs/gnark-plonky2-verifier/utils"
)
var testCurve = ecc.BN254
@@ -18,12 +18,12 @@ type TestPublicInputsHashCircuit struct {
}
func (circuit *TestPublicInputsHashCircuit) Define(api frontend.API) error {
fieldAPI := NewFieldAPI(api)
fieldAPI := field.NewFieldAPI(api)
// BN254 -> Binary(64) -> F
var input [3]F
var input [3]field.F
for i := 0; i < 3; i++ {
input[i] = fieldAPI.FromBinary(api.ToBinary(circuit.In[i], 64)).(F)
input[i] = fieldAPI.FromBinary(api.ToBinary(circuit.In[i], 64)).(field.F)
}
poseidonChip := &PoseidonChip{api: api, fieldAPI: fieldAPI}
@@ -33,7 +33,7 @@ func (circuit *TestPublicInputsHashCircuit) Define(api frontend.API) error {
for i := 0; i < 4; i++ {
fieldAPI.AssertIsEqual(
output[i],
fieldAPI.FromBinary(api.ToBinary(circuit.Out[i])).(F),
fieldAPI.FromBinary(api.ToBinary(circuit.Out[i])).(field.F),
)
}