mirror of
https://github.com/arnaucube/gnark-plonky2-verifier.git
synced 2026-01-12 09:01:32 +01:00
correctly deserialize fri opening proofs
This commit is contained in:
@@ -32,7 +32,7 @@ type ProofWithPublicInputsRaw struct {
|
|||||||
CommitPhaseMerkleCaps []interface{} `json:"commit_phase_merkle_caps"`
|
CommitPhaseMerkleCaps []interface{} `json:"commit_phase_merkle_caps"`
|
||||||
QueryRoundProofs []struct {
|
QueryRoundProofs []struct {
|
||||||
InitialTreesProof struct {
|
InitialTreesProof struct {
|
||||||
EvalsProofs [][]interface{} `json:"evals_proofs"`
|
EvalsProofs []EvalProofRaw `json:"evals_proofs"`
|
||||||
} `json:"initial_trees_proof"`
|
} `json:"initial_trees_proof"`
|
||||||
Steps []interface{} `json:"steps"`
|
Steps []interface{} `json:"steps"`
|
||||||
} `json:"query_round_proofs"`
|
} `json:"query_round_proofs"`
|
||||||
@@ -45,6 +45,38 @@ type ProofWithPublicInputsRaw struct {
|
|||||||
PublicInputs []uint64 `json:"public_inputs"`
|
PublicInputs []uint64 `json:"public_inputs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EvalProofRaw struct {
|
||||||
|
leafElements []uint64
|
||||||
|
merkleProof MerkleProofRaw
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EvalProofRaw) UnmarshalJSON(data []byte) error {
|
||||||
|
return json.Unmarshal(data, &[]interface{}{&e.leafElements, &e.merkleProof})
|
||||||
|
}
|
||||||
|
|
||||||
|
type MerkleProofRaw struct {
|
||||||
|
hash [][]uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MerkleProofRaw) UnmarshalJSON(data []byte) error {
|
||||||
|
var siblingDict map[string]interface{}
|
||||||
|
if err := json.Unmarshal(data, &siblingDict); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
siblings := siblingDict["siblings"].([]interface{})
|
||||||
|
m.hash = make([][]uint64, len(siblings))
|
||||||
|
for siblingIdx, sibling := range siblings {
|
||||||
|
siblingHash := sibling.(map[string]interface{})["elements"].([]interface{})
|
||||||
|
m.hash[siblingIdx] = make([]uint64, 4)
|
||||||
|
for siblingElementIdx, siblingElement := range siblingHash {
|
||||||
|
m.hash[siblingIdx][siblingElementIdx] = uint64(siblingElement.(float64))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type CommonCircuitDataRaw struct {
|
type CommonCircuitDataRaw struct {
|
||||||
Config struct {
|
Config struct {
|
||||||
NumWires uint64 `json:"num_wires"`
|
NumWires uint64 `json:"num_wires"`
|
||||||
@@ -113,6 +145,17 @@ func DeserializeMerkleCap(merkleCapRaw []struct{ Elements []uint64 }) MerkleCap
|
|||||||
return merkleCap
|
return merkleCap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeserializeMerkleProof(merkleProofRaw struct{ Siblings []interface{} }) MerkleProof {
|
||||||
|
n := len(merkleProofRaw.Siblings)
|
||||||
|
var mp MerkleProof
|
||||||
|
mp.Siblings = make([]Hash, n)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
element := merkleProofRaw.Siblings[i].(struct{ Elements []uint64 })
|
||||||
|
copy(mp.Siblings[i][:], utils.Uint64ArrayToFArray(element.Elements))
|
||||||
|
}
|
||||||
|
return mp
|
||||||
|
}
|
||||||
|
|
||||||
func DeserializeOpeningSet(openingSetRaw struct {
|
func DeserializeOpeningSet(openingSetRaw struct {
|
||||||
Constants [][]uint64
|
Constants [][]uint64
|
||||||
PlonkSigmas [][]uint64
|
PlonkSigmas [][]uint64
|
||||||
@@ -137,7 +180,7 @@ func DeserializeFriProof(openingProofRaw struct {
|
|||||||
CommitPhaseMerkleCaps []interface{}
|
CommitPhaseMerkleCaps []interface{}
|
||||||
QueryRoundProofs []struct {
|
QueryRoundProofs []struct {
|
||||||
InitialTreesProof struct {
|
InitialTreesProof struct {
|
||||||
EvalsProofs [][]interface{}
|
EvalsProofs []EvalProofRaw
|
||||||
}
|
}
|
||||||
Steps []interface{}
|
Steps []interface{}
|
||||||
}
|
}
|
||||||
@@ -149,6 +192,19 @@ func DeserializeFriProof(openingProofRaw struct {
|
|||||||
var openingProof FriProof
|
var openingProof FriProof
|
||||||
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)
|
||||||
|
|
||||||
|
numQueryRoundProofs := len(openingProofRaw.QueryRoundProofs)
|
||||||
|
openingProof.QueryRoundProofs = make([]FriQueryRound, numQueryRoundProofs)
|
||||||
|
|
||||||
|
for i := 0; i < numQueryRoundProofs; i++ {
|
||||||
|
numEvalProofs := len(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs)
|
||||||
|
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs = make([]EvalProof, numEvalProofs)
|
||||||
|
for j := 0; j < numEvalProofs; j++ {
|
||||||
|
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].Elements = utils.Uint64ArrayToFArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].leafElements)
|
||||||
|
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Siblings = utils.Uint64ArrayToHashArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].merkleProof.hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return openingProof
|
return openingProof
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,8 +239,10 @@ func DeserializeProofWithPublicInputs(path string) ProofWithPublicInputs {
|
|||||||
proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct {
|
proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct {
|
||||||
CommitPhaseMerkleCaps []interface{}
|
CommitPhaseMerkleCaps []interface{}
|
||||||
QueryRoundProofs []struct {
|
QueryRoundProofs []struct {
|
||||||
InitialTreesProof struct{ EvalsProofs [][]interface{} }
|
InitialTreesProof struct {
|
||||||
Steps []interface{}
|
EvalsProofs []EvalProofRaw
|
||||||
|
}
|
||||||
|
Steps []interface{}
|
||||||
}
|
}
|
||||||
FinalPoly struct{ Coeffs [][]uint64 }
|
FinalPoly struct{ Coeffs [][]uint64 }
|
||||||
PowWitness uint64
|
PowWitness uint64
|
||||||
@@ -224,7 +282,8 @@ func DeserializeCommonCircuitData(path string) CommonCircuitData {
|
|||||||
commonCircuitData.Config.FriConfig.ProofOfWorkBits = raw.Config.FriConfig.ProofOfWorkBits
|
commonCircuitData.Config.FriConfig.ProofOfWorkBits = raw.Config.FriConfig.ProofOfWorkBits
|
||||||
commonCircuitData.Config.FriConfig.NumQueryRounds = raw.Config.FriConfig.NumQueryRounds
|
commonCircuitData.Config.FriConfig.NumQueryRounds = raw.Config.FriConfig.NumQueryRounds
|
||||||
|
|
||||||
commonCircuitData.FriParams.Config.CapHeight = raw.FriParams.Config.CapHeight
|
commonCircuitData.FriParams.DegreeBits = raw.FriParams.DegreeBits
|
||||||
|
commonCircuitData.FriParams.Config.RateBits = raw.FriParams.Config.RateBits
|
||||||
commonCircuitData.FriParams.Config.CapHeight = raw.FriParams.Config.CapHeight
|
commonCircuitData.FriParams.Config.CapHeight = raw.FriParams.Config.CapHeight
|
||||||
commonCircuitData.FriParams.Config.ProofOfWorkBits = raw.FriParams.Config.ProofOfWorkBits
|
commonCircuitData.FriParams.Config.ProofOfWorkBits = raw.FriParams.Config.ProofOfWorkBits
|
||||||
commonCircuitData.FriParams.Config.NumQueryRounds = raw.FriParams.Config.NumQueryRounds
|
commonCircuitData.FriParams.Config.NumQueryRounds = raw.FriParams.Config.NumQueryRounds
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package plonky2_verifier
|
package plonky2_verifier
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"gnark-ed25519/field"
|
"gnark-ed25519/field"
|
||||||
. "gnark-ed25519/field"
|
. "gnark-ed25519/field"
|
||||||
"gnark-ed25519/poseidon"
|
"gnark-ed25519/poseidon"
|
||||||
@@ -155,7 +156,9 @@ func (f *FriChip) assertNoncanonicalIndicesOK() {
|
|||||||
numAmbiguousElems := uint64(math.MaxUint64) - EmulatedFieldModulus().Uint64() + 1
|
numAmbiguousElems := uint64(math.MaxUint64) - EmulatedFieldModulus().Uint64() + 1
|
||||||
queryError := f.friParams.Config.rate()
|
queryError := f.friParams.Config.rate()
|
||||||
pAmbiguous := float64(numAmbiguousElems) / float64(EmulatedFieldModulus().Uint64())
|
pAmbiguous := float64(numAmbiguousElems) / float64(EmulatedFieldModulus().Uint64())
|
||||||
if pAmbiguous < queryError*1e-5 {
|
|
||||||
|
// TODO: Check that pAmbiguous value is the same as the one in plonky2 verifier
|
||||||
|
if pAmbiguous >= queryError*1e-5 {
|
||||||
panic("A non-negligible portion of field elements are in the range that permits non-canonical encodings. Need to do more analysis or enforce canonical encodings.")
|
panic("A non-negligible portion of field elements are in the range that permits non-canonical encodings. Need to do more analysis or enforce canonical encodings.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,12 +170,11 @@ func (f *FriChip) verifyQueryRound(
|
|||||||
proof *FriProof,
|
proof *FriProof,
|
||||||
xIndex F,
|
xIndex F,
|
||||||
n uint64,
|
n uint64,
|
||||||
|
nLog uint64,
|
||||||
roundProof *FriQueryRound,
|
roundProof *FriQueryRound,
|
||||||
) {
|
) {
|
||||||
nLog := log2Strict(uint(n))
|
|
||||||
|
|
||||||
f.assertNoncanonicalIndicesOK()
|
f.assertNoncanonicalIndicesOK()
|
||||||
xIndexBits := f.qe.field.ToBinary(xIndex, nLog)
|
xIndexBits := f.qe.field.ToBinary(xIndex, int(nLog))
|
||||||
capIndex := f.qe.field.FromBinary(xIndexBits[len(xIndexBits)-int(f.friParams.Config.CapHeight):]...).(F)
|
capIndex := f.qe.field.FromBinary(xIndexBits[len(xIndexBits)-int(f.friParams.Config.CapHeight):]...).(F)
|
||||||
|
|
||||||
f.verifyInitialProof(xIndexBits, &roundProof.InitialTreesProof, initialMerkleCaps, capIndex)
|
f.verifyInitialProof(xIndexBits, &roundProof.InitialTreesProof, initialMerkleCaps, capIndex)
|
||||||
@@ -201,10 +203,15 @@ func (f *FriChip) VerifyFriProof(
|
|||||||
precomputedReducedEvals := f.fromOpeningsAndAlpha(&openings, friChallenges.FriAlpha)
|
precomputedReducedEvals := f.fromOpeningsAndAlpha(&openings, friChallenges.FriAlpha)
|
||||||
|
|
||||||
// Size of the LDE domain.
|
// Size of the LDE domain.
|
||||||
n := uint64(math.Pow(2, float64(f.friParams.DegreeBits+f.friParams.Config.RateBits)))
|
nLog := f.friParams.DegreeBits + f.friParams.Config.RateBits
|
||||||
|
n := uint64(math.Pow(2, float64(nLog)))
|
||||||
|
|
||||||
if len(friChallenges.FriQueryIndicies) != len(precomputedReducedEvals) {
|
if len(friChallenges.FriQueryIndicies) != len(friProof.QueryRoundProofs) {
|
||||||
panic("Number of queryRoundProofs should equal number of precomputedReducedEvals")
|
panic(fmt.Sprintf(
|
||||||
|
"Number of query indices (%d) should equal number of query round proofs (%d)",
|
||||||
|
len(friChallenges.FriQueryIndicies),
|
||||||
|
len(friProof.QueryRoundProofs),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
for idx, xIndex := range friChallenges.FriQueryIndicies {
|
for idx, xIndex := range friChallenges.FriQueryIndicies {
|
||||||
@@ -217,6 +224,7 @@ func (f *FriChip) VerifyFriProof(
|
|||||||
friProof,
|
friProof,
|
||||||
xIndex,
|
xIndex,
|
||||||
n,
|
n,
|
||||||
|
nLog,
|
||||||
&roundProof,
|
&roundProof,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,3 +40,11 @@ func Uint64ArrayToQuadraticExtensionArray(input [][]uint64) []QuadraticExtension
|
|||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Uint64ArrayToHashArray(input [][]uint64) []Hash {
|
||||||
|
var output []Hash
|
||||||
|
for i := 0; i < len(input); i++ {
|
||||||
|
output = append(output, [4]F{NewFieldElement(input[i][0]), NewFieldElement(input[i][1]), NewFieldElement(input[i][2]), NewFieldElement(input[i][3])})
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user