grapevine-sonobe/circom/node_modules/circomlib/circuits/pointbits.circom
circom/node_modules/circomlib/circuits/pointbits.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 "bitify.circom";
22include "aliascheck.circom";
23include "compconstant.circom";
24include "babyjub.circom";
25
26
27function sqrt(n) {
28
29 if (n == 0) {
30 return 0;
31 }
32
33 // Test that have solution
34 var res = n ** ((-1) >> 1);
35// if (res!=1) assert(false, "SQRT does not exists");
36 if (res!=1) return 0;
37
38 var m = 28;
39 var c = 19103219067921713944291392827692070036145651957329286315305642004821462161904;
40 var t = n ** 81540058820840996586704275553141814055101440848469862132140264610111;
41 var r = n ** ((81540058820840996586704275553141814055101440848469862132140264610111+1)>>1);
42 var sq;
43 var i;
44 var b;
45 var j;
46
47 while ((r != 0)&&(t != 1)) {
48 sq = t*t;
49 i = 1;
50 while (sq!=1) {
51 i++;
52 sq = sq*sq;
53 }
54
55 // b = c ^ m-i-1
56 b = c;
57 for (j=0; j< m-i-1; j ++) b = b*b;
58
59 m = i;
60 c = b*b;
61 t = t*c;
62 r = r*b;
63 }
64
65 if (r < 0 ) {
66 r = -r;
67 }
68
69 return r;
70}
71
72
73template Bits2Point() {
74 signal input in[256];
75 signal output out[2];
76}
77
78template Bits2Point_Strict() {
79 signal input in[256];
80 signal output out[2];
81
82 var i;
83
84 // Check aliasing
85 component aliasCheckY = AliasCheck();
86 for (i=0; i<254; i++) {
87 aliasCheckY.in[i] <== in[i];
88 }
89 in[254] === 0;
90
91 component b2nY = Bits2Num(254);
92 for (i=0; i<254; i++) {
93 b2nY.in[i] <== in[i];
94 }
95
96 out[1] <== b2nY.out;
97
98 var a = 168700;
99 var d = 168696;
100
101 var y2 = out[1] * out[1];
102
103 var x = sqrt( (1-y2)/(a - d*y2) );
104
105 if (in[255] == 1) x = -x;
106
107 out[0] <-- x;
108
109 component babyCheck = BabyCheck();
110 babyCheck.x <== out[0];
111 babyCheck.y <== out[1];
112
113 component n2bX = Num2Bits(254);
114 n2bX.in <== out[0];
115 component aliasCheckX = AliasCheck();
116 for (i=0; i<254; i++) {
117 aliasCheckX.in[i] <== n2bX.out[i];
118 }
119
120 component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808);
121 for (i=0; i<254; i++) {
122 signCalc.in[i] <== n2bX.out[i];
123 }
124
125 signCalc.out === in[255];
126}
127
128
129template Point2Bits() {
130 signal input in[2];
131 signal output out[256];
132
133
134}
135
136template Point2Bits_Strict() {
137 signal input in[2];
138 signal output out[256];
139
140 var i;
141
142 component n2bX = Num2Bits(254);
143 n2bX.in <== in[0];
144 component n2bY = Num2Bits(254);
145 n2bY.in <== in[1];
146
147 component aliasCheckX = AliasCheck();
148 component aliasCheckY = AliasCheck();
149 for (i=0; i<254; i++) {
150 aliasCheckX.in[i] <== n2bX.out[i];
151 aliasCheckY.in[i] <== n2bY.out[i];
152 }
153
154 component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808);
155 for (i=0; i<254; i++) {
156 signCalc.in[i] <== n2bX.out[i];
157 }
158
159 for (i=0; i<254; i++) {
160 out[i] <== n2bY.out[i];
161 }
162 out[254] <== 0;
163 out[255] <== signCalc.out;
164}