Replies: 3 comments 3 replies
-
I think you can finish the above 2 task at once, please check https://github.com/lightec-xyz/gnark/blob/feat/vkey_fp/std/recursion/plonk/verifier.go. // FingerPrint() returns the MiMc hash of the VerifyingKey. It could be used to identify a VerifyingKey
// during recursive verification.
func (vk *VerifyingKey[FR, G1El, G2El]) FingerPrint(api frontend.API) (frontend.Variable, error) {
var ret frontend.Variable
mimc, err := mimc.NewMiMC(api)
if err != nil {
return ret, err
}
mimc.Write(vk.BaseVerifyingKey.NbPublicVariables)
mimc.Write(vk.CircuitVerifyingKey.Size)
mimc.Write(vk.CircuitVerifyingKey.Generator.Limbs[:]...)
comms := make([]kzg.Commitment[G1El], 0)
comms = append(comms, vk.CircuitVerifyingKey.S[:]...)
comms = append(comms, vk.CircuitVerifyingKey.Ql)
comms = append(comms, vk.CircuitVerifyingKey.Qr)
comms = append(comms, vk.CircuitVerifyingKey.Qm)
comms = append(comms, vk.CircuitVerifyingKey.Qo)
comms = append(comms, vk.CircuitVerifyingKey.Qk)
comms = append(comms, vk.CircuitVerifyingKey.Qcp[:]...)
for _, comm := range comms {
el := comm.G1El
switch r := any(&el).(type) {
case *sw_bls12377.G1Affine:
mimc.Write(r.X)
mimc.Write(r.Y)
case *sw_bls12381.G1Affine:
mimc.Write(r.X.Limbs[:]...)
mimc.Write(r.Y.Limbs[:]...)
case *sw_bls24315.G1Affine:
mimc.Write(r.X)
mimc.Write(r.Y)
case *sw_bw6761.G1Affine:
mimc.Write(r.X.Limbs[:]...)
mimc.Write(r.Y.Limbs[:]...)
case *sw_bn254.G1Affine:
mimc.Write(r.X.Limbs[:]...)
mimc.Write(r.Y.Limbs[:]...)
default:
return ret, fmt.Errorf("unknown parametric type")
}
}
mimc.Write(vk.CircuitVerifyingKey.CommitmentConstraintIndexes[:]...)
result := mimc.Sum()
return result, nil
} |
Beta Was this translation helpful? Give feedback.
-
In principle the above approach works - you just have to keep in mind that when computing the witness that you use the same representation for hashing, i.e. you have to split the coordinates at 64-bit intervals. We have some helper tools which do this automatically, see https://pkg.go.dev/github.com/consensys/gnark@v0.10.0/std/recursion and the corresponding test file https://github.com/Consensys/gnark/blob/master/std/recursion/wrapped_hash_test.go. This wrapper is not very efficient though - we work with binary decomposition of non-native elements to map into native field for hashing and binary decomposition is slow. We're planning to migrate to the approach where we hash the limbs directly, but this requires also changes in gnark-crypto. |
Beta Was this translation helpful? Give feedback.
-
Converted to discussion as seems to be question about gnark usage, not an issue. |
Beta Was this translation helpful? Give feedback.
-
Starting from the
recursion/groth16
example onpkg.go.dev
I am trying to build a recursive 2-chain where the outer circuit verifies a signature on the inner proof system'sVerifyingKey
(among other things).I have two questions on this:
vk
of typerec_groth16.VerifyingKey[G1El, G2El, GtEl]
to sign over in the actual signing function?Define
method manipulateInnerVerKey
to get a message of valid type foreddsa.Verify
?Beta Was this translation helpful? Give feedback.
All reactions