-
Notifications
You must be signed in to change notification settings - Fork 4
/
print.html
1835 lines (1692 loc) · 112 KB
/
print.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>ZoKrates</title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body class="light">
<!-- Provide site root to javascript -->
<script type="text/javascript">var path_to_root = "";</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = 'light'; }
document.body.className = theme;
document.querySelector('html').className = theme + ' js';
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="gettingstarted.html"><strong aria-hidden="true">2.</strong> Getting Started</a></li><li><a href="language/index.html"><strong aria-hidden="true">3.</strong> Language</a></li><li><ol class="section"><li><a href="language/variables.html"><strong aria-hidden="true">3.1.</strong> Variables</a></li><li><a href="language/types.html"><strong aria-hidden="true">3.2.</strong> Types</a></li><li><a href="language/operators.html"><strong aria-hidden="true">3.3.</strong> Operators</a></li><li><a href="language/control_flow.html"><strong aria-hidden="true">3.4.</strong> Control flow</a></li><li><a href="language/constants.html"><strong aria-hidden="true">3.5.</strong> Constants</a></li><li><a href="language/functions.html"><strong aria-hidden="true">3.6.</strong> Functions</a></li><li><a href="language/generics.html"><strong aria-hidden="true">3.7.</strong> Generics</a></li><li><a href="language/imports.html"><strong aria-hidden="true">3.8.</strong> Imports</a></li><li><a href="language/comments.html"><strong aria-hidden="true">3.9.</strong> Comments</a></li><li><a href="language/macros.html"><strong aria-hidden="true">3.10.</strong> Macros</a></li><li><a href="language/logging.html"><strong aria-hidden="true">3.11.</strong> Logging</a></li><li><a href="language/assembly.html"><strong aria-hidden="true">3.12.</strong> Assembly</a></li></ol></li><li><a href="toolbox/index.html"><strong aria-hidden="true">4.</strong> Toolbox</a></li><li><ol class="section"><li><a href="toolbox/cli.html"><strong aria-hidden="true">4.1.</strong> CLI</a></li><li><a href="toolbox/trusted_setup.html"><strong aria-hidden="true">4.2.</strong> Trusted Setup</a></li><li><a href="toolbox/stdlib.html"><strong aria-hidden="true">4.3.</strong> Standard Library</a></li><li><a href="toolbox/proving_schemes.html"><strong aria-hidden="true">4.4.</strong> Proving schemes</a></li><li><a href="toolbox/verification.html"><strong aria-hidden="true">4.5.</strong> Verification</a></li><li><a href="toolbox/ir.html"><strong aria-hidden="true">4.6.</strong> ZIR</a></li><li><a href="toolbox/abi.html"><strong aria-hidden="true">4.7.</strong> JSON ABI</a></li><li><a href="toolbox/zokrates_js.html"><strong aria-hidden="true">4.8.</strong> zokrates.js</a></li><li><a href="toolbox/experimental.html"><strong aria-hidden="true">4.9.</strong> Experimental</a></li></ol></li><li><a href="examples/index.html"><strong aria-hidden="true">5.</strong> Examples</a></li><li><ol class="section"><li><a href="examples/rng_tutorial.html"><strong aria-hidden="true">5.1.</strong> A SNARK Powered RNG</a></li><li><a href="examples/sha256example.html"><strong aria-hidden="true">5.2.</strong> Proving knowledge of a hash preimage</a></li><li><a href="examples/magic_square.html"><strong aria-hidden="true">5.3.</strong> A ZK Magic Square in the browser</a></li></ol></li><li><a href="testing.html"><strong aria-hidden="true">6.</strong> Testing</a></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar" class="menu-bar">
<div id="menu-bar-sticky-container">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light <span class="default">(default)</span></button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">ZoKrates</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<a class="header" href="#introduction" id="introduction"><h1>Introduction</h1></a>
<p>ZoKrates is a toolbox for zkSNARKs on Ethereum. It helps you use verifiable computation in your DApp, from the specification of your program in a high level language to generating proofs of computation to verifying those proofs in Solidity.</p>
<a class="header" href="#background-on-zksnarks" id="background-on-zksnarks"><h2>Background on zkSNARKs</h2></a>
<p>Zero-knowledge proofs (ZKPs) are a family of probabilistic protocols, first described by <a href="http://people.csail.mit.edu/silvio/Selected%20Scientific%20Papers/Proof%20Systems/The_Knowledge_Complexity_Of_Interactive_Proof_Systems.pdf">Goldwasser, Micali and Rackoff</a> in 1985.</p>
<p>One particular family of ZKPs is described as zero-knowledge <strong>S</strong>uccinct <strong>N</strong>on-interactive <strong>AR</strong>guments of <strong>K</strong>nowledge, a.k.a. zkSNARKs. zkSNARKs are the most widely used zero-knowledge protocols, with the anonymous cryptocurrency Zcash and the smart-contract platform Ethereum among the notable early adopters.</p>
<p>For further details we refer the reader to some introductory material provided by the community: <a href="https://z.cash/technology/zksnarks/">[1]</a>, <a href="https://medium.com/@VitalikButerin/zkSNARKs-under-the-hood-b33151a013f6">[2]</a>, <a href="https://blog.decentriq.ch/zk-SNARKs-primer-part-one/">[3]</a>.</p>
<a class="header" href="#motivation" id="motivation"><h2>Motivation</h2></a>
<p>Ethereum runs computations on all nodes of the network, resulting in high costs, limits in complexity, and low privacy. zkSNARKs have been enabling to only verify computations on-chain for a fraction of the cost of running them, but are hard to grasp and work with.</p>
<p>ZoKrates bridges this gap. It helps you create off-chain programs and link them to the Ethereum blockchain, expanding the possibilities for your DApp.</p>
<a class="header" href="#license" id="license"><h2>License</h2></a>
<p>ZoKrates is released under the GNU Lesser General Public License v3.</p>
<a class="header" href="#getting-started" id="getting-started"><h1>Getting Started</h1></a>
<a class="header" href="#installation" id="installation"><h2>Installation</h2></a>
<a class="header" href="#online-ides" id="online-ides"><h3>Online IDEs</h3></a>
<p>To get a feel of the language, try the <a href="https://play.zokrat.es">ZoKrates playgound</a>.</p>
<p>To experiment with creating SNARKs and verifying them in the EVM, check out the ZoKrates plugin in the <a href="https://remix.ethereum.org">Remix online IDE</a>.</p>
<a class="header" href="#one-line-installation" id="one-line-installation"><h3>One-line installation</h3></a>
<p>We provide one-line installation for Linux, MacOS and FreeBSD:</p>
<pre><code class="language-bash">curl -LSfs get.zokrat.es | sh
</code></pre>
<a class="header" href="#from-source" id="from-source"><h3>From source</h3></a>
<p>You can build ZoKrates from <a href="https://github.com/ZoKrates/ZoKrates/">source</a> with the following commands:</p>
<pre><code class="language-bash">git clone https://github.com/ZoKrates/ZoKrates
cd ZoKrates
export ZOKRATES_STDLIB=$PWD/zokrates_stdlib/stdlib
cargo build -p zokrates_cli --release
cd target/release
</code></pre>
<a class="header" href="#docker" id="docker"><h3>Docker</h3></a>
<p>ZoKrates is available on Dockerhub.</p>
<pre><code class="language-bash">docker run -ti zokrates/zokrates /bin/bash
</code></pre>
<p>From there on, you can use the <code>zokrates</code> CLI.</p>
<a class="header" href="#hello-zokrates" id="hello-zokrates"><h2>Hello ZoKrates!</h2></a>
<p>First, create the text-file <code>root.zok</code> and implement your program. In this example, we will prove knowledge of the square root <code>a</code> of a number <code>b</code>:</p>
<pre><code class="language-zokrates">def main(private field a, field b) {
assert(a * a == b);
return;
}
</code></pre>
<p>Some observations:</p>
<ul>
<li>The keyword <code>field</code> is the basic type we use, which is an element of a given prime field.</li>
<li>The keyword <code>private</code> signals that we do not want to reveal this input, but still prove that we know its value.</li>
</ul>
<p>Then run the different phases of the protocol:</p>
<pre><code class="language-bash"># compile
zokrates compile -i root.zok
# perform the setup phase
zokrates setup
# execute the program
zokrates compute-witness -a 337 113569
# generate a proof of computation
zokrates generate-proof
# export a solidity verifier
zokrates export-verifier
# or verify natively
zokrates verify
</code></pre>
<p>The CLI commands are explained in more detail in the <a href="toolbox/cli.html">CLI reference</a>.</p>
<a class="header" href="#programming-concepts" id="programming-concepts"><h1>Programming Concepts</h1></a>
<a class="header" href="#variables" id="variables"><h2>Variables</h2></a>
<p>Variables can have any name which does not start with a number.
Variables are mutable, and always passed by value to functions.</p>
<a class="header" href="#declaration" id="declaration"><h3>Declaration</h3></a>
<p>Variables need to be declared to be used. Declaration and definition are always combined, so that undefined variables do not exist.</p>
<pre><code class="language-zokrates">def main() {
// declare and define `my_variable`
field mut my_variable = 2;
// redefine `my_variable`
my_variable = 3;
return;
}
</code></pre>
<a class="header" href="#mutability" id="mutability"><h3>Mutability</h3></a>
<p>Variables are immutable by default. In order to declare a mutable variable, the <code>mut</code> keyword is used.</p>
<pre><code class="language-zokrates">def main() {
field a = 42;
// a = 43; <- not allowed, as `a` is immutable
field mut b = 42;
b = 43; // ok
return;
}
</code></pre>
<a class="header" href="#shadowing" id="shadowing"><h3>Shadowing</h3></a>
<p>Shadowing is allowed.</p>
<pre><code class="language-zokrates">def main() -> field {
field a = 2;
field a = 3; // shadowing
for u32 i in 0..5 {
bool a = true; // shadowing
}
// `a` is the variable declared before the loop
return a;
}
</code></pre>
<a class="header" href="#scope" id="scope"><h3>Scope</h3></a>
<a class="header" href="#function" id="function"><h4>Function</h4></a>
<p>Functions have their own scope</p>
<pre><code class="language-zokrates">def foo() -> field {
// return myGlobal; <- not allowed
return 42;
}
def main() -> field {
field myGlobal = 42;
return foo();
}
</code></pre>
<a class="header" href="#for-loop" id="for-loop"><h4>For-loop</h4></a>
<p>For-loops have their own scope</p>
<pre><code class="language-zokrates">def main() -> u32 {
u32 mut a = 0;
for u32 i in 0..5 {
a = a + i;
}
// return i; <- not allowed
return a;
}
</code></pre>
<a class="header" href="#types" id="types"><h1>Types</h1></a>
<p>ZoKrates currently exposes two primitive types and two complex types:</p>
<a class="header" href="#primitive-types" id="primitive-types"><h2>Primitive Types</h2></a>
<a class="header" href="#field" id="field"><h3><code>field</code></h3></a>
<p>This is the most basic type in ZoKrates, and it represents a field element with positive integer values in <code>[0, p - 1]</code> where <code>p</code> is a (large) prime number.</p>
<p>As an example, <code>p</code> is set to <code>21888242871839275222246405745257275088548364400416034343698204186575808495617</code> when working with the <a href="../toolbox/proving_schemes.html#curves">ALT_BN128</a> curve supported by Ethereum.</p>
<p>While <code>field</code> values mostly behave like unsigned integers, one should keep in mind that they overflow at <code>p</code> and not some power of 2, so that we have:</p>
<pre><code class="language-zokrates">def main() {
field pMinusOne = 21888242871839275222246405745257275088548364400416034343698204186575808495616;
assert(0 - 1 == pMinusOne);
return;
}
</code></pre>
<p>Note that <a href="https://en.wikipedia.org/wiki/Finite_field_arithmetic">division in the finite field</a> behaves differently than in the case of integers.
For field elements, the division operation multiplies the numerator with the denominator's inverse field element. The results coincide with integer divisions for cases with remainder 0, but differ otherwise.</p>
<a class="header" href="#bool" id="bool"><h3><code>bool</code></h3></a>
<p>Booleans are available in ZoKrates. When a boolean is used as a parameter of the main function, the program is constrained to only accept <code>0</code> or <code>1</code> for that parameter. A boolean can be asserted to be true using an <code>assert(bool)</code> statement.</p>
<a class="header" href="#u8u16u32u64" id="u8u16u32u64"><h3><code>u8/u16/u32/u64</code></h3></a>
<p>Unsigned integers represent positive numbers of the interval <code>[0, 2 ** bitwidth)</code>, where <code>bitwidth</code> is specified in the type's name, e.g., 32 bits in the case of u32. Their arithmetics are defined modulo <code>2 ** bitwidth</code>.</p>
<p>Internally, they use a binary encoding, which makes them particularly efficient for implementing programs that operate on that binary representation, e.g., the SHA256 hash function.</p>
<p>Similarly to booleans, unsigned integer inputs of the main function only accept values of the appropriate range.</p>
<p>The division operation calculates the standard floor division for integers. The <code>%</code> operand can be used to obtain the remainder.</p>
<a class="header" href="#numeric-inference" id="numeric-inference"><h3>Numeric inference</h3></a>
<p>In the case of decimal literals like <code>42</code>, the compiler tries to find the appropriate type (<code>field</code>, <code>u8</code>, <code>u16</code>, <code>u32</code> or <code>u64</code>) depending on the context. If it cannot converge to a single option, an error is returned. This means that there is no default type for decimal literals.</p>
<p>All operations between literals have the semantics of the inferred type.</p>
<pre><code class="language-zokrates">def main() {
// `255` is inferred to `255f`, and the addition happens between field elements
assert(255 + 1f == 256);
// `255` is inferred to `255u8`, and the addition happens between u8
// This causes an overflow
assert(255 + 1u8 == 0);
return;
}
</code></pre>
<a class="header" href="#complex-types" id="complex-types"><h2>Complex Types</h2></a>
<p>ZoKrates provides two complex types: arrays and structs.</p>
<a class="header" href="#arrays" id="arrays"><h3>Arrays</h3></a>
<p>ZoKrates supports static arrays, i.e., whose length needs to be known at compile time. For more details on generic array sizes, see <a href="../language/generics.html">constant generics</a>
Arrays can contain elements of any type and have arbitrary dimensions.</p>
<p>The following example code shows examples of how to use arrays:</p>
<pre><code class="language-zokrates">def main() -> field {
field[3] mut a = [1, 2, 3]; // initialize a field array with field values
a[2] = 4; // set a member to a value
field[4] b = [42; 4]; // initialize an array of 4 values all equal to 42
field[4] c = [...a, 4]; // initialize an array copying values from `a`, followed by 4
field[2] d = a[1..3]; // initialize an array copying a slice from `a`
bool[3] e = [true, true || false, true]; // initialize a boolean array
u32 SIZE = 3;
field[SIZE] f = [1, 2, 3]; // initialize a field array with a size that's a compile-time constant
return a[0] + b[1] + c[2];
}
</code></pre>
<a class="header" href="#declaration-and-initialization" id="declaration-and-initialization"><h4>Declaration and Initialization</h4></a>
<p>An array is defined by appending <code>[]</code> to a type literal representing the type of the array's elements.</p>
<p>Initialization always needs to happen in the same statement as a declaration, unless the array is declared within a function's signature.</p>
<p>For initialization, a list of comma-separated values is provided within brackets <code>[]</code>.</p>
<p>ZoKrates offers a special shorthand syntax to initialize an array with a constant value:
<code>[value; repetitions]</code></p>
<p>The following code provides examples for declaration and initialization:</p>
<pre><code class="language-zokrates">field[3] a = [1, 2, 3]; // initialize a field array with field values
bool[13] b = [false; 13]; // initialize a bool array with value false
</code></pre>
<a class="header" href="#multidimensional-arrays" id="multidimensional-arrays"><h4>Multidimensional Arrays</h4></a>
<p>As an array can contain any type of elements, it can contain arrays again.
There is a special syntax to declare such multi-dimensional arrays, i.e., arrays of arrays.
To declare an array of an inner array, i.e., and an array of elements of a type, prepend brackets <code>[size]</code> to the declaration of the inner array.
In summary, this leads to the following scheme for array declarations:
<code>data_type[size of 1st dimension][size of 2nd dimension]</code>.
Consider the following example:</p>
<pre><code class="language-zokrates">def main() -> field {
// Array of two elements of array of 3 elements
field[2][3] a = [[1, 2, 3],[4, 5, 6]];
field[3] b = a[0]; // should be [1, 2, 3]
// allowed access [0..2][0..3]
return a[1][2];
}
</code></pre>
<a class="header" href="#spreads-and-slices" id="spreads-and-slices"><h4>Spreads and Slices</h4></a>
<p>ZoKrates provides some syntactic sugar to retrieve subsets of arrays.</p>
<a class="header" href="#spreads" id="spreads"><h5>Spreads</h5></a>
<p>The spread operator <code>...</code> applied to an array copies the elements of the existing array.
This can be used to conveniently compose new arrays, as shown in the following example:</p>
<pre><code>field[3] a = [1, 2, 3];
field[4] c = [...a, 4]; // initialize an array copying values from `a`, followed by 4
</code></pre>
<a class="header" href="#slices" id="slices"><h5>Slices</h5></a>
<p>An array can also be assigned to by creating a copy of a subset of an existing array.
This operation is called slicing, and the following example shows how to slice in ZoKrates:</p>
<pre><code>field[3] a = [1, 2, 3];
field[2] b = a[1..3]; // initialize an array copying a slice from `a`
</code></pre>
<a class="header" href="#tuples" id="tuples"><h3>Tuples</h3></a>
<p>A tuple is a composite datatype representing a numbered collection of values.
The following code shows an example of how to use tuples.</p>
<pre><code class="language-zokrates">def main() -> bool {
(field[2], bool) mut v = ([1, 2], true);
v.0 = [42, 43];
return v.1;
}
</code></pre>
<p>In tuple types and values, the trailing comma is optional, unless the tuple contains a single element, in which case it is mandatory.</p>
<a class="header" href="#structs" id="structs"><h3>Structs</h3></a>
<p>A struct is a composite datatype representing a named collection of values. Structs can be generic over constants, in order to wrap arrays of generic size. For more details on generic array sizes, see <a href="../language/generics.html">constant generics</a>. The contained variables can be of any type.</p>
<p>The following code shows an example of how to use structs.</p>
<pre><code class="language-zokrates">struct Bar<N> {
field[N] c;
bool d;
}
struct Foo<P> {
Bar<P> a;
bool b;
}
def main() -> Foo<2> {
Foo<2>[2] mut f = [Foo { a: Bar { c: [0, 0], d: false }, b: true}, Foo { a: Bar {c: [0, 0], d: false}, b: true }];
f[0].a.c = [42, 43];
return f[0];
}
</code></pre>
<a class="header" href="#definition" id="definition"><h4>Definition</h4></a>
<p>Before a struct data type can be used, it needs to be defined.
A struct definition starts with the <code>struct</code> keyword followed by a name. Afterwards, a new-line separated list of variables is declared in curly braces <code>{}</code>. For example:</p>
<pre><code class="language-zokrates">struct Point {
field x;
field y;
}
</code></pre>
<p>Note that two struct definitions with the same members still introduce two entirely different types. For example, they cannot be compared with each other.</p>
<a class="header" href="#declaration-and-initialization-1" id="declaration-and-initialization-1"><h4>Declaration and Initialization</h4></a>
<p>Initialization of a variable of a struct type always needs to happen in the same statement as a declaration, unless the struct-typed variable is declared within a function's signature.</p>
<p>The following example shows declaration and initialization of a variable of the <code>Point</code> struct type:</p>
<pre><code class="language-zokrates">struct Point {
field x;
field y;
}
def main() -> Point {
Point p = Point { x: 1, y: 0 };
return p;
}
</code></pre>
<a class="header" href="#assignment" id="assignment"><h4>Assignment</h4></a>
<p>The variables within a struct instance, the so called members, can be accessed through the <code>.</code> operator as shown in the following extended example:</p>
<pre><code class="language-zokrates">struct Point {
field x;
field y;
}
def main(field a) -> Point {
Point mut p = Point { x: 1, y: 0 };
p.x = a;
p.y = p.x;
return p;
}
</code></pre>
<a class="header" href="#type-aliases" id="type-aliases"><h3>Type aliases</h3></a>
<p>Type aliases can be defined for any existing type. This can be useful for readability, or to specialize generic types.</p>
<p>Note that type aliases are just syntactic sugar: in the type system, a type and its alias are exactly equivalent. For example, they can be compared.</p>
<pre><code class="language-zokrates">type MyField = field;
type Rectangle<L, W> = bool[L][W];
type Square<S> = Rectangle<S, S>;
def main() {
MyField f = 42;
Rectangle<2, 2> r = [[true; 2]; 2];
Square<2> s = r;
return;
}
</code></pre>
<a class="header" href="#operators" id="operators"><h2>Operators</h2></a>
<p>The following table lists the precedence and associativity of all operators. Operators are listed top to bottom, in ascending precedence. Operators in the same cell have the same precedence. Operators are binary, unless the syntax is provided.</p>
<table><thead><tr><th> Operator </th><th> Description </th><th> <code>field</code> </th><th> <code>u8/u16</code> <code>u32/u64</code> </th><th> <code>bool</code> </th><th> Associativity </th></tr></thead><tbody>
<tr><td> <code>**</code><br> </td><td> Power </td><td> ✓<sup class="footnote-reference"><a href="#1">1</a></sup> </td><td> </td><td> </td><td> Left </td></tr>
<tr><td> <code>+x</code><br><code>-x</code><br><code>!x</code><br> </td><td> Positive<br>Negative<br>Negation<br> </td><td> ✓<br>✓<br> </td><td> ✓<br>✓<br>✓ </td><td> <br> <br>✓ </td><td> Right </td></tr>
<tr><td> <code>*</code><br><code>/</code><br><code>%</code><br> </td><td> Multiplication<br> Division<br> Remainder<br> </td><td> ✓<br>✓<br> </td><td> ✓<br>✓<br>✓ </td><td> <br> <br> </td><td> Left </td></tr>
<tr><td> <code>+</code><br><code>-</code><br> </td><td> Addition<br> Subtraction<br> </td><td> ✓ </td><td> ✓ </td><td> </td><td> Left </td></tr>
<tr><td> <code><<</code><br><code>>></code><br> </td><td> Left shift<br> Right shift<br> </td><td> </td><td> ✓<sup class="footnote-reference"><a href="#2">2</a></sup> </td><td> </td><td> Left </td></tr>
<tr><td> <code>&</code> </td><td> Bitwise AND </td><td> </td><td> ✓ </td><td> </td><td> Left </td></tr>
<tr><td> <code>|</code> </td><td> Bitwise OR </td><td> </td><td> ✓ </td><td> </td><td> Left </td></tr>
<tr><td> <code>^</code> </td><td> Bitwise XOR </td><td> </td><td> ✓ </td><td> </td><td> Left </td></tr>
<tr><td> <code>>=</code><br><code>></code><br><code><=</code><br><code><</code> </td><td> Greater or equal<br>Greater<br>Lower or equal<br>Lower<br> </td><td> ✓<sup class="footnote-reference"><a href="#3">3</a></sup> </td><td> ✓ </td><td> </td><td> Left </td></tr>
<tr><td> <code>!=</code><br><code>==</code><br> </td><td> Not Equal<br>Equal<br> </td><td> ✓ </td><td> ✓ </td><td> ✓ </td><td> Left </td></tr>
<tr><td> <code>&&</code> </td><td> Boolean AND </td><td> </td><td> </td><td> ✓ </td><td> Left </td></tr>
<tr><td> <code>||</code> </td><td> Boolean OR </td><td> </td><td> </td><td> ✓ </td><td> Left </td></tr>
<tr><td> <code>c ? x : y</code><br><br><code>if c { x } else { y }</code> </td><td> Conditional expression </td><td> ✓ </td><td> ✓ </td><td> ✓ </td><td> Right </td></tr>
</tbody></table>
<div class="footnote-definition" id="1"><sup class="footnote-definition-label">1</sup>
<p>The exponent must be a compile-time constant of type <code>u32</code></p>
</div>
<div class="footnote-definition" id="2"><sup class="footnote-definition-label">2</sup>
<p>The right operand must be a compile time constant of type <code>u32</code></p>
</div>
<div class="footnote-definition" id="3"><sup class="footnote-definition-label">3</sup>
<p>If neither of the operands can be determined to be a compile-time constant, then we have a restriction: for the check <code>a < b</code>, if the field prime <code>p</code> is represented on <code>N</code> bits, <code>|a - b|</code> must fit in <code>N - 2</code> bits.
Failing to respect this condition will lead to a runtime error.</p>
</div>
<a class="header" href="#control-flow" id="control-flow"><h2>Control Flow</h2></a>
<p>ZoKrates provides a single thread of execution with a few flow constructs.</p>
<a class="header" href="#function-calls" id="function-calls"><h3>Function calls</h3></a>
<p>Function calls help make programs clear and modular.</p>
<p>Arguments are passed by value.</p>
<p>Function parameters can be declared as mutable to allow for mutation within the function's body. However, mutable function arguments are still passed by value, so the original value can never be mutated.</p>
<pre><code class="language-zokrates">def incr(field mut a) -> field {
a = a + 1;
return a;
}
def main() {
field x = 1;
field res = incr(x);
assert(x == 1); // x has not changed
return;
}
</code></pre>
<p>Generic parameters, if any, must be compile-time constants. They are inferred by the compiler if that is possible, but can also be provided explicitly.</p>
<pre><code class="language-zokrates">def foo<N, P>() -> field[P] {
return [42; P];
}
def main() -> field[2] {
// `P` is inferred from the declaration of `res`, while `N` is provided explicitly
field[2] res = foo::<3, _>();
return res;
}
</code></pre>
<a class="header" href="#conditional-expressions" id="conditional-expressions"><h3>Conditional expressions</h3></a>
<p>A conditional expression allows you to branch your code depending on a boolean condition.</p>
<pre><code class="language-zokrates">def main(field x) -> field {
field y = if x + 2 == 3 { 1 } else { 5 };
return y;
}
</code></pre>
<p>The conditional expression can also be written using a ternary operator:</p>
<pre><code class="language-zokrates">def main(field x) -> field {
field y = x + 2 == 3 ? 1 : 5;
return y;
}
</code></pre>
<p>There are two important caveats when it comes to conditional expressions. Before we go into them, let's define two concepts:</p>
<ul>
<li>for an execution of the program, <em>an executed branch</em> is a branch which has to be paid for when executing the program, generating proofs, etc.</li>
<li>for an execution of the program, <em>a logically executed branch</em> is a branch which is "chosen" by the condition of an if-expression. This is the more intuitive notion of execution, and there is only one for each if-expression.</li>
</ul>
<p>Now the two caveats:</p>
<ul>
<li><strong>Both branches are always executed</strong>. No short-circuiting happens based on the value of the condition. Therefore, the complexity of a program in terms of the number of constraints it compiles down to is the <em>sum</em> of the cost of all branches.</li>
</ul>
<pre><code class="language-zokrates">def cheap(field x) -> field {
return x + 1;
}
def expensive(field x) -> field {
return x**1000;
}
def main(field x) -> field {
return if x == 1 {
cheap(x)
} else {
expensive(x) // both branches executed
};
}
</code></pre>
<ul>
<li><strong>An unsatisfied constraint inside any branch will make the whole execution fail, even if this branch is not logically executed</strong>. Also, the compiler itself inserts assertions which can fail. This can lead to unexpected results:</li>
</ul>
<pre><code class="language-zokrates">def main(field x) -> field {
return if x == 0 {
0
} else {
1 / x // executed even for x := 0, which leads to the execution failing
};
}
</code></pre>
<blockquote>
<p>The reason for these caveats is that the program is compiled down to an arithmetic circuit. This construct does not support jumping to a branch depending on a condition as you could do on traditional architectures. Instead, all branches are inlined as if they were printed on a circuit board.</p>
</blockquote>
<a class="header" href="#for-loops" id="for-loops"><h3>For loops</h3></a>
<p>For loops are available with the following syntax:</p>
<pre><code class="language-zokrates">def main() -> u32 {
u32 mut res = 0;
for u32 i in 0..4 {
for u32 j in i..5 {
res = res + i;
}
}
return res;
}
</code></pre>
<p>The bounds have to be constant at compile-time, therefore they cannot depend on execution inputs. They can depend on generic parameters.
The range is half-open, meaning it is bounded inclusively below and exclusively above. The range <code>start..end</code> contains all values within <code>start <= x < end</code>. The range is empty if <code>start >= end</code>.</p>
<blockquote>
<p>For loops are only syntactic sugar for repeating a block of statements many times. No condition of the type <code>index < max</code> is being checked at run-time after each iteration. Instead, at compile-time, the index is incremented and the block is executed again. Therefore, assigning to the loop index does not have any influence on the number of iterations performed and is considered bad practice.</p>
</blockquote>
<a class="header" href="#assertions" id="assertions"><h3>Assertions</h3></a>
<p>Any boolean can be asserted to be true using the <code>assert</code> function.</p>
<pre><code class="language-zokrates">def main() {
assert(1f + 1f == 2f);
return;
}
</code></pre>
<p>If any assertion fails, execution stops as no valid proof could be generated from it.</p>
<a class="header" href="#constants" id="constants"><h2>Constants</h2></a>
<p>Constants must be globally defined outside all other scopes by using a <code>const</code> keyword. Constants can be set only to a constant expression.</p>
<pre><code class="language-zokrates">const field PRIME = 31;
def main() -> field {
return PRIME;
}
</code></pre>
<p>The value of a constant can't be changed through reassignment, and it can't be redeclared.</p>
<p>Constants must be explicitly typed. One can reference other constants inside the expression, as long as the referenced constant is already defined.</p>
<pre><code class="language-zokrates">const field ONE = 1;
const field TWO = ONE + ONE;
def main() -> field {
return TWO;
}
</code></pre>
<p>The naming convention for constants are similar to that of variables. All characters in a constant name are usually in uppercase.</p>
<a class="header" href="#functions" id="functions"><h2>Functions</h2></a>
<p>Functions are declared using the <code>def</code> keyword. A function's signature has to be explicitly provided.
Its arguments are type annotated, just like variables, and, if the function returns a value,
the return type must be specified after an arrow <code>-></code>.</p>
<p>A function has to be declared at the top level before it is called.</p>
<pre><code class="language-zokrates">def foo(field a, field b) -> field {
return a + b;
}
def main() -> field {
return foo(1, 2);
}
</code></pre>
<p>A function can be generic over any number of values of type <code>u32</code>.</p>
<pre><code class="language-zokrates">def foo<N>() -> field[N] {
return [42; N];
}
def main() -> field[2] {
field[2] res = foo();
return res;
}
</code></pre>
<p>The generic parameters can be provided explicitly, especially when they cannot be inferred.</p>
<pre><code class="language-zokrates">// a function to sum the N first powers of a field element
def sum_powers<N>(field a) -> field {
field mut res = 0;
for u32 i in 0..N {
res = res + a ** i;
}
return res;
}
def main(field a) -> field {
// call `sum_powers` providing the explicit generic parameter `N := 5`
return sum_powers::<5>(a);
}
</code></pre>
<p>If the return type of a function is the empty tuple <code>()</code>, the return type as well as the return statement can be omitted.</p>
<pre><code class="language-zokrates">def main() {}
</code></pre>
<a class="header" href="#generics" id="generics"><h2>Generics</h2></a>
<p>ZoKrates supports code that is generic over constants of the <code>u32</code> type. No specific keyword is used: the compiler determines if the generic parameters are indeed constant at compile time. Here's an example of generic code in ZoKrates:</p>
<pre><code class="language-zokrates">def sum<N>(field[N] a) -> field {
field mut res = 0;
for u32 i in 0..N {
res = res + a[i];
}
return res;
}
def main(field[3] a) -> field {
return sum(a);
}
</code></pre>
<a class="header" href="#imports" id="imports"><h2>Imports</h2></a>
<p>You can separate your code into multiple ZoKrates files using <code>import</code> statements to import symbols, ignoring the <code>.zok</code> extension of the imported file.</p>
<a class="header" href="#import-syntax" id="import-syntax"><h3>Import syntax</h3></a>
<a class="header" href="#symbol-selection" id="symbol-selection"><h4>Symbol selection</h4></a>
<p>The preferred way to import a symbol is by module and name:</p>
<pre><code class="language-zokrates">from "./path/to/my/module" import MySymbol;
// `MySymbol` is now in scope.
</code></pre>
<p>To import multiple symbols with a single import statement, separate the symbols names with commas:</p>
<pre><code class="language-zokrates">from "./path/to/my/module" import MySymbol, MyOtherSymbol;
</code></pre>
<a class="header" href="#aliasing" id="aliasing"><h4>Aliasing</h4></a>
<p>The <code>as</code> keyword enables renaming symbols:</p>
<pre><code class="language-zokrates">from "./path/to/my/module" import MySymbol as MyAlias;
// `MySymbol` is now in scope under the alias MyAlias.
</code></pre>
<a class="header" href="#legacy" id="legacy"><h4>Legacy</h4></a>
<p>The legacy way to import a symbol is by only specifying a module:</p>
<pre><code>import "./path/to/my/module";
</code></pre>
<p>In this case, the name of the symbol is assumed to be <code>main</code> and the alias is assumed to be the module's filename so that the above is equivalent to</p>
<pre><code class="language-zokrates">from "./path/to/my/module" import main as module;
// `main` is now in scope under the alias `module`.
</code></pre>
<p>Note that this legacy method is likely to become deprecated, so it is recommended to use the preferred way instead.</p>
<a class="header" href="#symbols" id="symbols"><h3>Symbols</h3></a>
<p>Three types of symbols can be imported</p>
<a class="header" href="#functions-1" id="functions-1"><h4>Functions</h4></a>
<p>Functions are imported by name. If many functions have the same name but different signatures, all of them get imported, and which one to use in a particular call is inferred.</p>
<a class="header" href="#user-defined-types" id="user-defined-types"><h4>User-defined types</h4></a>
<p>User-defined types declared with the <code>struct</code> keyword are imported by name.</p>
<a class="header" href="#constants-1" id="constants-1"><h4>Constants</h4></a>
<p>Constants declared with the <code>const</code> keyword are imported by name.</p>
<a class="header" href="#relative-imports" id="relative-imports"><h3>Relative Imports</h3></a>
<p>You can import a resource in the same folder directly, like this:</p>
<pre><code class="language-zokrates">from "./mycode" import foo;
</code></pre>
<p>Imports up the file-system tree are supported:</p>
<pre><code class="language-zokrates">from "../../../mycode" import foo;
</code></pre>
<a class="header" href="#absolute-imports" id="absolute-imports"><h3>Absolute Imports</h3></a>
<p>Absolute imports don't start with <code>./</code> or <code>../</code> in the path and are used to import components from the ZoKrates standard library. Please check the according <a href="../toolbox/stdlib.html">section</a> for more details.</p>
<a class="header" href="#comments" id="comments"><h2>Comments</h2></a>
<a class="header" href="#inline-comments" id="inline-comments"><h2>Inline comments</h2></a>
<p>Inline (single-line) comments allow narrative on only one line at a time. Single-line comments can begin in any column of a given line and end at a new line or carriage return. Inline comments can be added with double-slashes.</p>
<pre><code class="language-zokrates">def main() -> field {
field a = 42; // this is an end of line comment
// this is a full line comment
return a;
}
</code></pre>
<a class="header" href="#multi-line-comments" id="multi-line-comments"><h2>Multi-line comments</h2></a>
<p>Multi-line comments have one or more lines of narrative within a set of comment delimiters. The <code>/*</code> delimiter marks the beginning of the comment, and the <code>*/</code> marks the end. Any content between those delimiters is considered a comment.</p>
<pre><code class="language-zokrates">/*
This is a multi-line comment
written in more than just one line.
*/
def main() -> field {
return 42;
}
</code></pre>
<a class="header" href="#macros" id="macros"><h2>Macros</h2></a>
<p>ZoKrates currently exposes a single macro:</p>
<pre><code>#pragma curve $CURVE
</code></pre>
<p>The effect of this macro is to abort compilation if this file is being compiled for a curve different from <code>$CURVE</code>.</p>
<a class="header" href="#logging" id="logging"><h2>Logging</h2></a>
<p>ZoKrates supports a command to log messages during execution in the interpreter.</p>
<p>The values of expressions can be checked and basic string interpolation is supported:</p>
<pre><code class="language-zokrates">struct Foo {
field[3] a;
bool b;
}
def main(Foo x, field y) {
log("x is {}, y is {}", x, y);
return;
}
</code></pre>
<p>By default, logs get removed during compilation. In order to include them in the compiled program, the <code>--debug</code> flag has to be enabled.</p>
<a class="header" href="#assembly" id="assembly"><h2>Assembly</h2></a>
<p>ZoKrates allows developers to define constraints through assembly blocks. Assembly blocks are considered <strong>unsafe</strong>, as safety and correctness of the resulting arithmetic circuit is in the hands of the developer. Usage of assembly is recommended only in optimization efforts for experienced developers to minimize constraint count of an arithmetic circuit.</p>
<blockquote>
<p>The usage of assembly blocks in ZoKrates is experimental. In particular, while assembly blocks help minimise constraint count in some cases, they currently can at the same time lead to larger compiler output and slower witness generation.</p>
</blockquote>
<a class="header" href="#writing-assembly" id="writing-assembly"><h2>Writing assembly</h2></a>
<p>All constraints must be enclosed within an <code>asm</code> block. In an assembly block we can do the following:</p>
<ol>
<li>Assign to a witness variable using <code><--</code></li>
<li>Define a constraint using <code>===</code></li>
</ol>
<p>Assigning a value, in general, should be combined with adding a constraint:</p>
<pre><code class="language-zok">def main(field a, field b) -> field {
field mut c = 0;
field mut invb = 0;
asm {
invb <-- b == 0 ? 0 : 1 / b;
invb * b === 1;
c <-- invb * a;
a === b * c;
}
return c;
}
</code></pre>
<blockquote>
<p>Note that operator <code><--</code> is used for unconstrained assignment and can be easily misused. This operator does not generate constraints, which could result in unconstrained variables in the constraint system.</p>
</blockquote>
<p>Unconstrained assignment <code><--</code> allows assignment to variables with complex types. The type must consist of field elements only (eg. <code>field[3]</code>):</p>
<pre><code class="language-zok">field[3] mut c = [0; 3];
asm {
c <-- [2, 2, 4];
c[0] * c[1] === c[2];
}
</code></pre>
<p>In some cases we can combine the witness assignment and constraint generation with the <code><==</code> operator (constrained assignment):</p>
<pre><code class="language-zok">asm {
c <== 1 - a*b;
}
</code></pre>
<p>which is equivalent to:</p>
<pre><code class="language-zok">asm {
c <-- 1 - a*b;
c === 1 - a*b;
}
</code></pre>
<p>In the case of constrained assignment <code><==</code>, both sides of the statement have to be of type <code>field</code>.</p>
<p>A constraint can contain arithmetic expressions that are built using multiplication, addition, and other variables or <code>field</code> values. Only quadratic expressions are allowed to be included in constraints. Non-quadratic expressions or usage of other arithmetic operators like division or power are not allowed as constraints, but can be used in the witness assignment expression.</p>
<p>The following code is not allowed:</p>
<pre><code class="language-zok">asm {
d === a*b*c;
}
</code></pre>
<p>as the constraint <code>d === a*b*c</code> is not quadratic.</p>
<p>In some cases, ZoKrates will apply minor transformations on the defined constraints in order to meet the correct format:</p>
<pre><code class="language-zok">asm {
x * (x - 1) === 0;
}
</code></pre>
<p>will be transformed to:</p>
<pre><code class="language-zok">asm {
x === x * x;
}
</code></pre>
<a class="header" href="#type-casting" id="type-casting"><h2>Type casting</h2></a>
<p>Assembly is a low-level part of the compiler which does not have type safety. In some cases we might want to do zero-cost conversions between <code>field</code> and <code>bool</code> type.</p>
<a class="header" href="#field_to_bool_unsafe" id="field_to_bool_unsafe"><h3>field_to_bool_unsafe</h3></a>
<p>This call is unsafe because it is the responsibility of the user to constrain the field input:</p>
<pre><code class="language-zok">from "EMBED" import field_to_bool_unsafe;
def main(field x) -> bool {
// we constrain `x` to be 0 or 1
asm {
x * (x - 1) === 0;
}
// we can convert `x` to `bool` afterwards, as we constrained it properly
// if we failed to constrain `x` to `0` or `1`, the call to `field_to_bool_unsafe` introduces undefined behavior
// `field_to_bool_unsafe` call does not produce any extra constraints
bool out = field_to_bool_unsafe(x);
return out;
}
</code></pre>
<a class="header" href="#zokrates-reference" id="zokrates-reference"><h1>ZoKrates Reference</h1></a>
<p>The reference covers the details of the ZoKrates toolbox beyond the ZoKrates language.</p>
<a class="header" href="#command-line-tool" id="command-line-tool"><h1>Command Line Tool</h1></a>
<p>ZoKrates provides a command line interface.
You can see an overview of the available subcommands by running</p>
<pre><code class="language-sh">zokrates
</code></pre>
<p>You can get help about a particular subcommand with <code>--help</code>, for example:</p>
<pre><code class="language-sh">zokrates compile --help
</code></pre>
<a class="header" href="#performing-a-trusted-setup-using-a-multi-party-computation-protocol-mpc" id="performing-a-trusted-setup-using-a-multi-party-computation-protocol-mpc"><h1>Performing a trusted setup using a multi-party computation protocol (MPC)</h1></a>
<p>The zk-SNARK schemes supported by ZoKrates require a trusted setup. This procedure must be run to generate the proving and verification keys. This procedure generates some data often referred to as "toxic waste" which can be used to create fake proofs which will be accepted by the verifier. The entity running the trusted setup is trusted to delete this toxic waste.
Using an MPC protocol, we can run the trusted setup in a decentralized way, so that this responsibility is shared among all participants of the setup. If at least one participant is honest and deletes their part of the toxic waste, then no fake proofs can be created by anyone.
This section of the book describes the steps to perform a trusted setup for the Groth16 scheme.</p>
<a class="header" href="#pre-requisites" id="pre-requisites"><h2>Pre-requisites</h2></a>
<p>The trusted setup is done in two steps. The first step, also known as "phase 1", does not depend on the program and is called Powers of Tau. The second step is called "phase 2" and is circuit-specific, so it should be done separately for each different program. The Ethereum community runs a phase 1 setup called <a href="https://github.com/weijiekoh/perpetualpowersoftau">Perpetual Powers of Tau</a>, whose output we can use. Therefore, we only need to run phase 2 of the setup.</p>
<a class="header" href="#compiling-a-circuit" id="compiling-a-circuit"><h2>Compiling a circuit</h2></a>
<p>We will start this tutorial by using ZoKrates to compile a basic program.
First, we create a new file named <code>program.zok</code> with the following content:</p>
<pre><code class="language-zokrates">def main(private field a, private field b) -> field {
return a * b;
}
</code></pre>
<p>We compile the program using the <code>compile</code> command.</p>
<pre><code>zokrates compile -i program.zok -o circuit
</code></pre>
<a class="header" href="#initializing-a-phase-2-ceremony" id="initializing-a-phase-2-ceremony"><h2>Initializing a phase 2 ceremony</h2></a>
<p>We then initialize a phase 2 ceremony with the following command:</p>
<pre><code>$ zokrates mpc init -i circuit -o mpc.params -r ./phase1radix2m2
Initializing MPC...
Parameters written to `mpc.params`
</code></pre>
<p>Using the <code>-r</code> flag, we pass a path to the file which contains the parameters for our circuit with depth <code>2^n</code> (<code>phase1radix2m{n}</code>).
The parameters for various circuit depths can be computed using the <a href="https://github.com/kobigurk/phase2-bn254">phase2-bn254</a> utility
by picking the latest response from the <a href="https://github.com/weijiekoh/perpetualpowersoftau">Perpetual Powers of Tau</a> and following the instructions in the mentioned repositories.</p>
<a class="header" href="#making-a-contribution" id="making-a-contribution"><h2>Making a contribution</h2></a>
<p>In this example, we will conduct a ceremony that has 3 participants: Alice, Bob, and Charlie.
Participants will run the contributions in sequential order, managed by the coordinator (us).</p>
<p>Firstly, our initial <code>mpc.params</code> file is given to Alice who runs the following command:</p>
<pre><code>$ zokrates mpc contribute -i mpc.params -o alice.params -e "alice 1"
Contributing to `mpc.params`...
The BLAKE2b hash of your contribution is:
4ebf1359 416fbc42 31af6476 9173cb33
32b8c2f9 475d143a 25634a5c e461eb67
5f7738b1 6478a020 7ec9d365 9170bca6
154b31df d307b78e ca0c025f 59c5a7fb
Your contribution has been written to `alice.params`
</code></pre>
<p>Alice must give some randomness to the contribution, which is done by the <code>-e</code> flag.</p>
<p>Examples of entropy sources:</p>
<ul>
<li><code>/dev/urandom</code> from one or more devices</li>
<li>The most recent block hash</li>
<li>Randomly mashing keys on the keyboard</li>
</ul>
<p>Secondly, the output file <code>alice.params</code> is sent to Bob who runs his contribution:</p>
<pre><code>$ zokrates mpc contribute -i alice.params -o bob.params -e "bob 2"
Contributing to `alice.params`...
The BLAKE2b hash of your contribution is:
1a4e0d17 449b00ec f31d2072 59bc173c
f30f6dbd 78c81921 869091a8 e40f454e
8c8d72e8 395bf044 cd777842 b6ab1d88
9e24cf7f 7d88b473 2190fb0c 730fb6fc
Your contribution has been written to `bob.params`
</code></pre>
<p>Thirdly, with the same procedure as above, Charlie makes his contribution on top of Bob's:</p>
<pre><code>$ zokrates mpc contribute -i bob.params -o charlie.params -e "charlie 3"
Contributing to `bob.params`...
The BLAKE2b hash of your contribution is:
46dc6c01 ec778382 93b333b2 116a4bfb
a9aca5dd eb6945f1 cbe07cda 6ffb3ffd
cf4e4736 62fe2339 166d5b87 db392ca6
d2e87e36 92cc8f0e e618298f c3f7caf1
Your contribution has been written to `charlie.params`
</code></pre>
<a class="header" href="#applying-a-random-beacon" id="applying-a-random-beacon"><h2>Applying a random beacon</h2></a>
<p>To finalize the ceremony, we can apply a random beacon to get the final parameters:</p>
<pre><code>$ zokrates mpc beacon -i charlie.params -o final.params -h b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 -n 10
Creating a beacon RNG
0: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
1: bc62d4b80d9e36da29c16c5d4d9f11731f36052c72401a76c23c0fb5a9b74423
2: 76dfcb21a877aaeba06b3269d08dc2ed1d38c62ffec132800b46e94b14f72938
...removed for brevity
1022: dd842dc43d9ac5c6dff74cca18405123761d17edd36724b092ef57c237b31291
1023: a11c8a03c22e9c31c037aa0085c061ba8dd19a3f599314570702eeef1baacd79
Final result of beacon: ef8faec4fc31faf341f368084b82d267d380992e905c923a179e0717ce39708d
Contributing to `charlie.params`...
The BLAKE2b hash of your contribution is:
83d67a6f 935fc4d0 5733ebed d43f2074
5425b105 9a32a315 a790668a f5a1f021
66f840e2 e6a5d441 38593163 5b86df09
a00f352e 2ad2a88b ede07886 2134b889
Your contribution has been written to `final.params`
</code></pre>
<p>The random beacon is the <code>2^n</code> iteration of <code>SHA256</code> over the hash evaluated on
some high entropy and publicly available data. Possible sources of data could be:</p>
<ul>
<li>The closing value of the stock market on a certain date</li>
<li>The output of a selected set of national lotteries</li>
<li>The value of a block at a particular height in one or more blockchains</li>
<li><a href="https://www.cloudflare.com/leagueofentropy/">League of Entropy</a> (drand)</li>
</ul>
<a class="header" href="#verifying-contributions" id="verifying-contributions"><h2>Verifying contributions</h2></a>
<p>At any point in the ceremony we can verify contributions by running the following command:</p>
<pre><code>$ zokrates mpc verify -i final.params -c circuit -r ./phase1radix2m2
Verifying contributions...
Transcript contains 4 contributions:
0: 4ebf1359416fbc4231af64769173cb3332b8c2f9475d143a25634a5ce461eb675f7738b16478a0207ec9d3659170bca6154b31dfd307b78eca0c025f59c5a7fb
1: 1a4e0d17449b00ecf31d207259bc173cf30f6dbd78c81921869091a8e40f454e8c8d72e8395bf044cd777842b6ab1d889e24cf7f7d88b4732190fb0c730fb6fc
2: 46dc6c01ec77838293b333b2116a4bfba9aca5ddeb6945f1cbe07cda6ffb3ffdcf4e473662fe2339166d5b87db392ca6d2e87e3692cc8f0ee618298fc3f7caf1
3: 83d67a6f935fc4d05733ebedd43f20745425b1059a32a315a790668af5a1f02166f840e2e6a5d441385931635b86df09a00f352e2ad2a88bede078862134b889
Contributions verified
</code></pre>
<a class="header" href="#exporting-keys" id="exporting-keys"><h2>Exporting keys</h2></a>
<p>Once the ceremony is finalized, we can export the keys and use them to generate proofs and verify them.</p>
<pre><code># export keys from final parameters (proving and verification key)
zokrates mpc export -i final.params
# use the keys to generate proofs and verify
zokrates compute-witness -i circuit -a 123456789 987654321 --verbose
zokrates generate-proof -i circuit -b bellman
zokrates verify -b bellman
</code></pre>
<a class="header" href="#conclusion" id="conclusion"><h2>Conclusion</h2></a>
<p>The secure generation of parameters for zk-SNARKs is a crucial step in the trustworthiness of the resulting proof system.
The security of the ceremony relies entirely on the fact that at least one participant needs to securely delete their "toxic waste" for the resulting parameters to be generated honestly.
Opening the ceremony to a large number of participants reduces the probability that the resulting parameters are dishonest.
Once the ceremony is finalized, we can generate a verifier smart contract by using the keys we obtained through the trusted setup ceremony.
At this point, we can safely deploy the contract and verify proofs on-chain.</p>
<a class="header" href="#standard-library" id="standard-library"><h2>Standard library</h2></a>
<p>ZoKrates comes with a number of reusable components in the form of a Standard Library. In order to import it as described in the <a href="../language/imports.html">imports</a> section, the <code>$ZOKRATES_STDLIB</code> environment variable must be set to the <code>stdlib</code> folder.</p>
<p>The full ZoKrates Standard Library can be found <a href="https://github.com/Zokrates/ZoKrates/tree/latest/zokrates_stdlib/stdlib">here</a>.</p>
<a class="header" href="#hashes" id="hashes"><h3>Hashes</h3></a>
<a class="header" href="#sha256" id="sha256"><h4>SHA256</h4></a>
<p>We provide an implementation of the SHA256 function from the SHA-2 family of secure hash functions <sup class="footnote-reference"><a href="#1">1</a></sup>. The hash functions of the SHA-2 family are considered to be pseudorandom.</p>
<p>SHA256 is available in Ethereum as a pre-compiled contract and thus a hash function that is cheap to evaluate in the EVM. However, the implementation inside a circuit is comparatively expensive, as it is defined for binary in- and outputs and heavily relies on bit manipulation.</p>
<a class="header" href="#pedersen-hashes" id="pedersen-hashes"><h4>Pedersen Hashes</h4></a>
<p>The pedersen hash function is inspired by a commitment scheme published by Pedersen <sup class="footnote-reference"><a href="#2">2</a></sup>.
This hash function’s security is based on the discrete logarithm problem.
Pedersen-hashes cannot be assumed to be pseudorandom and should therefore not be used where a hash function serves as a random oracle.</p>
<p>In the EVM, operations on the BabyJubJub curve are not natively supported. Therefore, Pedersen hashes are expensive to evaluate on-chain and should be avoided.</p>
<p>By definition, the Pedersen hash function has a fixed-length binary input and outputs a group element, i.e., a point on the BabyJubJub elliptic curve in our case.</p>
<a class="header" href="#mimc" id="mimc"><h4>MiMC</h4></a>
<p>The MiMC hash function was designed by using the MiMC-Feistel permutation <sup class="footnote-reference"><a href="#3">3</a></sup> over a prime field in a sponge construction <sup class="footnote-reference"><a href="#4">4</a></sup> to arrive at a secure and efficiently provable hash function.
The construction is based on established hash function design principles from symmetric cryptography but is still novel and should thus be used cautiously. MiMC hashes are considered to be pseudorandom.</p>
<p>Due to its native use of prime field arithmetics, MiMC hash functions are efficient in circuits. At the same time, they can be evaluated by the EVM with comparatively little overhead.</p>
<p>The MiMC hash function maps from field elements to field elements; applying the function to its output again does not introduce overhead for packing/unpacking.</p>
<a class="header" href="#elliptic-curve-cryptography" id="elliptic-curve-cryptography"><h3>Elliptic curve cryptography</h3></a>
<p>Thanks to the existence of BabyJubJub, an efficient elliptic curve embedded in ALT_BN128, we provide tools to perform elliptic curve operations such as:</p>
<ul>
<li>Point operations</li>
<li>Proving knowledge of a private EdDSA key</li>
<li>Proving validity of an EdDSA signature</li>
</ul>
<p>Check out this <a href="https://github.com/Zokrates/pycrypto">python repository</a> for tooling, for example to generate EdDSA signatures to then check in a SNARK.</p>
<a class="header" href="#utils" id="utils"><h3>Utils</h3></a>
<a class="header" href="#packing--unpacking" id="packing--unpacking"><h4>Packing / Unpacking</h4></a>