arnaucube
arnaucube/arboPublic Self-hosted repository
arbo/circomproofs.go
circomproofs.goRaw
 1package arbo
 2
 3import (
 4	"encoding/json"
 5)
 6
 7// CircomVerifierProof contains the needed data to check a Circom Verifier Proof
 8// inside a circom circuit.  CircomVerifierProof allow to verify through a
 9// zkSNARK proof the inclusion/exclusion of a leaf in a tree.
10type CircomVerifierProof struct {
11	Root     []byte   `json:"root"`
12	Siblings [][]byte `json:"siblings"`
13	OldKey   []byte   `json:"oldKey"`
14	OldValue []byte   `json:"oldValue"`
15	IsOld0   bool     `json:"isOld0"`
16	Key      []byte   `json:"key"`
17	Value    []byte   `json:"value"`
18	Fnc      int      `json:"fnc"` // 0: inclusion, 1: non inclusion
19}
20
21// MarshalJSON implements the JSON marshaler
22func (cvp CircomVerifierProof) MarshalJSON() ([]byte, error) {
23	m := make(map[string]interface{})
24
25	m["root"] = BytesToBigInt(cvp.Root).String()
26	m["siblings"] = siblingsToStringArray(cvp.Siblings)
27	m["oldKey"] = BytesToBigInt(cvp.OldKey).String()
28	m["oldValue"] = BytesToBigInt(cvp.OldValue).String()
29	if cvp.IsOld0 {
30		m["isOld0"] = "1"
31	} else {
32		m["isOld0"] = "0"
33	}
34	m["key"] = BytesToBigInt(cvp.Key).String()
35	m["value"] = BytesToBigInt(cvp.Value).String()
36	m["fnc"] = cvp.Fnc
37
38	return json.Marshal(m)
39}
40
41func siblingsToStringArray(s [][]byte) []string {
42	var r []string
43	for i := 0; i < len(s); i++ {
44		r = append(r, BytesToBigInt(s[i]).String())
45	}
46	return r
47}
48
49// FillMissingEmptySiblings adds the empty values to the array of siblings for
50// the Tree number of max levels
51func (t *Tree) FillMissingEmptySiblings(s [][]byte) [][]byte {
52	for i := len(s); i < t.maxLevels; i++ {
53		s = append(s, emptyValue)
54	}
55	return s
56}
57
58// GenerateCircomVerifierProof generates a CircomVerifierProof for a given key
59// in the Tree
60func (t *Tree) GenerateCircomVerifierProof(k []byte) (*CircomVerifierProof, error) {
61	kAux, v, siblings, existence, err := t.GenProof(k)
62	if err != nil && err != ErrKeyNotFound {
63		return nil, err
64	}
65	var cp CircomVerifierProof
66	cp.Root, err = t.Root()
67	if err != nil {
68		return nil, err
69	}
70	s, err := UnpackSiblings(t.hashFunction, siblings)
71	if err != nil {
72		return nil, err
73	}
74	cp.Siblings = t.FillMissingEmptySiblings(s)
75	if !existence {
76		cp.OldKey = kAux
77		cp.OldValue = v
78	} else {
79		cp.OldKey = emptyValue
80		cp.OldValue = emptyValue
81	}
82	cp.Key = k
83	cp.Value = v
84	if existence {
85		cp.Fnc = 0 // inclusion
86	} else {
87		cp.Fnc = 1 // non inclusion
88	}
89
90	return &cp, nil
91}