fixed some bugs
Kevin Jue kjue235@gmail.com
Tue, 15 Nov 2022 17:50:45 -0800
2 files changed,
51 insertions(+),
14 deletions(-)
M
plonky2_verifier/deserialize.go
→
plonky2_verifier/deserialize.go
@@ -29,7 +29,7 @@ PartialProducts [][]uint64 `json:"partial_products"`
QuotientPolys [][]uint64 `json:"quotient_polys"` } `json:"openings"` OpeningProof struct { - CommitPhaseMerkleCaps []interface{} `json:"commit_phase_merkle_caps"` + CommitPhaseMerkleCaps []MerkleCapsRaw `json:"commit_phase_merkle_caps"` QueryRoundProofs []struct { InitialTreesProof struct { EvalsProofs []EvalProofRaw `json:"evals_proofs"`@@ -46,6 +46,23 @@ PowWitness uint64 `json:"pow_witness"`
} `json:"opening_proof"` } `json:"proof"` 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 {@@ -179,7 +196,7 @@ }
} func DeserializeFriProof(openingProofRaw struct { - CommitPhaseMerkleCaps []interface{} + CommitPhaseMerkleCaps []MerkleCapsRaw QueryRoundProofs []struct { InitialTreesProof struct { EvalsProofs []EvalProofRaw@@ -197,6 +214,11 @@ }) FriProof {
var openingProof FriProof openingProof.PowWitness = NewFieldElement(openingProofRaw.PowWitness) 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) openingProof.QueryRoundProofs = make([]FriQueryRound, numQueryRoundProofs)@@ -249,7 +271,7 @@ PartialProducts [][]uint64
QuotientPolys [][]uint64 }(raw.Proof.Openings)) proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct { - CommitPhaseMerkleCaps []interface{} + CommitPhaseMerkleCaps []MerkleCapsRaw QueryRoundProofs []struct { InitialTreesProof struct { EvalsProofs []EvalProofRaw
M
plonky2_verifier/fri.go
→
plonky2_verifier/fri.go
@@ -336,6 +336,9 @@ arity := 1 << arityBits
if (len(evals)) != arity { panic("len(evals) ! arity") } + if arityBits > 8 { + panic("currently assuming that arityBits is <= 8") + } g := field.GoldilocksPrimitiveRootOfUnity(arityBits) gInv := goldilocks.NewElement(0)@@ -346,10 +349,8 @@ // element's new index is the bit reverse of it's original index.
// TODO: Optimization - Since the size of the evals array should be constant (e.g. 2^arityBits), // we can just hard code the permutation. permutedEvals := make([]QuadraticExtension, len(evals)) - for i := uint(0); i < uint(len(evals)); i++ { - bitLen := bits.Len(i) - rightPadLen := arityBits - uint64(bitLen) - newIndex := bits.Reverse(i) << rightPadLen + for i := uint8(0); i < uint8(len(evals)); i++ { + newIndex := bits.Reverse8(i) >> arityBits permutedEvals[newIndex] = evals[i] }@@ -366,10 +367,10 @@ xPoints := make([]QuadraticExtension, len(evals))
yPoints := permutedEvals // 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) 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?@@ -445,13 +446,25 @@ // First create the "leaf" lookup2 circuits
// The will use the least significant bits of the xIndexWithCosetBits array for i := 0; i < NUM_LEAF_LOOKUPS; i++ { leafLookups[i] = f.qeAPI.Lookup2( - xIndexWithinCosetBits[0], 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], + xIndexWithinCosetBits[0], + 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 - 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) oldEval = f.computeEvaluation(@@ -463,9 +476,10 @@ challenges.FriBetas[i],
) // 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++ { - fieldEvals[j] = evals[j][0] + fieldEvals = append(fieldEvals, evals[j][0]) + fieldEvals = append(fieldEvals, evals[j][1]) } f.verifyMerkleProofToCapWithCapIndex( fieldEvals,@@ -483,6 +497,7 @@
xIndexBits = cosetIndexBits } + subgroupX_QE = f.qeAPI.FieldToQE(subgroupX) finalPolyEval := f.finalPolyEval(proof.FinalPoly, subgroupX_QE) f.qeAPI.AssertIsEqual(oldEval, finalPolyEval)