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.

217 lines
7.0 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. /*
  2. Copyright 2018 0kims association.
  3. This file is part of zksnark JavaScript library.
  4. zksnark JavaScript library is a free software: you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License as published by the
  6. Free Software Foundation, either version 3 of the License, or (at your option)
  7. any later version.
  8. zksnark JavaScript library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. more details.
  12. You should have received a copy of the GNU General Public License along with
  13. zksnark JavaScript library. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. const chai = require("chai");
  16. const bigInt = require("../src/bigint.js");
  17. const PolField = require("../src/polfield.js");
  18. const ZqField = require("../src/zqfield");
  19. const assert = chai.assert;
  20. const r = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  21. describe("Polynomial field", () => {
  22. it("Should compute a multiplication", () => {
  23. const PF = new PolField(new ZqField(r));
  24. const a = [bigInt(1), bigInt(2), bigInt(3)];
  25. const b = [bigInt(1), bigInt(2), bigInt(3)];
  26. const res = PF.mul(a,b);
  27. assert(PF.equals(res, [bigInt(1), bigInt(4), bigInt(10), bigInt(12), bigInt(9)]));
  28. });
  29. it("Should compute a multiplication 2", () => {
  30. const PF = new PolField(new ZqField(r));
  31. const a = [bigInt(5), bigInt(1)];
  32. const b = [bigInt(-5), bigInt(1)];
  33. const res = PF.mul(a,b);
  34. assert(PF.equals(res, [bigInt(-25), bigInt(0), bigInt(1)]));
  35. });
  36. it("Should compute an addition", () => {
  37. const PF = new PolField(new ZqField(r));
  38. const a = [bigInt(5), bigInt(1)];
  39. const b = [bigInt(-5), bigInt(1)];
  40. const res = PF.add(a,b);
  41. assert(PF.equals(res, [bigInt(0), bigInt(2)]));
  42. });
  43. it("Should compute a substraction", () => {
  44. const PF = new PolField(new ZqField(r));
  45. const a = [bigInt(5), bigInt(3), bigInt(4)];
  46. const b = [bigInt(5), bigInt(1)];
  47. const res = PF.sub(a,b);
  48. assert(PF.equals(res, [bigInt(0), bigInt(2), bigInt(4)]));
  49. });
  50. it("Should compute reciprocal", () => {
  51. const PF = new PolField(new ZqField(r));
  52. const a = [bigInt(4), bigInt(1), bigInt(-3), bigInt(-1), bigInt(2),bigInt(1), bigInt(-1), bigInt(1)];
  53. const res = PF._reciprocal(a, 3, 0);
  54. assert(PF.equals(res, [bigInt(12), bigInt(15), bigInt(3), bigInt(-4), bigInt(-3), bigInt(0), bigInt(1), bigInt(1)]));
  55. });
  56. it("Should div2", () => {
  57. const PF = new PolField(new ZqField(r));
  58. // x^6
  59. const a = [bigInt(0), bigInt(0), bigInt(0), bigInt(0), bigInt(0),bigInt(0), bigInt(1)];
  60. // x^5
  61. const b = [bigInt(0), bigInt(0), bigInt(0), bigInt(0), bigInt(0), bigInt(1)];
  62. const res = PF._div2(6, b);
  63. assert(PF.equals(res, [bigInt(0), bigInt(1)]));
  64. const res2 = PF.div(a,b);
  65. assert(PF.equals(res2, [bigInt(0), bigInt(1)]));
  66. });
  67. it("Should div", () => {
  68. const PF = new PolField(new ZqField(r));
  69. const a = [bigInt(1), bigInt(2), bigInt(3), bigInt(4), bigInt(5),bigInt(6), bigInt(7)];
  70. const b = [bigInt(8), bigInt(9), bigInt(10), bigInt(11), bigInt(12), bigInt(13)];
  71. const c = PF.mul(a,b);
  72. const d = PF.div(c,b);
  73. assert(PF.equals(a, d));
  74. });
  75. it("Should div big/small", () => {
  76. const PF = new PolField(new ZqField(r));
  77. const a = [bigInt(1), bigInt(2), bigInt(3), bigInt(4), bigInt(5),bigInt(6), bigInt(7)];
  78. const b = [bigInt(8), bigInt(9)];
  79. const c = PF.mul(a,b);
  80. const d = PF.div(c,b);
  81. assert(PF.equals(a, d));
  82. });
  83. it("Should div random big", () => {
  84. const PF = new PolField(new ZqField(r));
  85. const a = [];
  86. const b = [];
  87. for (let i=0; i<1000; i++) a.push(bigInt(Math.floor(Math.random()*100000) -500000));
  88. for (let i=0; i<900; i++) b.push(bigInt(Math.floor(Math.random()*100000) -500000));
  89. const c = PF.mul(a,b);
  90. const d = PF.div(c,b);
  91. assert(PF.equals(a, d));
  92. }).timeout(10000);
  93. it("Should evaluate and zero", () => {
  94. const PF = new PolField(new ZqField(r));
  95. const p = [PF.F.neg(bigInt(2)), bigInt(1)];
  96. const v = PF.eval(p, bigInt(2));
  97. assert(PF.F.equals(v, bigInt(0)));
  98. });
  99. it("Should evaluate bigger number", () => {
  100. const PF = new PolField(new ZqField(r));
  101. const p = [bigInt(1), bigInt(2), bigInt(3)];
  102. const v = PF.eval(p, bigInt(2));
  103. assert(PF.F.equals(v, bigInt(17)));
  104. });
  105. it("Should create lagrange polynomial minmal", () => {
  106. const PF = new PolField(new ZqField(r));
  107. const points=[];
  108. points.push([bigInt(1), bigInt(1)]);
  109. points.push([bigInt(2), bigInt(2)]);
  110. points.push([bigInt(3), bigInt(5)]);
  111. const p=PF.lagrange(points);
  112. for (let i=0; i<points.length; i++) {
  113. const v = PF.eval(p, points[i][0]);
  114. assert(PF.F.equals(v, points[i][1]));
  115. }
  116. });
  117. it("Should create lagrange polynomial", () => {
  118. const PF = new PolField(new ZqField(r));
  119. const points=[];
  120. points.push([bigInt(1), bigInt(2)]);
  121. points.push([bigInt(2), bigInt(-2)]);
  122. points.push([bigInt(3), bigInt(0)]);
  123. points.push([bigInt(4), bigInt(453345)]);
  124. const p=PF.lagrange(points);
  125. for (let i=0; i<points.length; i++) {
  126. const v = PF.eval(p, points[i][0]);
  127. assert(PF.F.equals(v, points[i][1]));
  128. }
  129. });
  130. it("Should test ruffini", () => {
  131. const PF = new PolField(new ZqField(r));
  132. const a = [bigInt(1), bigInt(2), bigInt(3), bigInt(4), bigInt(5),bigInt(6), bigInt(7)];
  133. const b = PF.mul(a, [bigInt(-7), bigInt(1)]);
  134. const c = PF.ruffini(b, bigInt(7));
  135. assert(PF.equals(a, c));
  136. });
  137. it("Should test roots", () => {
  138. const PF = new PolField(new ZqField(r));
  139. let rt;
  140. rt = PF.oneRoot(256, 16);
  141. for (let i=0; i<8; i++) {
  142. rt = PF.F.mul(rt, rt);
  143. }
  144. assert(rt.equals(PF.F.one));
  145. rt = PF.oneRoot(256, 15);
  146. for (let i=0; i<8; i++) {
  147. rt = PF.F.mul(rt, rt);
  148. }
  149. assert(rt.equals(PF.F.one));
  150. rt = PF.oneRoot(8, 3);
  151. for (let i=0; i<3; i++) {
  152. rt = PF.F.mul(rt, rt);
  153. }
  154. assert(rt.equals(PF.F.one));
  155. rt = PF.oneRoot(8, 0);
  156. assert(rt.equals(PF.F.one));
  157. });
  158. it("Should create a polynomial with values at roots with fft", () => {
  159. const PF = new PolField(new ZqField(r));
  160. const a = [bigInt(1), bigInt(2), bigInt(3), bigInt(4), bigInt(5),bigInt(6), bigInt(7)];
  161. const p = PF.ifft(a);
  162. for (let i=0; i<a.length; i++) {
  163. const s = PF.F.affine(PF.eval(p, PF.oneRoot(8,i)));
  164. assert(s.equals(a[i]));
  165. }
  166. });
  167. });