From e82f74c751e290950549d48ead2083efe56cd533 Mon Sep 17 00:00:00 2001 From: Richard Liu Date: Mon, 13 Feb 2023 00:51:23 -0800 Subject: [PATCH] add computeAllInputs to javascript --- javascript/package.json | 2 +- javascript/src/index.ts | 47 ++++++++++++++++++++++++++++-- javascript/src/utils/encoding.ts | 2 +- javascript/test/signals.test.ts | 50 ++++++++++++++++++++++++-------- javascript/yarn.lock | 38 ++++++++++++------------ 5 files changed, 104 insertions(+), 35 deletions(-) diff --git a/javascript/package.json b/javascript/package.json index eeecdd6..cf0964b 100644 --- a/javascript/package.json +++ b/javascript/package.json @@ -1,6 +1,6 @@ { "name": "plume-sig", - "version": "1.0.2", + "version": "1.1.0", "packageManager": "yarn@3.2.4", "devDependencies": { "@types/jest": "^29.2.3", diff --git a/javascript/src/index.ts b/javascript/src/index.ts index 24edbe3..743bf7b 100644 --- a/javascript/src/index.ts +++ b/javascript/src/index.ts @@ -1,5 +1,11 @@ -import { Point } from "@noble/secp256k1"; -import { concatUint8Arrays, hexToBigInt } from "./utils/encoding"; +import { CURVE, getPublicKey, Point, utils } from "@noble/secp256k1"; +import { + concatUint8Arrays, + hexToBigInt, + hexToUint8Array, + messageToUint8Array, + uint8ArrayToBigInt, +} from "./utils/encoding"; import hashToCurve from "./utils/hashToCurve"; import { sha512 } from "js-sha512"; import { HashedPoint, multiplyPoint } from "./utils/curve"; @@ -52,3 +58,40 @@ export function computeGPowR(r: Uint8Array) { export function computeHashMPkPowR(hashMPk: HashedPoint, r: Uint8Array) { return multiplyPoint(hashMPk, r); } + +export function computeS(r: Uint8Array, secretKey: Uint8Array, c: string) { + const skC = (uint8ArrayToBigInt(secretKey) * hexToBigInt(c)) % CURVE.P; + return ((skC + uint8ArrayToBigInt(r)) % CURVE.P).toString(16); +} + +export function computeAllInputs( + message: string | Uint8Array, + secretKey: string | Uint8Array, + r?: string | Uint8Array +) { + const secretKeyBytes = + typeof secretKey === "string" ? hexToUint8Array(secretKey) : secretKey; + const messageBytes = + typeof message === "string" ? messageToUint8Array(message) : message; + const publicKeyBytes = getPublicKey(secretKeyBytes, true); + let rBytes; + if (r) { + rBytes = typeof r === "string" ? hexToUint8Array(r) : r; + } else { + rBytes = utils.randomPrivateKey(); + } + const hashMPK = computeHashMPk(messageBytes, publicKeyBytes); + const nullifier = computeNullifer(hashMPK, secretKeyBytes); + const hashMPKPowR = computeHashMPkPowR(hashMPK, rBytes); + const gPowR = computeGPowR(rBytes); + const c = computeC(publicKeyBytes, hashMPK, nullifier, gPowR, hashMPKPowR); + const s = computeS(rBytes, secretKeyBytes, c); + return { + plume: nullifier, + s, + publicKey: publicKeyBytes, + c, + gPowR, + hashMPKPowR, + }; +} diff --git a/javascript/src/utils/encoding.ts b/javascript/src/utils/encoding.ts index 0e540ac..f38a6f6 100644 --- a/javascript/src/utils/encoding.ts +++ b/javascript/src/utils/encoding.ts @@ -21,7 +21,7 @@ export function uint8ArrayToBigInt(buffer: Uint8Array): bigint { } export function asciitobytes(s: string): number[] { - var b = [], + var b: number[] = [], i: number; for (i = 0; i < s.length; i++) { b.push(s.charCodeAt(i)); diff --git a/javascript/test/signals.test.ts b/javascript/test/signals.test.ts index 7e86b0f..77bed51 100644 --- a/javascript/test/signals.test.ts +++ b/javascript/test/signals.test.ts @@ -1,17 +1,14 @@ -import { CURVE, getPublicKey, Point } from "@noble/secp256k1"; +import { getPublicKey, Point } from "@noble/secp256k1"; import { + computeAllInputs, computeC, computeGPowR, computeHashMPk, computeHashMPkPowR, computeNullifer, + computeS, } from "../src"; -import { - hexToBigInt, - hexToUint8Array, - messageToUint8Array, - uint8ArrayToBigInt, -} from "../src/utils/encoding"; +import { hexToUint8Array, messageToUint8Array } from "../src/utils/encoding"; const testSecretKey = hexToUint8Array( "519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464" @@ -96,13 +93,42 @@ describe("signals", () => { "7da1ad3f63c6180beefd0d6a8e3c87620b54f1b1d2c8287d104da9e53b6b5524"; it("generates an s signal", () => { - const skC = - (uint8ArrayToBigInt(testSecretKey) * hexToBigInt(mockC)) % CURVE.P; - const s = ((skC + uint8ArrayToBigInt(testR)) % CURVE.P).toString(16); + const s = computeS(testR, testSecretKey, mockC); expect(s).toEqual( "49d55841b8b8003b21be96c24d9d6866fe82b409edd14cdc9aacd88c17742118" ); }); -}); -// TODO: Add custom verification function + it("generates all signals", () => { + const { plume, s, publicKey, c, gPowR, hashMPKPowR } = computeAllInputs( + testMessage, + testSecretKey, + testR + ); + expect(publicKey).toEqual(testPublicKey); + expect(gPowR.x.toString(16)).toEqual( + "9d8ca4350e7e2ad27abc6d2a281365818076662962a28429590e2dc736fe9804" + ); + expect(gPowR.y.toString(16)).toEqual( + "ff08c30b8afd4e854623c835d9c3aac6bcebe45112472d9b9054816a7670c5a1" + ); + expect(plume.x.toString(16)).toEqual( + "57bc3ed28172ef8adde4b9e0c2cce745fcc5a66473a45c1e626f1d0c67e55830" + ); + expect(plume.y.toString(16)).toEqual( + "6a2f41488d58f33ae46edd2188e111609f9f3ae67ea38fa891d6087fe59ecb73" + ); + expect(hashMPKPowR.x.toString(16)).toEqual( + "6d017c6f63c59fa7a5b1e9a654e27d2869579f4d152131db270558fccd27b97c" + ); + expect(c).toEqual( + "7da1ad3f63c6180beefd0d6a8e3c87620b54f1b1d2c8287d104da9e53b6b5524" + ); + expect(s).toEqual( + "49d55841b8b8003b21be96c24d9d6866fe82b409edd14cdc9aacd88c17742118" + ); + expect(hashMPKPowR.y.toString(16)).toEqual( + "586c43fb5c99818c564a8f80a88a65f83e3f44d3c6caf5a1a4e290b777ac56ed" + ); + }); +}); diff --git a/javascript/yarn.lock b/javascript/yarn.lock index aecbe70..1f4627f 100644 --- a/javascript/yarn.lock +++ b/javascript/yarn.lock @@ -3200,6 +3200,25 @@ __metadata: languageName: node linkType: hard +"plume-sig@workspace:.": + version: 0.0.0-use.local + resolution: "plume-sig@workspace:." + dependencies: + "@noble/secp256k1": ^1.7.0 + "@types/jest": ^29.2.3 + "@types/js-sha512": ^0 + "@types/node": ^18.11.9 + "@types/nodemon": ^1.19.2 + amcl-js: ^3.0.0 + jest: ^29.3.1 + js-sha512: ^0.8.0 + nodemon: ^2.0.20 + ts-jest: ^29.0.3 + ts-node: ^10.9.1 + typescript: ^4.9.3 + languageName: unknown + linkType: soft + "pretty-format@npm:^29.0.0, pretty-format@npm:^29.3.1": version: 29.3.1 resolution: "pretty-format@npm:29.3.1" @@ -3999,22 +4018,3 @@ __metadata: checksum: f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 languageName: node linkType: hard - -"zk-ecdsa-signature@workspace:.": - version: 0.0.0-use.local - resolution: "zk-ecdsa-signature@workspace:." - dependencies: - "@noble/secp256k1": ^1.7.0 - "@types/jest": ^29.2.3 - "@types/js-sha512": ^0 - "@types/node": ^18.11.9 - "@types/nodemon": ^1.19.2 - amcl-js: ^3.0.0 - jest: ^29.3.1 - js-sha512: ^0.8.0 - nodemon: ^2.0.20 - ts-jest: ^29.0.3 - ts-node: ^10.9.1 - typescript: ^4.9.3 - languageName: unknown - linkType: soft