-
Notifications
You must be signed in to change notification settings - Fork 23
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
Showing
19 changed files
with
486 additions
and
259 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
name: Circom checks | ||
on: [push, pull_request] | ||
|
||
concurrency: | ||
group: ${{ github.workflow }}-${{ github.ref }} | ||
cancel-in-progress: true | ||
|
||
jobs: | ||
checks: | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
node-version: [18] | ||
command: ["prettier", "types", "test:coverage"] | ||
|
||
runs-on: ubuntu-latest | ||
|
||
timeout-minutes: 240 | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Clone circom repository | ||
uses: actions/checkout@v4 | ||
with: | ||
repository: iden3/circom | ||
path: ./circom | ||
|
||
- uses: pnpm/action-setup@v2 | ||
with: | ||
version: latest | ||
|
||
- uses: actions/setup-node@v4 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
|
||
- uses: dtolnay/rust-toolchain@nightly | ||
with: | ||
components: "clippy, rustfmt" | ||
|
||
- name: Cache circom | ||
uses: actions/cache@v3 | ||
id: circom-cache | ||
continue-on-error: true | ||
with: | ||
path: | | ||
~/.cargo/bin/circom | ||
key: ${{ runner.os }}-circom-${{ hashFiles('./circom/Cargo.lock') }} | ||
restore-keys: | | ||
${{ runner.os }}-circom- | ||
- name: Install circom | ||
if: steps.circom-cache.outputs.cache-hit != 'true' | ||
run: | | ||
cargo build --release | ||
cargo install --path circom | ||
working-directory: ./circom | ||
|
||
|
||
- name: Build javascript | ||
run: | | ||
pnpm install --no-frozen-lockfile --prefer-offline | ||
pnpm run build | ||
working-directory: "./javascript" | ||
|
||
- name: Check circom | ||
run: | | ||
pnpm install --no-frozen-lockfile --prefer-offline | ||
pnpm run ${{ matrix.command }} | ||
working-directory: "./circuits/circom" |
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
2 changes: 1 addition & 1 deletion
2
.../circom/test/12_point_sha_256_test.circom → ...est/circuits/12_point_sha_256_test.circom
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 |
---|---|---|
@@ -1,5 +1,5 @@ | ||
pragma circom 2.1.2; | ||
|
||
include "../verify_nullifier.circom"; | ||
include "../../verify_nullifier.circom"; | ||
|
||
component main = sha256_12_coordinates(64, 4); |
2 changes: 1 addition & 1 deletion
2
...its/circom/test/a_div_b_pow_c_test.circom → ...m/test/circuits/a_div_b_pow_c_test.circom
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 |
---|---|---|
@@ -1,5 +1,5 @@ | ||
pragma circom 2.1.2; | ||
|
||
include "../verify_nullifier.circom"; | ||
include "../../verify_nullifier.circom"; | ||
|
||
component main = a_div_b_pow_c(64, 4); |
2 changes: 1 addition & 1 deletion
2
circuits/circom/test/compression_test.circom → ...com/test/circuits/compression_test.circom
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 |
---|---|---|
@@ -1,5 +1,5 @@ | ||
pragma circom 2.1.2; | ||
|
||
include "../verify_nullifier.circom"; | ||
include "../../verify_nullifier.circom"; | ||
|
||
component main = compress_ec_point(64, 4); |
2 changes: 1 addition & 1 deletion
2
...test/compression_verification_test.circom → ...uits/compression_verification_test.circom
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 |
---|---|---|
@@ -1,5 +1,5 @@ | ||
pragma circom 2.1.2; | ||
|
||
include "../verify_nullifier.circom"; | ||
include "../../verify_nullifier.circom"; | ||
|
||
component main = verify_ec_compression(64, 4); |
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,5 @@ | ||
pragma circom 2.1.2; | ||
|
||
include "../../node_modules/secp256k1_hash_to_curve_circom/circom/hash_to_curve.circom"; | ||
|
||
component main = HashToCurve(62); |
2 changes: 1 addition & 1 deletion
2
circuits/circom/test/v1_test.circom → circuits/circom/test/circuits/v1_test.circom
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 |
---|---|---|
@@ -1,5 +1,5 @@ | ||
pragma circom 2.1.2; | ||
|
||
include "../verify_nullifier.circom"; | ||
include "../../verify_nullifier.circom"; | ||
|
||
component main = plume_v1(64, 4, 29); |
2 changes: 1 addition & 1 deletion
2
circuits/circom/test/v2_test.circom → circuits/circom/test/circuits/v2_test.circom
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 |
---|---|---|
@@ -1,5 +1,5 @@ | ||
pragma circom 2.1.2; | ||
|
||
include "../verify_nullifier.circom"; | ||
include "../../verify_nullifier.circom"; | ||
|
||
component main = plume_v2(64, 4, 29); |
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,76 @@ | ||
import path from "path"; | ||
|
||
import { Point } from "@noble/secp256k1"; | ||
import { wasm as wasm_tester } from "circom_tester"; | ||
|
||
import { | ||
rPoint, | ||
hashMPk, | ||
hashedToCurveR, | ||
nullifier, | ||
testSecretKey, | ||
} from "../../../javascript/test/consts"; | ||
import { hexToBigInt } from "../../../javascript/src/utils/encoding"; | ||
|
||
import { pointToCircuitValue } from "../utils"; | ||
|
||
jest.setTimeout(20_000); | ||
|
||
describe("Compression Circuit", () => { | ||
const hashMPkPoint = new Point( | ||
hexToBigInt(hashMPk.x.toString()), | ||
hexToBigInt(hashMPk.y.toString()), | ||
); | ||
|
||
const sha_preimage_points: Point[] = [ | ||
Point.BASE, | ||
Point.fromPrivateKey(testSecretKey), | ||
hashMPkPoint, | ||
nullifier, | ||
rPoint, | ||
hashedToCurveR, | ||
]; | ||
|
||
test("Correct compressed values are calculated", async () => { | ||
const p = path.join(__dirname, "./circuits/compression_test.circom"); | ||
const circuit = await wasm_tester(p, { json: true, sym: true }); | ||
|
||
for (let i = 0; i < sha_preimage_points.length; i++) { | ||
const w = await circuit.calculateWitness( | ||
{ uncompressed: pointToCircuitValue(sha_preimage_points[i]) }, | ||
true, | ||
); | ||
|
||
await circuit.checkConstraints(w); | ||
await circuit.assertOut(w, { | ||
compressed: Array.from(sha_preimage_points[i].toRawBytes(true)), | ||
}); | ||
} | ||
}); | ||
|
||
test("Compressed points are permitted if they are valid", async () => { | ||
const p = path.join( | ||
__dirname, | ||
"./circuits/compression_verification_test.circom", | ||
); | ||
const circuit = await wasm_tester(p, { json: true, sym: true }); | ||
|
||
for (let i = 0; i < sha_preimage_points.length; i++) { | ||
for (let j = 0; j <= i; j++) { | ||
const inputs = { | ||
uncompressed: pointToCircuitValue(sha_preimage_points[i]), | ||
compressed: Array.from(sha_preimage_points[j].toRawBytes(true)), | ||
}; | ||
|
||
if (i === j) { | ||
const w = await circuit.calculateWitness(inputs, true); | ||
await circuit.checkConstraints(w); | ||
} else { | ||
await expect(circuit.calculateWitness(inputs)).rejects.toThrow( | ||
"Assert Failed", | ||
); | ||
} | ||
} | ||
} | ||
}); | ||
}); |
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,14 @@ | ||
import { circuitValueToScalar, scalarToCircuitValue } from "../utils"; | ||
|
||
describe("Conversion", () => { | ||
test("bigint <-> register conversion", async () => { | ||
[ | ||
132467823045762934876529873465987623452222345n, | ||
57574748379385798237094756982679876233455n, | ||
55757457845857572n, | ||
1n, | ||
].forEach((value) => { | ||
expect(circuitValueToScalar(scalarToCircuitValue(value))).toBe(value); | ||
}); | ||
}); | ||
}); |
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,39 @@ | ||
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 { utils } from "ffjavascript"; | ||
|
||
import { | ||
hashMPk, | ||
testMessage, | ||
testPublicKey, | ||
} from "../../../javascript/test/consts"; | ||
import { hexToBigInt } from "../../../javascript/src/utils/encoding"; | ||
|
||
import { pointToCircuitValue } from "../utils"; | ||
|
||
jest.setTimeout(2_000_000); | ||
|
||
describe("Hash to curve", () => { | ||
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)), | ||
); | ||
|
||
test("should outputs same value", async () => { | ||
const p = path.join(__dirname, "./circuits/hash_to_curve_test.circom"); | ||
const circuit = await wasm_tester(p, { json: true, sym: true }); | ||
const w = await circuit.calculateWitness({ ...hash_to_curve_inputs }, true); | ||
await circuit.checkConstraints(w); | ||
await circuit.assertOut(w, { out: pointToCircuitValue(hashMPkPoint) }); | ||
}); | ||
}); |
This file was deleted.
Oops, something went wrong.
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,75 @@ | ||
import crypto from "crypto"; | ||
import path from "path"; | ||
|
||
import { Point } from "@noble/secp256k1"; | ||
import { wasm as wasm_tester } from "circom_tester"; | ||
import { bufToSha256PaddedBitArr } from "secp256k1_hash_to_curve_circom/ts/utils"; | ||
|
||
import { | ||
c_v1, | ||
rPoint, | ||
hashMPk, | ||
hashedToCurveR, | ||
nullifier, | ||
testSecretKey, | ||
} from "../../../javascript/test/consts"; | ||
import { | ||
hexToBigInt, | ||
concatUint8Arrays, | ||
} from "../../../javascript/src/utils/encoding"; | ||
|
||
import { pointToCircuitValue } from "../utils"; | ||
|
||
jest.setTimeout(2_000_000); | ||
|
||
describe("SHA256 Circuit", () => { | ||
const hashMPkPoint = new Point( | ||
hexToBigInt(hashMPk.x.toString()), | ||
hexToBigInt(hashMPk.y.toString()), | ||
); | ||
|
||
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("") | ||
.map(Number); | ||
|
||
test("Correct sha256 value", async () => { | ||
const coordinates = []; | ||
sha_preimage_points.forEach((point) => { | ||
const cv = pointToCircuitValue(point); | ||
coordinates.push(cv[0]); | ||
coordinates.push(cv[1]); | ||
}); | ||
|
||
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, preimage_bit_length: v1_sha256_preimage_bit_length }, | ||
true, | ||
); | ||
await circuit.checkConstraints(w); | ||
await circuit.assertOut(w, { out: v1_binary_c }); | ||
}); | ||
}); |
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,41 @@ | ||
import path from "path"; | ||
|
||
import { Point } from "@noble/secp256k1"; | ||
import { wasm as wasm_tester } from "circom_tester"; | ||
|
||
import { | ||
c_v1, | ||
rPoint, | ||
s_v1, | ||
testSecretKey, | ||
} from "../../../javascript/test/consts"; | ||
import { hexToBigInt } from "../../../javascript/src/utils/encoding"; | ||
|
||
import { pointToCircuitValue, scalarToCircuitValue } from "../utils"; | ||
|
||
jest.setTimeout(2_000_000); | ||
|
||
// This tests that our circuit correctly computes g^s/(g^sk)^c = g^r, and that the first two equations are | ||
// implicitly verified correctly. | ||
describe("a/b^c subcircuit", () => { | ||
test("should check circuit calculation", async () => { | ||
const p = path.join(__dirname, "./circuits/a_div_b_pow_c_test.circom"); | ||
const circuit = await wasm_tester(p); | ||
|
||
// Verify that gPowS/pkPowC = gPowR outside the circuit, as a sanity check | ||
const gPowS = Point.fromPrivateKey(s_v1); | ||
const pkPowC = Point.fromPrivateKey(testSecretKey).multiply( | ||
hexToBigInt(c_v1), | ||
); | ||
expect(gPowS.add(pkPowC.negate()).equals(rPoint)).toBe(true); | ||
|
||
// Verify that circuit calculates g^s / pk^c = g^r | ||
const w = await circuit.calculateWitness({ | ||
a: pointToCircuitValue(gPowS), | ||
b: pointToCircuitValue(Point.fromPrivateKey(testSecretKey)), | ||
c: scalarToCircuitValue(hexToBigInt(c_v1)), | ||
}); | ||
await circuit.checkConstraints(w); | ||
await circuit.assertOut(w, { out: pointToCircuitValue(rPoint) }); | ||
}); | ||
}); |
Oops, something went wrong.