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