You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
3.6 KiB

6 years ago
  1. /*
  2. Copyright 2018 0KIMS association.
  3. This file is part of circom (Zero Knowledge Circuit Compiler).
  4. circom is a free software: you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. circom is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  11. License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with circom. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. include "bitify.circom";
  16. include "aliascheck.circom";
  17. include "compconstant.circom";
  18. include "babyjub.circom";
  19. function sqrt(n) {
  20. if (n == 0) {
  21. return 0;
  22. }
  23. // Test that have solution
  24. var res = n ** ((-1) >> 1);
  25. // if (res!=1) assert(false, "SQRT does not exists");
  26. if (res!=1) return 0;
  27. var m = 28;
  28. var c = 19103219067921713944291392827692070036145651957329286315305642004821462161904;
  29. var t = n ** 81540058820840996586704275553141814055101440848469862132140264610111;
  30. var r = n ** ((81540058820840996586704275553141814055101440848469862132140264610111+1)>>1);
  31. var sq;
  32. var i;
  33. var b;
  34. var j;
  35. while ((r != 0)&&(t != 1)) {
  36. sq = t*t;
  37. i = 1;
  38. while (sq!=1) {
  39. i++;
  40. sq = sq*sq;
  41. }
  42. // b = c ^ m-i-1
  43. b = c;
  44. for (j=0; j< m-i-1; j ++) b = b*b;
  45. m = i;
  46. c = b*b;
  47. t = t*c;
  48. r = r*b;
  49. }
  50. if (r > ((-1) >> 1)) {
  51. r = -r;
  52. }
  53. return r;
  54. }
  55. template Bits2Point() {
  56. signal input in[256];
  57. signal output out[2];
  58. }
  59. template Bits2Point_Strict() {
  60. signal input in[256];
  61. signal output out[2];
  62. var i;
  63. // Check aliasing
  64. component aliasCheckY = AliasCheck();
  65. for (i=0; i<254; i++) {
  66. aliasCheckY.in[i] <== in[i];
  67. }
  68. in[254] === 0;
  69. component b2nY = Bits2Num(254);
  70. for (i=0; i<254; i++) {
  71. b2nY.in[i] <== in[i];
  72. }
  73. out[1] <== b2nY.out;
  74. var a = 168700;
  75. var d = 168696;
  76. var y2 = out[1] * out[1];
  77. var x = sqrt( (1-y2)/(a - d*y2) );
  78. if (in[255] == 1) x = -x;
  79. out[0] <-- x;
  80. component babyCheck = BabyCheck();
  81. babyCheck.x <== out[0];
  82. babyCheck.y <== out[1];
  83. component n2bX = Num2Bits(254);
  84. n2bX.in <== out[0];
  85. component aliasCheckX = AliasCheck();
  86. for (i=0; i<254; i++) {
  87. aliasCheckX.in[i] <== n2bX.out[i];
  88. }
  89. component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808);
  90. for (i=0; i<254; i++) {
  91. signCalc.in[i] <== n2bX.out[i];
  92. }
  93. signCalc.out === in[255];
  94. }
  95. template Point2Bits() {
  96. signal input in[2];
  97. signal output out[256];
  98. }
  99. template Point2Bits_Strict() {
  100. signal input in[2];
  101. signal output out[256];
  102. var i;
  103. component n2bX = Num2Bits(254);
  104. n2bX.in <== in[0];
  105. component n2bY = Num2Bits(254);
  106. n2bY.in <== in[1];
  107. component aliasCheckX = AliasCheck();
  108. component aliasCheckY = AliasCheck();
  109. for (i=0; i<254; i++) {
  110. aliasCheckX.in[i] <== n2bX.out[i];
  111. aliasCheckY.in[i] <== n2bY.out[i];
  112. }
  113. component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808);
  114. for (i=0; i<254; i++) {
  115. signCalc.in[i] <== n2bX.out[i];
  116. }
  117. for (i=0; i<254; i++) {
  118. out[i] <== n2bY.out[i];
  119. }
  120. out[254] <== 0;
  121. out[255] <== signCalc.out;
  122. }