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.

137 lines
3.4 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 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 fUtils = require("./futils.js");
  16. class F2Field {
  17. constructor(F, nonResidue) {
  18. this.F = F;
  19. this.zero = [this.F.zero, this.F.zero];
  20. this.one = [this.F.one, this.F.zero];
  21. this.nonResidue = nonResidue;
  22. }
  23. _mulByNonResidue(a) {
  24. return this.F.mul(this.nonResidue, a);
  25. }
  26. copy(a) {
  27. return [this.F.copy(a[0]), this.F.copy(a[1])];
  28. }
  29. add(a, b) {
  30. return [
  31. this.F.add(a[0], b[0]),
  32. this.F.add(a[1], b[1])
  33. ];
  34. }
  35. double(a) {
  36. return this.add(a,a);
  37. }
  38. sub(a, b) {
  39. return [
  40. this.F.sub(a[0], b[0]),
  41. this.F.sub(a[1], b[1])
  42. ];
  43. }
  44. neg(a) {
  45. return this.sub(this.zero, a);
  46. }
  47. mul(a, b) {
  48. const aA = this.F.mul(a[0] , b[0]);
  49. const bB = this.F.mul(a[1] , b[1]);
  50. return [
  51. this.F.add( aA , this._mulByNonResidue(bB)),
  52. this.F.sub(
  53. this.F.mul(
  54. this.F.add(a[0], a[1]),
  55. this.F.add(b[0], b[1])),
  56. this.F.add(aA, bB))];
  57. }
  58. inverse(a) {
  59. const t0 = this.F.square(a[0]);
  60. const t1 = this.F.square(a[1]);
  61. const t2 = this.F.sub(t0, this._mulByNonResidue(t1));
  62. const t3 = this.F.inverse(t2);
  63. return [
  64. this.F.mul(a[0], t3),
  65. this.F.neg(this.F.mul( a[1], t3)) ];
  66. }
  67. div(a, b) {
  68. return this.mul(a, this.inverse(b));
  69. }
  70. square(a) {
  71. const ab = this.F.mul(a[0] , a[1]);
  72. /*
  73. [
  74. (a + b) * (a + non_residue * b) - ab - non_residue * ab,
  75. ab + ab
  76. ];
  77. */
  78. return [
  79. this.F.sub(
  80. this.F.mul(
  81. this.F.add(a[0], a[1]) ,
  82. this.F.add(
  83. a[0] ,
  84. this._mulByNonResidue(a[1]))),
  85. this.F.add(
  86. ab,
  87. this._mulByNonResidue(ab))),
  88. this.F.add(ab, ab)
  89. ];
  90. }
  91. isZero(a) {
  92. return this.F.isZero(a[0]) && this.F.isZero(a[1]);
  93. }
  94. equals(a, b) {
  95. return this.F.equals(a[0], b[0]) && this.F.equals(a[1], b[1]);
  96. }
  97. affine(a) {
  98. return [this.F.affine(a[0]), this.F.affine(a[1])];
  99. }
  100. mulScalar(base, e) {
  101. return fUtils.mulScalar(this, base, e);
  102. }
  103. exp(base, e) {
  104. return fUtils.exp(this, base, e);
  105. }
  106. toString(a) {
  107. const cp = this.affine(a);
  108. return `[ ${this.F.toString(cp[0])} , ${this.F.toString(cp[1])} ]`;
  109. }
  110. }
  111. module.exports = F2Field;