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