Browse Source

fixed some bugs

main
Kevin Jue 2 years ago
parent
commit
a16fe09634
2 changed files with 51 additions and 14 deletions
  1. +25
    -3
      plonky2_verifier/deserialize.go
  2. +26
    -11
      plonky2_verifier/fri.go

+ 25
- 3
plonky2_verifier/deserialize.go

@ -29,7 +29,7 @@ type ProofWithPublicInputsRaw struct {
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"`
@ -48,6 +48,23 @@ type ProofWithPublicInputsRaw struct {
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 {
leafElements []uint64
merkleProof MerkleProofRaw
@ -179,7 +196,7 @@ func DeserializeOpeningSet(openingSetRaw struct {
}
func DeserializeFriProof(openingProofRaw struct {
CommitPhaseMerkleCaps []interface{}
CommitPhaseMerkleCaps []MerkleCapsRaw
QueryRoundProofs []struct {
InitialTreesProof struct {
EvalsProofs []EvalProofRaw
@ -198,6 +215,11 @@ func DeserializeFriProof(openingProofRaw struct {
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 @@ func DeserializeProofWithPublicInputs(path string) ProofWithPublicInputs {
QuotientPolys [][]uint64
}(raw.Proof.Openings))
proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct {
CommitPhaseMerkleCaps []interface{}
CommitPhaseMerkleCaps []MerkleCapsRaw
QueryRoundProofs []struct {
InitialTreesProof struct {
EvalsProofs []EvalProofRaw

+ 26
- 11
plonky2_verifier/fri.go

@ -336,6 +336,9 @@ func (f *FriChip) computeEvaluation(
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 @@ func (f *FriChip) computeEvaluation(
// 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 @@ func (f *FriChip) computeEvaluation(
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 @@ func (f *FriChip) verifyQueryRound(
// 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 @@ func (f *FriChip) verifyQueryRound(
)
// 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 @@ func (f *FriChip) verifyQueryRound(
xIndexBits = cosetIndexBits
}
subgroupX_QE = f.qeAPI.FieldToQE(subgroupX)
finalPolyEval := f.finalPolyEval(proof.FinalPoly, subgroupX_QE)
f.qeAPI.AssertIsEqual(oldEval, finalPolyEval)

Loading…
Cancel
Save