circomlib/circuits/montgomery.circom
circuits/montgomery.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*/
19
20/*
21 Source: https://en.wikipedia.org/wiki/Montgomery_curve
22
23 1 + y 1 + y
24 [u, v] = [ ------- , ---------- ]
25 1 - y (1 - y)x
26
27 */
28
29template Edwards2Montgomery() {
30 signal input in[2];
31 signal output out[2];
32
33 out[0] <-- (1 + in[1]) / (1 - in[1]);
34 out[1] <-- out[0] / in[0];
35
36
37 out[0] * (1-in[1]) === (1 + in[1]);
38 out[1] * in[0] === out[0];
39}
40
41/*
42
43 u u - 1
44 [x, y] = [ ---, ------- ]
45 v u + 1
46
47 */
48template Montgomery2Edwards() {
49 signal input in[2];
50 signal output out[2];
51
52 out[0] <-- in[0] / in[1];
53 out[1] <-- (in[0] - 1) / (in[0] + 1);
54
55 out[0] * in[1] === in[0];
56 out[1] * (in[0] + 1) === in[0] - 1;
57}
58
59
60/*
61 x2 - x1
62 lamda = ---------
63 y2 - y1
64
65 x3 + A + x1 + x2
66 x3 = B * lamda^2 - A - x1 -x2 => lamda^2 = ------------------
67 B
68
69 y3 = (2*x1 + x2 + A)*lamda - B*lamda^3 - y1 =>
70
71
72 => y3 = lamda * ( 2*x1 + x2 + A - x3 - A - x1 - x2) - y1 =>
73
74 => y3 = lamda * ( x1 - x3 ) - y1
75
76----------
77
78 y2 - y1
79 lamda = ---------
80 x2 - x1
81
82 x3 = B * lamda^2 - A - x1 -x2
83
84 y3 = lamda * ( x1 - x3 ) - y1
85
86 */
87
88template MontgomeryAdd() {
89 signal input in1[2];
90 signal input in2[2];
91 signal output out[2];
92
93 var a = 168700;
94 var d = 168696;
95
96 var A = (2 * (a + d)) / (a - d);
97 var B = 4 / (a - d);
98
99 signal lamda;
100
101 lamda <-- (in2[1] - in1[1]) / (in2[0] - in1[0]);
102 lamda * (in2[0] - in1[0]) === (in2[1] - in1[1]);
103
104 out[0] <== B*lamda*lamda - A - in1[0] -in2[0];
105 out[1] <== lamda * (in1[0] - out[0]) - in1[1];
106}
107
108/*
109
110 x1_2 = x1*x1
111
112 3*x1_2 + 2*A*x1 + 1
113 lamda = ---------------------
114 2*B*y1
115
116 x3 = B * lamda^2 - A - x1 -x1
117
118 y3 = lamda * ( x1 - x3 ) - y1
119
120 */
121template MontgomeryDouble() {
122 signal input in[2];
123 signal output out[2];
124
125 var a = 168700;
126 var d = 168696;
127
128 var A = (2 * (a + d)) / (a - d);
129 var B = 4 / (a - d);
130
131 signal lamda;
132 signal x1_2;
133
134 x1_2 <== in[0] * in[0];
135
136 lamda <-- (3*x1_2 + 2*A*in[0] + 1 ) / (2*B*in[1]);
137 lamda * (2*B*in[1]) === (3*x1_2 + 2*A*in[0] + 1 );
138
139 out[0] <== B*lamda*lamda - A - 2*in[0];
140 out[1] <== lamda * (in[0] - out[0]) - in[1];
141}