1+ from "./poseidon_struct.zok" import DoubleHash
2+ from "./poseidon2.zok" import poseidon2_batch2
3+ from "./poseidon3.zok" import poseidon3
4+ from "./poseidon5.zok" import poseidon5_batch2
5+ from "./merkle.zok" import MerkleProof, verify_merkle, verify_merkle_batch
6+ from "./schnorr.zok" import WIDTH, Point, DoublePoint, QuadPoint, PublicKey, Signature, verify_signature, point_add, point_mul, point_double_add_batch, point_mul_batch
7+
8+ // Reveal Proof Entry
9+ struct T {
10+ u32 i
11+ field[ro 5] s // sig_r_x, sig_r_y, sig_s, l, r
12+ field[ro 5] p // pk_p_x, pk_p_y, pk_q_x, pk_q_y, w
13+ }
14+
15+ struct CompactCertProof {
16+ field sig_root
17+ u64 signed_weight
18+ u32[ro 0] t_i_list
19+ field[ro 0][ro 5] t_p_list
20+ }
21+
22+ // Verifier of a compact certificate function
23+ def verifier(
24+ CompactCertProof compact_cert_proof,
25+ u64 proven_weight,
26+ u32 num_reveals,
27+ field message,
28+ u32 merkle_depth,
29+ field att_root,
30+ field[ro 0] coins
31+ ) -> field:
32+ u64 signed_weight = compact_cert_proof.signed_weight
33+ assert(signed_weight > proven_weight)
34+ // let num_reveals: usize = (k + q).div_ceil((signed_weight / proven_weight).ilog2() as usize);
35+
36+ for u32 j in 0..num_reveals do
37+ // Reproduce coin
38+ // field[5] inputs = [(F)j, compact_cert_proof.sig_root, (F)proven_weight, message, att_root]
39+ // field coin_hash = poseidon(5, inputs)
40+ // field coin = coin_hash % (F)signed_weight
41+ field coin = coins[j]
42+
43+ u32 t_i = compact_cert_proof.t_i_list[j]
44+ field[ro 5] t_p = compact_cert_proof.t_p_list[j]
45+ witness field sig_r_x
46+ witness field sig_r_y
47+ witness field sig_s
48+ witness field l
49+ witness field r
50+ // Sig Opening & Att Opening
51+ assert(verify_merkle_batch(t_i, compact_cert_proof.sig_root, sig_r_x, sig_r_y, sig_s, l, r, att_root, t_p, merkle_depth) == 1)
52+ // Validity of signature
53+ PublicKey pk = PublicKey {
54+ p: Point { x: t_p[0], y: t_p[1] },
55+ q: Point { x: t_p[2], y: t_p[3] }
56+ }
57+ Signature sig = Signature {
58+ r: Point{ x: sig_r_x, y: sig_r_y },
59+ s: sig_s
60+ }
61+ assert(verify_signature(message, pk, sig) == 1)
62+ // L < coin <= L + Weight
63+ field t_p_4 = t_p[4]
64+ assert(l + t_p_4 == r)
65+ assert(l <= coin && coin < r)
66+ endfor
67+
68+ return 1
69+
70+ // Parse out the inputs in simple register - memory form
71+ def main(
72+ u32 num_attestors,
73+ // For compact_cert_proof
74+ field sig_root,
75+ u64 signed_weight,
76+ u32[ro 0] t_i_list,
77+ // All memory entries within T (p)
78+ field[ro 0] t_mem,
79+ // List of pointers (input format field[0])
80+ field[ro 0][ro 5] t_p_list,
81+ // For others
82+ u64 proven_weight,
83+ u32 num_reveals,
84+ field message,
85+ u32 merkle_depth,
86+ field att_root,
87+ field[ro 0] coins
88+ ) -> field:
89+ CompactCertProof compact_cert_proof = CompactCertProof {
90+ sig_root: sig_root,
91+ signed_weight: signed_weight,
92+ t_i_list: t_i_list,
93+ t_p_list: t_p_list
94+ }
95+
96+ return verifier(
97+ compact_cert_proof,
98+ proven_weight,
99+ num_reveals,
100+ message,
101+ merkle_depth,
102+ att_root,
103+ coins
104+ )
105+ /*
106+ def main() -> u32:
107+ field message = 6908441180828167112785246881494320159273940089327447106269949444716788494909
108+
109+ // Let all attestors use the same pk & weight, does not affect performance
110+ u32 num_attestors = 8
111+ u32 weight = 5
112+ u32 proven_weight = num_attestors * weight - 1
113+ u32 signed_weight = num_attestors * weight
114+ array_decl PublicKey[num_attestors] pk_list
115+ array_decl Signature[num_attestors] sig_list
116+ // Constant folding to avoid constructing new blocks
117+ for u32 i in 0..8 do
118+ pk_list[i] = PublicKey {
119+ p: Point {
120+ x: 2023776050662786605020065854616777351003832247628992350849206310281785027488,
121+ y: 1079270832837170318396516616249394502719834190979906495690419930531357954746
122+ },
123+ q: Point {
124+ x: 7101684830137506950821434332972100736705268320764486193269722119377250644660,
125+ y: 1764840689618624173098512281158161439147043396136846829753116276022936136130
126+ }
127+ }
128+ sig_list[i] = Signature {
129+ r: Point {
130+ x: 5824293800188062938533237344790739102726705128562220570802448947038150657007,
131+ y: 340848841123394720212279364279745606262149681372696003943728267198931244360
132+ },
133+ s: 4415915127126372096757067153593537022657929051278082364476489088715040314973
134+ }
135+ endfor
136+ // Pre-compute merkle tree
137+ field att_l3 = 3568540802966646228682833257557760865097881745527951700421217637177394578913
138+ field att_l2 = 2484212816056817413898735043111201825935337234900653303346593633698983423094
139+ field att_l1 = 5903852974969142884799701163972075918012827147993384813454715036777418930530
140+ field att_root = 5370923878175693173927301385262983018969346333984379995904147798742460333298
141+ field[8] sig_l3 = [2143011384822392262595217693211276733745818975285573378412503830433633959080, 5158845522944913588713567773900368475672965537784145747547478088857012853666, 5894431764744941209369386797811063446586114379583965613751294306331542502696, 3667283647262791680030373214327691510807066264550220904438401348778560171091, 1932762137729700956492443572973924935698339638272997763907569306777878106609, 1418160613934592350074019113722063326372415219334378482966622875040143984418, 1123602082019234105093136610853837217580120360581368113294785447946335970166, 677162234791219704923474809188832072777286476135280817077786787139967839874]
142+ field[4] sig_l2 = [4160497668328416341124388728115946100594341504290452585444083838585144458368, 1786009993478681170835177129397965607571769106910016212295375778662767436399, 6323428707993845638065745016939134132792346703598261115088661703160553949516, 1179006504278106626617144731083403287975523722023953894416803973871305137607]
143+ field[2] sig_l1 = [2082031909420678479574926408191366694068435842853798548085170995138065656765, 2509162190273150374531803693747128200974026349740956653847078957273579771806]
144+ field sig_root = 2845540671766269799140204035187166219383492292318390575781563565945781070871
145+ u32 merkle_depth = 3
146+
147+ u32 num_reveals = 3
148+ // coin = [7, 30, 34]
149+ // entry = [1, 6, 6]
150+ // All bits in big endian
151+ bool[num_reveals][WIDTH] e_bits_list = [[false, false, false, false, true, false, true, true, true, false, true, true, true, true, true, true, false, false, false, true, false, true, false, false, true, false, false, true, true, true, false, true, false, true, true, true, false, false, true, false, false, true, false, false, false, true, true, false, false, false, true, false, false, false, false, true, true, false, false, false, true, false, false, false, false, true, false, false, true, true, true, true, false, true, false, true, false, false, true, true, false, true, false, false, false, true, false, true, false, false, false, false, true, false, true, true, false, false, false, false, true, false, true, false, true, false, false, false, true, true, false, false, true, true, false, true, true, false, true, false, true, true, true, false, true, false, true, false, true, true, true, true, true, true, false, false, false, true, false, true, false, false, true, false, false, false, true, true, false, false, true, false, false, true, false, false, false, true, false, false, false, true, false, false, true, true, true, false, false, false, true, true, true, false, false, false, false, false, true, true, true, false, true, true, false, true, false, true, false, true, false, true, false, false, true, true, false, false, false, false, true, true, false, false, false, false, true, false, true, true, false, true, false, false, true, true, true, false, true, false, true, true, true, true, false, true, true, false, false, true, false, false, true, false, false, false, true, false, false, false, false, false, false, true, false, true, true, false, true, true, false, false, true]; num_reveals]
152+ bool[num_reveals][WIDTH] s_bits_list = [[false, true, false, false, true, true, true, false, false, false, false, true, true, false, true, false, true, false, false, false, true, true, true, false, false, false, false, true, true, true, false, false, false, false, false, false, true, false, false, true, false, false, true, true, true, false, true, true, false, true, false, false, true, true, true, true, false, true, true, true, true, true, false, false, true, false, true, true, false, false, true, false, true, true, true, true, true, true, false, false, true, false, false, true, true, true, false, true, false, false, true, false, false, false, false, true, true, true, false, true, true, false, false, true, true, true, true, true, false, false, false, true, false, true, true, true, true, false, true, false, true, true, false, false, true, false, false, false, false, true, false, false, false, true, true, true, true, false, true, true, false, false, false, true, true, false, false, false, true, false, true, true, true, false, true, true, true, false, true, false, false, true, true, false, false, true, false, false, false, false, true, true, false, true, false, true, false, false, false, true, true, false, true, true, false, true, true, false, true, true, true, false, true, true, false, true, false, true, true, false, true, true, true, false, true, true, false, false, true, true, false, false, true, false, true, false, false, false, false, true, false, false, true, false, true, true, true, true, true, false, false, false, true, false, false, false, true, false, true, false, true, false, true, true, false, false, true, false, true, true, true, false, true]; num_reveals]
153+
154+ CompactCertProof compact_cert_proof = CompactCertProof {
155+ sig_root: sig_root,
156+ signed_weight: signed_weight,
157+ t_list: [
158+ T {
159+ i: 1,
160+ i_bits: [false, false, true],
161+ s: [sig_list[1].r.x, sig_list[1].r.y, sig_list[1].s, 5, 10],
162+ pi_s: MerkleProof {
163+ path: [sig_l3[0], sig_l2[1], sig_l1[1]]
164+ },
165+ p: [pk_list[1].p.x, pk_list[1].p.y, pk_list[1].q.x, pk_list[1].q.y, (F)weight],
166+ pi_p: MerkleProof {
167+ path: [att_l3, att_l2, att_l1]
168+ }
169+ },
170+ T {
171+ i: 6,
172+ i_bits: [true, true, false],
173+ s: [sig_list[6].r.x, sig_list[6].r.y, sig_list[6].s, 30, 35],
174+ pi_s: MerkleProof {
175+ path: [sig_l3[7], sig_l2[2], sig_l1[0]]
176+ },
177+ p: [pk_list[6].p.x, pk_list[6].p.y, pk_list[6].q.x, pk_list[6].q.y, (F)weight],
178+ pi_p: MerkleProof {
179+ path: [att_l3, att_l2, att_l1]
180+ }
181+ },
182+ T {
183+ i: 6,
184+ i_bits: [true, true, false],
185+ s: [sig_list[6].r.x, sig_list[6].r.y, sig_list[6].s, 30, 35],
186+ pi_s: MerkleProof {
187+ path: [sig_l3[7], sig_l2[2], sig_l1[0]]
188+ },
189+ p: [pk_list[6].p.x, pk_list[6].p.y, pk_list[6].q.x, pk_list[6].q.y, (F)weight],
190+ pi_p: MerkleProof {
191+ path: [att_l3, att_l2, att_l1]
192+ }
193+ }
194+ ]
195+ }
196+
197+ return verifier(
198+ compact_cert_proof,
199+ proven_weight,
200+ num_reveals,
201+ message,
202+ merkle_depth,
203+ att_root,
204+ e_bits_list,
205+ s_bits_list
206+ )
207+ */
0 commit comments