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.

228 lines
7.6 KiB

5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
  1. const createBlakeHash = require("blake-hash");
  2. const Scalar = require("ffjavascript").Scalar;
  3. const F1Field = require("ffjavascript").F1Field;
  4. const babyJub = require("./babyjub");
  5. const utils = require("ffjavascript").utils;
  6. const pedersenHash = require("./pedersenHash").hash;
  7. const mimc7 = require("./mimc7");
  8. const poseidon = require("./poseidon.js");
  9. const mimcsponge = require("./mimcsponge");
  10. exports.prv2pub= prv2pub;
  11. exports.sign = sign;
  12. exports.signMiMC = signMiMC;
  13. exports.signPoseidon = signPoseidon;
  14. exports.signMiMCSponge = signMiMCSponge;
  15. exports.verify = verify;
  16. exports.verifyMiMC = verifyMiMC;
  17. exports.verifyPoseidon = verifyPoseidon;
  18. exports.verifyMiMCSponge = verifyMiMCSponge;
  19. exports.packSignature = packSignature;
  20. exports.unpackSignature = unpackSignature;
  21. exports.pruneBuffer = pruneBuffer;
  22. function pruneBuffer(_buff) {
  23. const buff = Buffer.from(_buff);
  24. buff[0] = buff[0] & 0xF8;
  25. buff[31] = buff[31] & 0x7F;
  26. buff[31] = buff[31] | 0x40;
  27. return buff;
  28. }
  29. function prv2pub(prv) {
  30. const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0,32));
  31. let s = utils.leBuff2int(sBuff);
  32. const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s,3));
  33. return A;
  34. }
  35. function sign(prv, msg) {
  36. const h1 = createBlakeHash("blake512").update(prv).digest();
  37. const sBuff = pruneBuffer(h1.slice(0,32));
  38. const s = utils.leBuff2int(sBuff);
  39. const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
  40. const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest();
  41. let r = utils.leBuff2int(rBuff);
  42. const Fr = new F1Field(babyJub.subOrder);
  43. r = Fr.e(r);
  44. const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
  45. const R8p = babyJub.packPoint(R8);
  46. const Ap = babyJub.packPoint(A);
  47. const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
  48. const hm = utils.leBuff2int(hmBuff);
  49. const S = Fr.add(r , Fr.mul(hm, s));
  50. return {
  51. R8: R8,
  52. S: S
  53. };
  54. }
  55. function signMiMC(prv, msg) {
  56. const h1 = createBlakeHash("blake512").update(prv).digest();
  57. const sBuff = pruneBuffer(h1.slice(0,32));
  58. const s = utils.leBuff2int(sBuff);
  59. const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
  60. const msgBuff = utils.leInt2Buff(msg, 32);
  61. const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
  62. let r = utils.leBuff2int(rBuff);
  63. const Fr = new F1Field(babyJub.subOrder);
  64. r = Fr.e(r);
  65. const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
  66. const hm = mimc7.multiHash([R8[0], R8[1], A[0], A[1], msg]);
  67. const S = Fr.add(r , Fr.mul(hm, s));
  68. return {
  69. R8: R8,
  70. S: S
  71. };
  72. }
  73. function signMiMCSponge(prv, msg) {
  74. const h1 = createBlakeHash("blake512").update(prv).digest();
  75. const sBuff = pruneBuffer(h1.slice(0,32));
  76. const s = utils.leBuff2int(sBuff);
  77. const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
  78. const msgBuff = utils.leInt2Buff(msg, 32);
  79. const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
  80. let r = utils.leBuff2int(rBuff);
  81. const Fr = new F1Field(babyJub.subOrder);
  82. r = Fr.e(r);
  83. const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
  84. const hm = mimcsponge.multiHash([R8[0], R8[1], A[0], A[1], msg]);
  85. const S = Fr.add(r , Fr.mul(hm, s));
  86. return {
  87. R8: R8,
  88. S: S
  89. };
  90. }
  91. function signPoseidon(prv, msg) {
  92. const h1 = createBlakeHash("blake512").update(prv).digest();
  93. const sBuff = pruneBuffer(h1.slice(0,32));
  94. const s = utils.leBuff2int(sBuff);
  95. const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
  96. const msgBuff = utils.leInt2Buff(msg, 32);
  97. const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
  98. let r = utils.leBuff2int(rBuff);
  99. const Fr = new F1Field(babyJub.subOrder);
  100. r = Fr.e(r);
  101. const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
  102. const hm = poseidon([R8[0], R8[1], A[0], A[1], msg]);
  103. const S = Fr.add(r , Fr.mul(hm, s));
  104. return {
  105. R8: R8,
  106. S: S
  107. };
  108. }
  109. function verify(msg, sig, A) {
  110. // Check parameters
  111. if (typeof sig != "object") return false;
  112. if (!Array.isArray(sig.R8)) return false;
  113. if (sig.R8.length!= 2) return false;
  114. if (!babyJub.inCurve(sig.R8)) return false;
  115. if (!Array.isArray(A)) return false;
  116. if (A.length!= 2) return false;
  117. if (!babyJub.inCurve(A)) return false;
  118. if (sig.S>= babyJub.subOrder) return false;
  119. const R8p = babyJub.packPoint(sig.R8);
  120. const Ap = babyJub.packPoint(A);
  121. const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
  122. const hm = utils.leBuff2int(hmBuff);
  123. const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
  124. let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm,8));
  125. Pright = babyJub.addPoint(sig.R8, Pright);
  126. if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
  127. if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
  128. return true;
  129. }
  130. function verifyMiMC(msg, sig, A) {
  131. // Check parameters
  132. if (typeof sig != "object") return false;
  133. if (!Array.isArray(sig.R8)) return false;
  134. if (sig.R8.length!= 2) return false;
  135. if (!babyJub.inCurve(sig.R8)) return false;
  136. if (!Array.isArray(A)) return false;
  137. if (A.length!= 2) return false;
  138. if (!babyJub.inCurve(A)) return false;
  139. if (sig.S>= babyJub.subOrder) return false;
  140. const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
  141. const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
  142. let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm, 8));
  143. Pright = babyJub.addPoint(sig.R8, Pright);
  144. if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
  145. if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
  146. return true;
  147. }
  148. function verifyPoseidon(msg, sig, A) {
  149. // Check parameters
  150. if (typeof sig != "object") return false;
  151. if (!Array.isArray(sig.R8)) return false;
  152. if (sig.R8.length!= 2) return false;
  153. if (!babyJub.inCurve(sig.R8)) return false;
  154. if (!Array.isArray(A)) return false;
  155. if (A.length!= 2) return false;
  156. if (!babyJub.inCurve(A)) return false;
  157. if (sig.S>= babyJub.subOrder) return false;
  158. const hm = poseidon([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
  159. const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
  160. let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm, 8));
  161. Pright = babyJub.addPoint(sig.R8, Pright);
  162. if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
  163. if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
  164. return true;
  165. }
  166. function verifyMiMCSponge(msg, sig, A) {
  167. // Check parameters
  168. if (typeof sig != "object") return false;
  169. if (!Array.isArray(sig.R8)) return false;
  170. if (sig.R8.length!= 2) return false;
  171. if (!babyJub.inCurve(sig.R8)) return false;
  172. if (!Array.isArray(A)) return false;
  173. if (A.length!= 2) return false;
  174. if (!babyJub.inCurve(A)) return false;
  175. if (sig.S>= babyJub.subOrder) return false;
  176. const hm = mimcsponge.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
  177. const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
  178. let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
  179. Pright = babyJub.addPoint(sig.R8, Pright);
  180. if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
  181. if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
  182. return true;
  183. }
  184. function packSignature(sig) {
  185. const R8p = babyJub.packPoint(sig.R8);
  186. const Sp = utils.leInt2Buff(sig.S, 32);
  187. return Buffer.concat([R8p, Sp]);
  188. }
  189. function unpackSignature(sigBuff) {
  190. return {
  191. R8: babyJub.unpackPoint(sigBuff.slice(0,32)),
  192. S: utils.leBuff2int(sigBuff.slice(32,64))
  193. };
  194. }