forked from plume-sig/zk-nullifier-sig
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
88f8864
commit c17de76
Showing
6 changed files
with
233 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.computeAllInputs = exports.computeS = exports.computeHashToCurveR = exports.computeRPoint = exports.computeNullifer = exports.computeC_V1 = exports.computeC_V2 = exports.computeHashToCurve = exports.PlumeVersion = void 0; | ||
var secp256k1_1 = require("@noble/secp256k1"); | ||
var encoding_1 = require("./utils/encoding"); | ||
var hashToCurve_1 = require("./utils/hashToCurve"); | ||
var curve_1 = require("./utils/curve"); | ||
var js_sha256_1 = require("js-sha256"); | ||
// PLUME version | ||
var PlumeVersion; | ||
(function (PlumeVersion) { | ||
PlumeVersion[PlumeVersion["V1"] = 1] = "V1"; | ||
PlumeVersion[PlumeVersion["V2"] = 2] = "V2"; | ||
})(PlumeVersion || (exports.PlumeVersion = PlumeVersion = {})); | ||
function computeHashToCurve(message, pk) { | ||
// Concatenate message and publicKey | ||
var preimage = new Uint8Array(message.length + pk.length); | ||
preimage.set(message); | ||
preimage.set(pk, message.length); | ||
return (0, hashToCurve_1.default)(Array.from(preimage)); | ||
} | ||
exports.computeHashToCurve = computeHashToCurve; | ||
function computeC_V2(nullifier, rPoint, hashedToCurveR) { | ||
var nullifierBytes = nullifier.toRawBytes(true); | ||
var preimage = (0, encoding_1.concatUint8Arrays)([ | ||
nullifierBytes, | ||
rPoint.toRawBytes(true), | ||
hashedToCurveR.toRawBytes(true), | ||
]); | ||
return js_sha256_1.sha256.create().update(preimage).hex(); | ||
} | ||
exports.computeC_V2 = computeC_V2; | ||
function computeC_V1(pkBytes, hashedToCurve, nullifier, rPoint, hashedToCurveR) { | ||
var nullifierBytes = nullifier.toRawBytes(true); | ||
var preimage = (0, encoding_1.concatUint8Arrays)([ | ||
secp256k1_1.Point.BASE.toRawBytes(true), | ||
pkBytes, | ||
new secp256k1_1.Point((0, encoding_1.hexToBigInt)(hashedToCurve.x.toString()), (0, encoding_1.hexToBigInt)(hashedToCurve.y.toString())).toRawBytes(true), | ||
nullifierBytes, | ||
rPoint.toRawBytes(true), | ||
hashedToCurveR.toRawBytes(true), | ||
]); | ||
return js_sha256_1.sha256.create().update(preimage).hex(); | ||
} | ||
exports.computeC_V1 = computeC_V1; | ||
function computeNullifer(hashedToCurve, sk) { | ||
return (0, curve_1.multiplyPoint)(hashedToCurve, sk); | ||
} | ||
exports.computeNullifer = computeNullifer; | ||
function computeRPoint(rScalar) { | ||
return secp256k1_1.Point.fromPrivateKey(rScalar); | ||
} | ||
exports.computeRPoint = computeRPoint; | ||
function computeHashToCurveR(hashedToCurve, rScalar) { | ||
return (0, curve_1.multiplyPoint)(hashedToCurve, rScalar); | ||
} | ||
exports.computeHashToCurveR = computeHashToCurveR; | ||
function computeS(rScalar, sk, c) { | ||
return (((((0, encoding_1.uint8ArrayToBigInt)(sk) * (0, encoding_1.hexToBigInt)(c)) % secp256k1_1.CURVE.n) + | ||
(0, encoding_1.uint8ArrayToBigInt)(rScalar)) % | ||
secp256k1_1.CURVE.n).toString(16); | ||
} | ||
exports.computeS = computeS; | ||
/** | ||
* Computes and returns the Plume and other signals for the prover. | ||
* @param {string | Uint8Array} message - Message to sign, in either string or UTF-8 array format. | ||
* @param {string | Uint8Array} sk - ECDSA secret key to sign with. | ||
* @param {string| Uint8Array} rScalar - Optional seed for randomness. | ||
* @returns Object containing Plume and other signals - public key, s, c, gPowR, and hashMPKPowR. | ||
*/ | ||
function computeAllInputs(message, sk, rScalar, version) { | ||
if (version === void 0) { version = PlumeVersion.V2; } | ||
var skBytes = typeof sk === "string" ? (0, encoding_1.hexToUint8Array)(sk) : sk; | ||
var messageBytes = typeof message === "string" ? (0, encoding_1.messageToUint8Array)(message) : message; | ||
var pkBytes = (0, secp256k1_1.getPublicKey)(skBytes, true); | ||
var rScalarBytes; | ||
if (rScalar) { | ||
rScalarBytes = | ||
typeof rScalar === "string" ? (0, encoding_1.hexToUint8Array)(rScalar) : rScalar; | ||
} | ||
else { | ||
rScalarBytes = secp256k1_1.utils.randomPrivateKey(); | ||
} | ||
var hashedToCurve = computeHashToCurve(messageBytes, pkBytes); | ||
var nullifier = computeNullifer(hashedToCurve, skBytes); | ||
var hashedToCurveR = computeHashToCurveR(hashedToCurve, rScalarBytes); | ||
var rPoint = computeRPoint(rScalarBytes); | ||
var c = version == PlumeVersion.V1 | ||
? computeC_V1(pkBytes, hashedToCurve, nullifier, rPoint, hashedToCurveR) | ||
: computeC_V2(nullifier, rPoint, hashedToCurveR); | ||
var s = computeS(rScalarBytes, skBytes, c); | ||
return { | ||
plume: nullifier, | ||
s: s, | ||
pk: pkBytes, | ||
c: c, | ||
rPoint: rPoint, | ||
hashedToCurveR: hashedToCurveR, | ||
}; | ||
} | ||
exports.computeAllInputs = computeAllInputs; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.multiplyPoint = void 0; | ||
var secp256k1_1 = require("@noble/secp256k1"); | ||
var encoding_1 = require("./encoding"); | ||
function multiplyPoint(h, secretKey) { | ||
var hashPoint = new secp256k1_1.Point(BigInt("0x" + h.x.toString()), BigInt("0x" + h.y.toString())); | ||
return hashPoint.multiply(BigInt("0x" + (0, encoding_1.uint8ArrayToHex)(secretKey))); | ||
} | ||
exports.multiplyPoint = multiplyPoint; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.concatUint8Arrays = exports.asciitobytes = exports.uint8ArrayToBigInt = exports.hexToBigInt = exports.uint8ArrayToHex = exports.hexToUint8Array = exports.messageToUint8Array = void 0; | ||
var utf8Encoder = new TextEncoder(); | ||
function messageToUint8Array(message) { | ||
return utf8Encoder.encode(message); | ||
} | ||
exports.messageToUint8Array = messageToUint8Array; | ||
function hexToUint8Array(hexString) { | ||
// Source: https://stackoverflow.com/questions/38987784/how-to-convert-a-hexadecimal-string-to-uint8array-and-back-in-javascript/50868276#50868276 | ||
return Uint8Array.from(hexString.match(/.{1,2}/g).map(function (byte) { return parseInt(byte, 16); })); | ||
} | ||
exports.hexToUint8Array = hexToUint8Array; | ||
function uint8ArrayToHex(uint8Array) { | ||
// Source: https://stackoverflow.com/questions/38987784/how-to-convert-a-hexadecimal-string-to-uint8array-and-back-in-javascript/50868276#50868276 | ||
return uint8Array.reduce(function (str, byte) { return str + byte.toString(16).padStart(2, "0"); }, ""); | ||
} | ||
exports.uint8ArrayToHex = uint8ArrayToHex; | ||
function hexToBigInt(hex) { | ||
return BigInt("0x" + hex); | ||
} | ||
exports.hexToBigInt = hexToBigInt; | ||
function uint8ArrayToBigInt(buffer) { | ||
return hexToBigInt(uint8ArrayToHex(buffer)); | ||
} | ||
exports.uint8ArrayToBigInt = uint8ArrayToBigInt; | ||
function asciitobytes(s) { | ||
var b = []; | ||
for (var i = 0; i < s.length; i++) { | ||
b.push(s.charCodeAt(i)); | ||
} | ||
return b; | ||
} | ||
exports.asciitobytes = asciitobytes; | ||
function concatUint8Arrays(arrays) { | ||
// sum of individual array lengths | ||
var totalLength = arrays.reduce(function (acc, value) { return acc + value.length; }, 0); | ||
var result = new Uint8Array(totalLength); | ||
if (!arrays.length) { | ||
return result; | ||
} | ||
// for each array - copy it over result | ||
// next array is copied right after the previous one | ||
var length = 0; | ||
for (var _i = 0, arrays_1 = arrays; _i < arrays_1.length; _i++) { | ||
var array = arrays_1[_i]; | ||
result.set(array, length); | ||
length += array.length; | ||
} | ||
return result; | ||
} | ||
exports.concatUint8Arrays = concatUint8Arrays; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var amcl_js_1 = require("amcl-js"); | ||
var encoding_1 = require("./encoding"); | ||
// Refactored from miracl-core | ||
var ctx = new amcl_js_1.CTX("SECP256K1"); | ||
var ro = "QUUX-V01-CS02-with-secp256k1_XMD:SHA-256_SSWU_RO_"; | ||
var hlen = ctx.ECP.HASH_TYPE; | ||
function ceil(a, b) { | ||
return Math.floor((a - 1) / b + 1); | ||
} | ||
function hashToField(ctx, hash, hlen, DST, M, ctr) { | ||
var u = []; | ||
var q = new ctx.BIG(0); | ||
q.rcopy(ctx.ROM_FIELD.Modulus); | ||
var k = q.nbits(); | ||
var r = new ctx.BIG(0); | ||
r.rcopy(ctx.ROM_CURVE.CURVE_Order); | ||
var m = r.nbits(); | ||
var L = ceil(k + ceil(m, 2), 8); | ||
var OKM = ctx.HMAC.XMD_Expand(hash, hlen, L * ctr, DST, M); | ||
var fd = []; | ||
for (var i = 0; i < ctr; i++) { | ||
for (var j = 0; j < L; j++) { | ||
fd[j] = OKM[i * L + j]; | ||
} | ||
var dx = ctx.DBIG.fromBytes(fd); | ||
var w = new ctx.FP(dx.mod(q)); | ||
u[i] = new ctx.FP(w); | ||
} | ||
return u; | ||
} | ||
// Taken from https://github.com/miracl/core/blob/master/javascript/examples/node/TestHTP.js#L37 | ||
function hashToPairing(ctx, M, ro, hlen) { | ||
var DSTRO = (0, encoding_1.asciitobytes)(ro); | ||
var u = hashToField(ctx, ctx.HMAC.MC_SHA2, hlen, DSTRO, M, 2); | ||
var P = ctx.ECP.map2point(u[0]); | ||
var P1 = ctx.ECP.map2point(u[1]); | ||
P.add(P1); | ||
P.cfp(); | ||
P.affine(); | ||
return P; | ||
} | ||
function hashToCurve(bytes) { | ||
return hashToPairing(ctx, bytes, ro, hlen); | ||
} | ||
exports.default = hashToCurve; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.s_v2 = exports.c_v2 = exports.s_v1 = exports.c_v1 = exports.rPoint = exports.hashedToCurveR = exports.nullifier = exports.hashMPk = exports.testMessage = exports.testMessageString = exports.testR = exports.testPublicKey = exports.testPublicKeyPoint = exports.testSecretKey = void 0; | ||
var secp256k1_1 = require("@noble/secp256k1"); | ||
var signals_1 = require("../src/signals"); | ||
var encoding_1 = require("../src/utils/encoding"); | ||
exports.testSecretKey = (0, encoding_1.hexToUint8Array)("519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464"); | ||
exports.testPublicKeyPoint = secp256k1_1.Point.fromPrivateKey(exports.testSecretKey); | ||
exports.testPublicKey = (0, secp256k1_1.getPublicKey)(exports.testSecretKey, true); | ||
exports.testR = (0, encoding_1.hexToUint8Array)("93b9323b629f251b8f3fc2dd11f4672c5544e8230d493eceea98a90bda789808"); | ||
exports.testMessageString = "An example app message string"; | ||
exports.testMessage = (0, encoding_1.messageToUint8Array)(exports.testMessageString); | ||
exports.hashMPk = (0, signals_1.computeHashToCurve)(exports.testMessage, Buffer.from(exports.testPublicKey)); | ||
exports.nullifier = (0, signals_1.computeNullifer)(exports.hashMPk, exports.testSecretKey); | ||
exports.hashedToCurveR = (0, signals_1.computeHashToCurveR)(exports.hashMPk, exports.testR); | ||
exports.rPoint = (0, signals_1.computeRPoint)(exports.testR); | ||
exports.c_v1 = (0, signals_1.computeC_V1)(exports.testPublicKey, exports.hashMPk, exports.nullifier, exports.rPoint, exports.hashedToCurveR); | ||
exports.s_v1 = (0, signals_1.computeS)(exports.testR, exports.testSecretKey, exports.c_v1); | ||
exports.c_v2 = (0, signals_1.computeC_V2)(exports.nullifier, exports.rPoint, exports.hashedToCurveR); | ||
exports.s_v2 = (0, signals_1.computeS)(exports.testR, exports.testSecretKey, exports.c_v2); |