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.

182 lines
5.9 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
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
  1. const createBlakeHash = require("blake-hash");
  2. const bigInt = require("snarkjs").bigInt;
  3. const babyJub = require("./babyjub");
  4. const pedersenHash = require("./pedersenHash").hash;
  5. const mimc7 = require("./mimc7");
  6. const poseidon = require("./poseidon.js");
  7. exports.prv2pub= prv2pub;
  8. exports.sign = sign;
  9. exports.signMiMC = signMiMC;
  10. exports.signPoseidon = signPoseidon;
  11. exports.verify = verify;
  12. exports.verifyMiMC = verifyMiMC;
  13. exports.verifyPoseidon = verifyPoseidon;
  14. exports.packSignature = packSignature;
  15. exports.unpackSignature = unpackSignature;
  16. exports.pruneBuffer = pruneBuffer;
  17. function pruneBuffer(_buff) {
  18. const buff = Buffer.from(_buff);
  19. buff[0] = buff[0] & 0xF8;
  20. buff[31] = buff[31] & 0x7F;
  21. buff[31] = buff[31] | 0x40;
  22. return buff;
  23. }
  24. function prv2pub(prv) {
  25. const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0,32));
  26. let s = bigInt.leBuff2int(sBuff);
  27. const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
  28. return A;
  29. }
  30. function sign(prv, msg) {
  31. const h1 = createBlakeHash("blake512").update(prv).digest();
  32. const sBuff = pruneBuffer(h1.slice(0,32));
  33. const s = bigInt.leBuff2int(sBuff);
  34. const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
  35. const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest();
  36. let r = bigInt.leBuff2int(rBuff);
  37. r = r.mod(babyJub.subOrder);
  38. const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
  39. const R8p = babyJub.packPoint(R8);
  40. const Ap = babyJub.packPoint(A);
  41. const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
  42. const hm = bigInt.leBuff2int(hmBuff);
  43. const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
  44. return {
  45. R8: R8,
  46. S: S
  47. };
  48. }
  49. function signMiMC(prv, msg) {
  50. const h1 = createBlakeHash("blake512").update(prv).digest();
  51. const sBuff = pruneBuffer(h1.slice(0,32));
  52. const s = bigInt.leBuff2int(sBuff);
  53. const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
  54. const msgBuff = bigInt.leInt2Buff(msg, 32);
  55. const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
  56. let r = bigInt.leBuff2int(rBuff);
  57. r = r.mod(babyJub.subOrder);
  58. const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
  59. const hm = mimc7.multiHash([R8[0], R8[1], A[0], A[1], msg]);
  60. const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
  61. return {
  62. R8: R8,
  63. S: S
  64. };
  65. }
  66. function signPoseidon(prv, msg) {
  67. const h1 = createBlakeHash("blake512").update(prv).digest();
  68. const sBuff = pruneBuffer(h1.slice(0,32));
  69. const s = bigInt.leBuff2int(sBuff);
  70. const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
  71. const msgBuff = bigInt.leInt2Buff(msg, 32);
  72. const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
  73. let r = bigInt.leBuff2int(rBuff);
  74. r = r.mod(babyJub.subOrder);
  75. const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
  76. const hash = poseidon.createHash(6, 8, 57);
  77. const hm = hash([R8[0], R8[1], A[0], A[1], msg]);
  78. const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
  79. return {
  80. R8: R8,
  81. S: S
  82. };
  83. }
  84. function verify(msg, sig, A) {
  85. // Check parameters
  86. if (typeof sig != "object") return false;
  87. if (!Array.isArray(sig.R8)) return false;
  88. if (sig.R8.length!= 2) return false;
  89. if (!babyJub.inCurve(sig.R8)) return false;
  90. if (!Array.isArray(A)) return false;
  91. if (A.length!= 2) return false;
  92. if (!babyJub.inCurve(A)) return false;
  93. if (sig.S>= babyJub.subOrder) return false;
  94. const R8p = babyJub.packPoint(sig.R8);
  95. const Ap = babyJub.packPoint(A);
  96. const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
  97. const hm = bigInt.leBuff2int(hmBuff);
  98. const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
  99. let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
  100. Pright = babyJub.addPoint(sig.R8, Pright);
  101. if (!Pleft[0].equals(Pright[0])) return false;
  102. if (!Pleft[1].equals(Pright[1])) return false;
  103. return true;
  104. }
  105. function verifyMiMC(msg, sig, A) {
  106. // Check parameters
  107. if (typeof sig != "object") return false;
  108. if (!Array.isArray(sig.R8)) return false;
  109. if (sig.R8.length!= 2) return false;
  110. if (!babyJub.inCurve(sig.R8)) return false;
  111. if (!Array.isArray(A)) return false;
  112. if (A.length!= 2) return false;
  113. if (!babyJub.inCurve(A)) return false;
  114. if (sig.S>= babyJub.subOrder) return false;
  115. const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
  116. const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
  117. let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
  118. Pright = babyJub.addPoint(sig.R8, Pright);
  119. if (!Pleft[0].equals(Pright[0])) return false;
  120. if (!Pleft[1].equals(Pright[1])) return false;
  121. return true;
  122. }
  123. function verifyPoseidon(msg, sig, A) {
  124. // Check parameters
  125. if (typeof sig != "object") return false;
  126. if (!Array.isArray(sig.R8)) return false;
  127. if (sig.R8.length!= 2) return false;
  128. if (!babyJub.inCurve(sig.R8)) return false;
  129. if (!Array.isArray(A)) return false;
  130. if (A.length!= 2) return false;
  131. if (!babyJub.inCurve(A)) return false;
  132. if (sig.S>= babyJub.subOrder) return false;
  133. const hash = poseidon.createHash(6, 8, 57);
  134. const hm = hash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
  135. const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
  136. let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
  137. Pright = babyJub.addPoint(sig.R8, Pright);
  138. if (!Pleft[0].equals(Pright[0])) return false;
  139. if (!Pleft[1].equals(Pright[1])) return false;
  140. return true;
  141. }
  142. function packSignature(sig) {
  143. const R8p = babyJub.packPoint(sig.R8);
  144. const Sp = bigInt.leInt2Buff(sig.S, 32);
  145. return Buffer.concat([R8p, Sp]);
  146. }
  147. function unpackSignature(sigBuff) {
  148. return {
  149. R8: babyJub.unpackPoint(sigBuff.slice(0,32)),
  150. S: bigInt.leBuff2int(sigBuff.slice(32,64))
  151. };
  152. }