mirror of
https://github.com/arnaucube/gnark-plonky2-verifier.git
synced 2026-01-12 09:01:32 +01:00
fixed some bugs
This commit is contained in:
@@ -29,7 +29,7 @@ type ProofWithPublicInputsRaw struct {
|
|||||||
QuotientPolys [][]uint64 `json:"quotient_polys"`
|
QuotientPolys [][]uint64 `json:"quotient_polys"`
|
||||||
} `json:"openings"`
|
} `json:"openings"`
|
||||||
OpeningProof struct {
|
OpeningProof struct {
|
||||||
CommitPhaseMerkleCaps []interface{} `json:"commit_phase_merkle_caps"`
|
CommitPhaseMerkleCaps []MerkleCapsRaw `json:"commit_phase_merkle_caps"`
|
||||||
QueryRoundProofs []struct {
|
QueryRoundProofs []struct {
|
||||||
InitialTreesProof struct {
|
InitialTreesProof struct {
|
||||||
EvalsProofs []EvalProofRaw `json:"evals_proofs"`
|
EvalsProofs []EvalProofRaw `json:"evals_proofs"`
|
||||||
@@ -48,6 +48,23 @@ type ProofWithPublicInputsRaw struct {
|
|||||||
PublicInputs []uint64 `json:"public_inputs"`
|
PublicInputs []uint64 `json:"public_inputs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MerkleCapsRaw struct {
|
||||||
|
hashes [][]uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MerkleCapsRaw) UnmarshalJSON(data []byte) error {
|
||||||
|
var merkleCaps []map[string][]uint64
|
||||||
|
if err := json.Unmarshal(data, &merkleCaps); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.hashes = make([][]uint64, len(merkleCaps))
|
||||||
|
for i := 0; i < len(merkleCaps); i++ {
|
||||||
|
m.hashes[i] = merkleCaps[i]["elements"]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type EvalProofRaw struct {
|
type EvalProofRaw struct {
|
||||||
leafElements []uint64
|
leafElements []uint64
|
||||||
merkleProof MerkleProofRaw
|
merkleProof MerkleProofRaw
|
||||||
@@ -179,7 +196,7 @@ func DeserializeOpeningSet(openingSetRaw struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DeserializeFriProof(openingProofRaw struct {
|
func DeserializeFriProof(openingProofRaw struct {
|
||||||
CommitPhaseMerkleCaps []interface{}
|
CommitPhaseMerkleCaps []MerkleCapsRaw
|
||||||
QueryRoundProofs []struct {
|
QueryRoundProofs []struct {
|
||||||
InitialTreesProof struct {
|
InitialTreesProof struct {
|
||||||
EvalsProofs []EvalProofRaw
|
EvalsProofs []EvalProofRaw
|
||||||
@@ -198,6 +215,11 @@ func DeserializeFriProof(openingProofRaw struct {
|
|||||||
openingProof.PowWitness = NewFieldElement(openingProofRaw.PowWitness)
|
openingProof.PowWitness = NewFieldElement(openingProofRaw.PowWitness)
|
||||||
openingProof.FinalPoly.Coeffs = utils.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs)
|
openingProof.FinalPoly.Coeffs = utils.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs)
|
||||||
|
|
||||||
|
openingProof.CommitPhaseMerkleCaps = make([]MerkleCap, len(openingProofRaw.CommitPhaseMerkleCaps))
|
||||||
|
for i := 0; i < len(openingProofRaw.CommitPhaseMerkleCaps); i++ {
|
||||||
|
openingProof.CommitPhaseMerkleCaps[i] = utils.Uint64ArrayToHashArray(openingProofRaw.CommitPhaseMerkleCaps[i].hashes)
|
||||||
|
}
|
||||||
|
|
||||||
numQueryRoundProofs := len(openingProofRaw.QueryRoundProofs)
|
numQueryRoundProofs := len(openingProofRaw.QueryRoundProofs)
|
||||||
openingProof.QueryRoundProofs = make([]FriQueryRound, numQueryRoundProofs)
|
openingProof.QueryRoundProofs = make([]FriQueryRound, numQueryRoundProofs)
|
||||||
|
|
||||||
@@ -249,7 +271,7 @@ func DeserializeProofWithPublicInputs(path string) ProofWithPublicInputs {
|
|||||||
QuotientPolys [][]uint64
|
QuotientPolys [][]uint64
|
||||||
}(raw.Proof.Openings))
|
}(raw.Proof.Openings))
|
||||||
proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct {
|
proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct {
|
||||||
CommitPhaseMerkleCaps []interface{}
|
CommitPhaseMerkleCaps []MerkleCapsRaw
|
||||||
QueryRoundProofs []struct {
|
QueryRoundProofs []struct {
|
||||||
InitialTreesProof struct {
|
InitialTreesProof struct {
|
||||||
EvalsProofs []EvalProofRaw
|
EvalsProofs []EvalProofRaw
|
||||||
|
|||||||
@@ -336,6 +336,9 @@ func (f *FriChip) computeEvaluation(
|
|||||||
if (len(evals)) != arity {
|
if (len(evals)) != arity {
|
||||||
panic("len(evals) ! arity")
|
panic("len(evals) ! arity")
|
||||||
}
|
}
|
||||||
|
if arityBits > 8 {
|
||||||
|
panic("currently assuming that arityBits is <= 8")
|
||||||
|
}
|
||||||
|
|
||||||
g := field.GoldilocksPrimitiveRootOfUnity(arityBits)
|
g := field.GoldilocksPrimitiveRootOfUnity(arityBits)
|
||||||
gInv := goldilocks.NewElement(0)
|
gInv := goldilocks.NewElement(0)
|
||||||
@@ -346,10 +349,8 @@ func (f *FriChip) computeEvaluation(
|
|||||||
// TODO: Optimization - Since the size of the evals array should be constant (e.g. 2^arityBits),
|
// TODO: Optimization - Since the size of the evals array should be constant (e.g. 2^arityBits),
|
||||||
// we can just hard code the permutation.
|
// we can just hard code the permutation.
|
||||||
permutedEvals := make([]QuadraticExtension, len(evals))
|
permutedEvals := make([]QuadraticExtension, len(evals))
|
||||||
for i := uint(0); i < uint(len(evals)); i++ {
|
for i := uint8(0); i < uint8(len(evals)); i++ {
|
||||||
bitLen := bits.Len(i)
|
newIndex := bits.Reverse8(i) >> arityBits
|
||||||
rightPadLen := arityBits - uint64(bitLen)
|
|
||||||
newIndex := bits.Reverse(i) << rightPadLen
|
|
||||||
permutedEvals[newIndex] = evals[i]
|
permutedEvals[newIndex] = evals[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,10 +367,10 @@ func (f *FriChip) computeEvaluation(
|
|||||||
yPoints := permutedEvals
|
yPoints := permutedEvals
|
||||||
|
|
||||||
// TODO: Make g_F a constant
|
// TODO: Make g_F a constant
|
||||||
g_F := NewFieldElement(g.Uint64())
|
g_F := f.qeAPI.FieldToQE(NewFieldElement(g.Uint64()))
|
||||||
xPoints[0] = f.qeAPI.FieldToQE(cosetStart)
|
xPoints[0] = f.qeAPI.FieldToQE(cosetStart)
|
||||||
for i := 1; i < len(evals); i++ {
|
for i := 1; i < len(evals); i++ {
|
||||||
xPoints[i] = f.qeAPI.FieldToQE(f.fieldAPI.Mul(xPoints[i-1], g_F).(F))
|
xPoints[i] = f.qeAPI.MulExtension(xPoints[i-1], g_F)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This is n^2. Is there a way to do this better?
|
// TODO: This is n^2. Is there a way to do this better?
|
||||||
@@ -445,13 +446,25 @@ func (f *FriChip) verifyQueryRound(
|
|||||||
// The will use the least significant bits of the xIndexWithCosetBits array
|
// The will use the least significant bits of the xIndexWithCosetBits array
|
||||||
for i := 0; i < NUM_LEAF_LOOKUPS; i++ {
|
for i := 0; i < NUM_LEAF_LOOKUPS; i++ {
|
||||||
leafLookups[i] = f.qeAPI.Lookup2(
|
leafLookups[i] = f.qeAPI.Lookup2(
|
||||||
xIndexWithinCosetBits[0], xIndexWithinCosetBits[1],
|
xIndexWithinCosetBits[0],
|
||||||
evals[i*NUM_LEAF_LOOKUPS], evals[i*NUM_LEAF_LOOKUPS+1], evals[i*NUM_LEAF_LOOKUPS+2], evals[i*NUM_LEAF_LOOKUPS+3],
|
xIndexWithinCosetBits[1],
|
||||||
|
evals[i*NUM_LEAF_LOOKUPS],
|
||||||
|
evals[i*NUM_LEAF_LOOKUPS+1],
|
||||||
|
evals[i*NUM_LEAF_LOOKUPS+2],
|
||||||
|
evals[i*NUM_LEAF_LOOKUPS+3],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the most 2 significant bits of the xIndexWithCosetBits array for the "root" lookup
|
// Use the most 2 significant bits of the xIndexWithCosetBits array for the "root" lookup
|
||||||
newEval := f.qeAPI.Lookup2(xIndexWithinCosetBits[2], xIndexWithinCosetBits[3], evals[0], evals[1], evals[2], evals[3])
|
newEval := f.qeAPI.Lookup2(
|
||||||
|
xIndexWithinCosetBits[2],
|
||||||
|
xIndexWithinCosetBits[3],
|
||||||
|
leafLookups[0],
|
||||||
|
leafLookups[1],
|
||||||
|
leafLookups[2],
|
||||||
|
leafLookups[3],
|
||||||
|
)
|
||||||
|
|
||||||
f.qeAPI.AssertIsEqual(newEval, oldEval)
|
f.qeAPI.AssertIsEqual(newEval, oldEval)
|
||||||
|
|
||||||
oldEval = f.computeEvaluation(
|
oldEval = f.computeEvaluation(
|
||||||
@@ -463,9 +476,10 @@ func (f *FriChip) verifyQueryRound(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Convert evals (array of QE) to fields by taking their 0th degree coefficients
|
// Convert evals (array of QE) to fields by taking their 0th degree coefficients
|
||||||
fieldEvals := make([]F, len(evals))
|
fieldEvals := make([]F, 0, 2*len(evals))
|
||||||
for j := 0; j < len(evals); j++ {
|
for j := 0; j < len(evals); j++ {
|
||||||
fieldEvals[j] = evals[j][0]
|
fieldEvals = append(fieldEvals, evals[j][0])
|
||||||
|
fieldEvals = append(fieldEvals, evals[j][1])
|
||||||
}
|
}
|
||||||
f.verifyMerkleProofToCapWithCapIndex(
|
f.verifyMerkleProofToCapWithCapIndex(
|
||||||
fieldEvals,
|
fieldEvals,
|
||||||
@@ -483,6 +497,7 @@ func (f *FriChip) verifyQueryRound(
|
|||||||
xIndexBits = cosetIndexBits
|
xIndexBits = cosetIndexBits
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subgroupX_QE = f.qeAPI.FieldToQE(subgroupX)
|
||||||
finalPolyEval := f.finalPolyEval(proof.FinalPoly, subgroupX_QE)
|
finalPolyEval := f.finalPolyEval(proof.FinalPoly, subgroupX_QE)
|
||||||
|
|
||||||
f.qeAPI.AssertIsEqual(oldEval, finalPolyEval)
|
f.qeAPI.AssertIsEqual(oldEval, finalPolyEval)
|
||||||
|
|||||||
Reference in New Issue
Block a user