grapevine-sonobe/circom/node_modules/circomlib/circuits/eddsa.circom
circom/node_modules/circomlib/circuits/eddsa.circomRaw
1/*
2 Copyright 2018 0KIMS association.
3
4 This file is part of circom (Zero Knowledge Circuit Compiler).
5
6 circom is a free software: you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 circom is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with circom. If not, see <https://www.gnu.org/licenses/>.
18*/
19pragma circom 2.0.0;
20
21include "compconstant.circom";
22include "pointbits.circom";
23include "pedersen.circom";
24include "escalarmulany.circom";
25include "escalarmulfix.circom";
26
27template EdDSAVerifier(n) {
28 signal input msg[n];
29
30 signal input A[256];
31 signal input R8[256];
32 signal input S[256];
33
34 signal Ax;
35 signal Ay;
36
37 signal R8x;
38 signal R8y;
39
40 var i;
41
42// Ensure S<Subgroup Order
43
44 component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
45
46 for (i=0; i<254; i++) {
47 S[i] ==> compConstant.in[i];
48 }
49 compConstant.out === 0;
50 S[254] === 0;
51 S[255] === 0;
52
53// Convert A to Field elements (And verify A)
54
55 component bits2pointA = Bits2Point_Strict();
56
57 for (i=0; i<256; i++) {
58 bits2pointA.in[i] <== A[i];
59 }
60 Ax <== bits2pointA.out[0];
61 Ay <== bits2pointA.out[1];
62
63// Convert R8 to Field elements (And verify R8)
64
65 component bits2pointR8 = Bits2Point_Strict();
66
67 for (i=0; i<256; i++) {
68 bits2pointR8.in[i] <== R8[i];
69 }
70 R8x <== bits2pointR8.out[0];
71 R8y <== bits2pointR8.out[1];
72
73// Calculate the h = H(R,A, msg)
74
75 component hash = Pedersen(512+n);
76
77 for (i=0; i<256; i++) {
78 hash.in[i] <== R8[i];
79 hash.in[256+i] <== A[i];
80 }
81 for (i=0; i<n; i++) {
82 hash.in[512+i] <== msg[i];
83 }
84
85 component point2bitsH = Point2Bits_Strict();
86 point2bitsH.in[0] <== hash.out[0];
87 point2bitsH.in[1] <== hash.out[1];
88
89// Calculate second part of the right side: right2 = h*8*A
90
91 // Multiply by 8 by adding it 3 times. This also ensure that the result is in
92 // the subgroup.
93 component dbl1 = BabyDbl();
94 dbl1.x <== Ax;
95 dbl1.y <== Ay;
96 component dbl2 = BabyDbl();
97 dbl2.x <== dbl1.xout;
98 dbl2.y <== dbl1.yout;
99 component dbl3 = BabyDbl();
100 dbl3.x <== dbl2.xout;
101 dbl3.y <== dbl2.yout;
102
103 // We check that A is not zero.
104 component isZero = IsZero();
105 isZero.in <== dbl3.x;
106 isZero.out === 0;
107
108 component mulAny = EscalarMulAny(256);
109 for (i=0; i<256; i++) {
110 mulAny.e[i] <== point2bitsH.out[i];
111 }
112 mulAny.p[0] <== dbl3.xout;
113 mulAny.p[1] <== dbl3.yout;
114
115
116// Compute the right side: right = R8 + right2
117
118 component addRight = BabyAdd();
119 addRight.x1 <== R8x;
120 addRight.y1 <== R8y;
121 addRight.x2 <== mulAny.out[0];
122 addRight.y2 <== mulAny.out[1];
123
124// Calculate left side of equation left = S*B8
125
126 var BASE8[2] = [
127 5299619240641551281634865583518297030282874472190772894086521144482721001553,
128 16950150798460657717958625567821834550301663161624707787222815936182638968203
129 ];
130 component mulFix = EscalarMulFix(256, BASE8);
131 for (i=0; i<256; i++) {
132 mulFix.e[i] <== S[i];
133 }
134
135// Do the comparation left == right
136
137 mulFix.out[0] === addRight.xout;
138 mulFix.out[1] === addRight.yout;
139}