Files
arbo/gnark.go
Lucas Menéndez 84e7901031 feature: multiple big int keys and multi values support (#35)
Support to work with BigInts 

---------

Co-authored-by: Guido Iribarren <git@guidoi.com.ar>
2025-04-14 10:56:42 +02:00

71 lines
2.1 KiB
Go

package arbo
import "math/big"
// GnarkVerifierProof is a struct that contains all the information needed to
// verify a proof in a gnark circuit. The attributes are all big.Int, so they
// can be used as frontend.Variable's in the gnark circuit. The endianess of
// root, siblings and value has been changed to Little-Endian to match the
// gnark arbo verifier.
type GnarkVerifierProof struct {
Root *big.Int
Siblings []*big.Int
OldKey *big.Int
IsOld0 *big.Int
OldValue *big.Int
Key *big.Int
Value *big.Int
Fnc *big.Int
}
// GenerateGnarkVerifierProof generates a GnarkVerifierProof for a given key
// in the Tree. Every attribute is a big.Int, so it can be used in the gnark
// circuit as frontend.Variable's. The endianess of root, siblings and value
// has been changed to Little-Endian to match the gnark arbo verifier.
func (t *Tree) GenerateGnarkVerifierProof(k []byte) (*GnarkVerifierProof, error) {
// generate the arbo proof
oldKey, value, siblings, existence, err := t.GenProof(k)
if err != nil && err != ErrKeyNotFound {
return nil, err
}
// get the root of the tree
root, err := t.Root()
if err != nil {
return nil, err
}
// unpack the siblings
unpackedSiblings, err := UnpackSiblings(t.hashFunction, siblings)
if err != nil {
return nil, err
}
// convert the siblings to big.Int swapping the endianess
bigSiblings := make([]*big.Int, len(unpackedSiblings))
for i := range bigSiblings {
bigSiblings[i] = BytesToBigInt(unpackedSiblings[i])
}
// initialize the GnarkVerifierProof
gp := GnarkVerifierProof{
Root: BytesToBigInt(root),
Key: BytesToBigInt(k),
Value: BytesToBigInt(value),
Siblings: bigSiblings,
OldKey: big.NewInt(0),
OldValue: big.NewInt(0),
IsOld0: big.NewInt(0),
Fnc: big.NewInt(0), // inclusion
}
// if the arbo proof is for a non-existing key, set the old key and value
// to the key and value of the proof
if !existence {
gp.OldKey = BytesToBigInt(oldKey)
gp.OldValue = BytesToBigInt(value)
gp.Fnc = big.NewInt(1) // exclusion
}
// set the IsOld0 attribute to 1 if there is no old key
if len(oldKey) == 0 {
gp.IsOld0 = big.NewInt(1)
}
return &gp, nil
}