diff --git a/circuits/circom/test/sha256Circuit.test.ts b/circuits/circom/test/sha256Circuit.test.ts index 8c7faf3..7a1d1f0 100644 --- a/circuits/circom/test/sha256Circuit.test.ts +++ b/circuits/circom/test/sha256Circuit.test.ts @@ -28,27 +28,18 @@ describe("SHA256 Circuit", () => { hexToBigInt(hashMPk.y.toString()), ); + const public_key_compressed = Array.from( + Point.fromPrivateKey(testSecretKey).toRawBytes(true), + ); + const sha_preimage_points: Point[] = [ Point.BASE, - Point.fromPrivateKey(testSecretKey), hashMPkPoint, nullifier, rPoint, hashedToCurveR, ]; - const v1_sha256_preimage_bits = bufToSha256PaddedBitArr( - Buffer.from( - concatUint8Arrays( - sha_preimage_points.map((point) => point.toRawBytes(true)), - ), - ), - ); - const v1_sha256_preimage_bit_length = parseInt( - v1_sha256_preimage_bits.slice(-64), - 2, - ); - const v1_binary_c = BigInt("0x" + c_v1) .toString(2) .split("") @@ -65,7 +56,13 @@ describe("SHA256 Circuit", () => { const p = path.join(__dirname, "./circuits/12_point_sha_256_test.circom"); const circuit = await wasm_tester(p, { json: true, sym: true }); - const w = await circuit.calculateWitness({ coordinates }, true); + const w = await circuit.calculateWitness( + { + pk_compressed: public_key_compressed, + coordinates, + }, + true, + ); await circuit.checkConstraints(w); await circuit.assertOut(w, { out: v1_binary_c }); }); diff --git a/circuits/circom/test/v1.test.ts b/circuits/circom/test/v1.test.ts index f253d82..007bce7 100644 --- a/circuits/circom/test/v1.test.ts +++ b/circuits/circom/test/v1.test.ts @@ -3,24 +3,17 @@ import path from "path"; import { Point } from "@noble/secp256k1"; import { wasm as wasm_tester } from "circom_tester"; import { generate_inputs_from_array } from "secp256k1_hash_to_curve_circom/ts/generate_inputs"; -import { bufToSha256PaddedBitArr } from "secp256k1_hash_to_curve_circom/ts/utils"; import { utils } from "ffjavascript"; import { c_v1, - rPoint, - hashMPk, - hashedToCurveR, nullifier, s_v1, testMessage, testPublicKey, testSecretKey, } from "../../../javascript/test/consts"; -import { - hexToBigInt, - concatUint8Arrays, -} from "../../../javascript/src/utils/encoding"; +import { hexToBigInt } from "../../../javascript/src/utils/encoding"; import { pointToCircuitValue, scalarToCircuitValue } from "../utils"; @@ -30,37 +23,10 @@ describe("V1 Circuit", () => { const public_key_bytes = Array.from(testPublicKey); const message_bytes = Array.from(testMessage); - const hashMPkPoint = new Point( - hexToBigInt(hashMPk.x.toString()), - hexToBigInt(hashMPk.y.toString()), - ); - const hash_to_curve_inputs = utils.stringifyBigInts( generate_inputs_from_array(message_bytes.concat(public_key_bytes)), ); - const sha_preimage_points: Point[] = [ - Point.BASE, - Point.fromPrivateKey(testSecretKey), - hashMPkPoint, - nullifier, - rPoint, - hashedToCurveR, - ]; - - const v1_sha256_preimage_bits = bufToSha256PaddedBitArr( - Buffer.from( - concatUint8Arrays( - sha_preimage_points.map((point) => point.toRawBytes(true)), - ), - ), - ); - - const v1_sha256_preimage_bit_length = parseInt( - v1_sha256_preimage_bits.slice(-64), - 2, - ); - test("V1 circuit works", async () => { const p = path.join(__dirname, "./circuits/v1_test.circom"); const circuit = await wasm_tester(p); diff --git a/circuits/circom/verify_nullifier.circom b/circuits/circom/verify_nullifier.circom index bdc6ac7..7a44894 100644 --- a/circuits/circom/verify_nullifier.circom +++ b/circuits/circom/verify_nullifier.circom @@ -30,11 +30,16 @@ template plume_v1(n, k, message_length) { signal input q1_x_mapped[4]; signal input q1_y_mapped[4]; + // compressing public key here to avoid compressing it twice in both `check_ec_equations` and `sha256_12_coordinates` + component pk_compressor = compress_ec_point(n, k); + pk_compressor.uncompressed <== pk; + component check_ec_equations = check_ec_equations(n, k, message_length); check_ec_equations.c <== c; check_ec_equations.s <== s; check_ec_equations.pk <== pk; + check_ec_equations.pk_compressed <== pk_compressor.compressed; check_ec_equations.nullifier <== nullifier; check_ec_equations.plume_message <== plume_message; @@ -56,15 +61,15 @@ template plume_v1(n, k, message_length) { var g[2][100]; g[0] = get_genx(n, k); g[1] = get_geny(n, k); + c_sha256.pk_compressed <== pk_compressor.compressed; for (var i = 0; i < 2; i++) { for (var j = 0; j < k; j++) { c_sha256.coordinates[i][j] <== g[i][j]; - c_sha256.coordinates[2+i][j] <== pk[i][j]; - c_sha256.coordinates[4+i][j] <== check_ec_equations.hashed_to_curve[i][j]; - c_sha256.coordinates[6+i][j] <== nullifier[i][j]; - c_sha256.coordinates[8+i][j] <== check_ec_equations.r_point[i][j]; - c_sha256.coordinates[10+i][j] <== check_ec_equations.hashed_to_curve_r[i][j]; + c_sha256.coordinates[2+i][j] <== check_ec_equations.hashed_to_curve[i][j]; + c_sha256.coordinates[4+i][j] <== nullifier[i][j]; + c_sha256.coordinates[6+i][j] <== check_ec_equations.r_point[i][j]; + c_sha256.coordinates[8+i][j] <== check_ec_equations.hashed_to_curve_r[i][j]; } } @@ -112,11 +117,15 @@ template plume_v2(n, k, message_length) { signal input q1_x_mapped[4]; signal input q1_y_mapped[4]; + component pk_compressor = compress_ec_point(n, k); + pk_compressor.uncompressed <== pk; + component check_ec_equations = check_ec_equations(n, k, message_length); check_ec_equations.c <== c; check_ec_equations.s <== s; check_ec_equations.pk <== pk; + check_ec_equations.pk_compressed <== pk_compressor.compressed; check_ec_equations.nullifier <== nullifier; check_ec_equations.plume_message <== plume_message; @@ -142,6 +151,7 @@ template check_ec_equations(n, k, message_length) { signal input s[k]; signal input plume_message[message_length]; signal input pk[2][k]; + signal input pk_compressed[33]; signal input nullifier[2][k]; signal output r_point[2][k]; @@ -183,14 +193,10 @@ template check_ec_equations(n, k, message_length) { component hash_to_curve = HashToCurve(message_length + 33); for (var i = 0; i < message_length; i++) { hash_to_curve.msg[i] <== plume_message[i]; - } - - component pk_compressor = compress_ec_point(n, k); - - pk_compressor.uncompressed <== pk; + } for (var i = 0; i < 33; i++) { - hash_to_curve.msg[message_length + i] <== pk_compressor.compressed[i]; + hash_to_curve.msg[message_length + i] <== pk_compressed[i]; } // Input precalculated values into HashToCurve @@ -255,12 +261,13 @@ template a_div_b_pow_c(n, k) { } template sha256_12_coordinates(n, k) { - signal input coordinates[12][k]; + signal input pk_compressed[33]; + signal input coordinates[10][k]; signal output out[256]; // compress coordinates - component compressors[6]; - for (var i = 0; i < 6; i++) { + component compressors[5]; + for (var i = 0; i < 5; i++) { compressors[i] = compress_ec_point(n, k); compressors[i].uncompressed[0] <== coordinates[2*i]; compressors[i].uncompressed[1] <== coordinates[2*i + 1]; @@ -270,8 +277,16 @@ template sha256_12_coordinates(n, k) { component binary[6*33]; for (var i = 0; i < 6; i++) { // for each compressor for (var j = 0; j < 33; j++) { // for each byte - binary[33*i + j] = Num2Bits(8); - binary[33*i + j].in <== compressors[i].compressed[j]; + if (i == 0) { + binary[33*i + j] = Num2Bits(8); + binary[33*i + j].in <== compressors[i].compressed[j]; + } else if (i == 1) { + binary[33*i + j] = Num2Bits(8); + binary[33*i + j].in <== pk_compressed[j]; + } else { + binary[33*i + j] = Num2Bits(8); + binary[33*i + j].in <== compressors[i-1].compressed[j]; + } } }