Files
arbo/circomproofs.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

92 lines
2.3 KiB
Go

package arbo
import (
"encoding/json"
)
// CircomVerifierProof contains the needed data to check a Circom Verifier Proof
// inside a circom circuit. CircomVerifierProof allow to verify through a
// zkSNARK proof the inclusion/exclusion of a leaf in a tree.
type CircomVerifierProof struct {
Root []byte `json:"root"`
Siblings [][]byte `json:"siblings"`
OldKey []byte `json:"oldKey"`
OldValue []byte `json:"oldValue"`
IsOld0 bool `json:"isOld0"`
Key []byte `json:"key"`
Value []byte `json:"value"`
Fnc int `json:"fnc"` // 0: inclusion, 1: non inclusion
}
// MarshalJSON implements the JSON marshaler
func (cvp CircomVerifierProof) MarshalJSON() ([]byte, error) {
m := make(map[string]any)
m["root"] = BytesToBigInt(cvp.Root).String()
m["siblings"] = siblingsToStringArray(cvp.Siblings)
m["oldKey"] = BytesToBigInt(cvp.OldKey).String()
m["oldValue"] = BytesToBigInt(cvp.OldValue).String()
if cvp.IsOld0 {
m["isOld0"] = "1"
} else {
m["isOld0"] = "0"
}
m["key"] = BytesToBigInt(cvp.Key).String()
m["value"] = BytesToBigInt(cvp.Value).String()
m["fnc"] = cvp.Fnc
return json.Marshal(m)
}
func siblingsToStringArray(s [][]byte) []string {
var r []string
for i := range s {
r = append(r, BytesToBigInt(s[i]).String())
}
return r
}
// FillMissingEmptySiblings adds the empty values to the array of siblings for
// the Tree number of max levels
func (t *Tree) FillMissingEmptySiblings(s [][]byte) [][]byte {
for i := len(s); i < t.maxLevels; i++ {
s = append(s, emptyValue)
}
return s
}
// GenerateCircomVerifierProof generates a CircomVerifierProof for a given key
// in the Tree
func (t *Tree) GenerateCircomVerifierProof(k []byte) (*CircomVerifierProof, error) {
kAux, v, siblings, existence, err := t.GenProof(k)
if err != nil && err != ErrKeyNotFound {
return nil, err
}
var cp CircomVerifierProof
cp.Root, err = t.Root()
if err != nil {
return nil, err
}
s, err := UnpackSiblings(t.hashFunction, siblings)
if err != nil {
return nil, err
}
cp.Siblings = t.FillMissingEmptySiblings(s)
if !existence {
cp.OldKey = kAux
cp.OldValue = v
} else {
cp.OldKey = emptyValue
cp.OldValue = emptyValue
}
cp.Key = k
cp.Value = v
if existence {
cp.Fnc = 0 // inclusion
} else {
cp.Fnc = 1 // non inclusion
}
return &cp, nil
}