From 378573fab89ce93ff7461e657fb0c2281c41b9ad Mon Sep 17 00:00:00 2001 From: cypriansakwa Date: Thu, 14 Aug 2025 19:54:53 +0300 Subject: [PATCH 1/4] First commit --- .github/workflows/discrete_log_example.yml | 43 ++++++++++++++++++++++ discrete_log_example | 1 + 2 files changed, 44 insertions(+) create mode 100644 .github/workflows/discrete_log_example.yml create mode 160000 discrete_log_example diff --git a/.github/workflows/discrete_log_example.yml b/.github/workflows/discrete_log_example.yml new file mode 100644 index 0000000..4364db0 --- /dev/null +++ b/.github/workflows/discrete_log_example.yml @@ -0,0 +1,43 @@ +name: Run discrete_log_example Tests on PR +on: + pull_request: + paths: + - "discrete_log_example/**" + schedule: + - cron: "0 2 * * *" + workflow_dispatch: + +jobs: + test: + defaults: + run: + working-directory: discrete_log_example + permissions: + issues: write + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Nargo + uses: noir-lang/noirup@v0.1.2 + with: + toolchain: stable + + - name: Run Noir unit tests + working-directory: discrete_log_example/circuits + run: | + nargo test + + - name: Create issue on failure (nightly) + if: failure() && github.event_name == 'schedule' + uses: actions/github-script@v6 + with: + script: | + github.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: '[Nightly] discrete_log_example workflow failed', + body: `The nightly discrete_log_example workflow failed. Please investigate.\n\n/cc @noir-lang/developerrelations`, + labels: ['nightly', 'bug'] + }) \ No newline at end of file diff --git a/discrete_log_example b/discrete_log_example new file mode 160000 index 0000000..e7b4f17 --- /dev/null +++ b/discrete_log_example @@ -0,0 +1 @@ +Subproject commit e7b4f17d0193eadb600d988503f7a327ce057ca6 From e8a91b4b5b87ecbd06a46d46ff4ec1f51417579f Mon Sep 17 00:00:00 2001 From: cypriansakwa Date: Fri, 15 Aug 2025 01:03:50 +0300 Subject: [PATCH 2/4] Remove discrete_log_example as submodule --- discrete_log_example | 1 - 1 file changed, 1 deletion(-) delete mode 160000 discrete_log_example diff --git a/discrete_log_example b/discrete_log_example deleted file mode 160000 index e7b4f17..0000000 --- a/discrete_log_example +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e7b4f17d0193eadb600d988503f7a327ce057ca6 From 70e61287e6c4b87a317bd6b78aff58e49dc4d971 Mon Sep 17 00:00:00 2001 From: cypriansakwa Date: Fri, 15 Aug 2025 01:04:18 +0300 Subject: [PATCH 3/4] Add discrete_log_example as a normal folder --- discrete_log_example/.gitignore | 1 + discrete_log_example/README.md | 42 ++++++++++++ discrete_log_example/circuits/Nargo.toml | 9 +++ discrete_log_example/circuits/Prover.toml | 14 ++++ discrete_log_example/circuits/src/main.nr | 78 +++++++++++++++++++++++ 5 files changed, 144 insertions(+) create mode 100644 discrete_log_example/.gitignore create mode 100644 discrete_log_example/README.md create mode 100644 discrete_log_example/circuits/Nargo.toml create mode 100644 discrete_log_example/circuits/Prover.toml create mode 100644 discrete_log_example/circuits/src/main.nr diff --git a/discrete_log_example/.gitignore b/discrete_log_example/.gitignore new file mode 100644 index 0000000..d4e3d73 --- /dev/null +++ b/discrete_log_example/.gitignore @@ -0,0 +1 @@ +circuits/target/ \ No newline at end of file diff --git a/discrete_log_example/README.md b/discrete_log_example/README.md new file mode 100644 index 0000000..5274a0f --- /dev/null +++ b/discrete_log_example/README.md @@ -0,0 +1,42 @@ +# Noir Elliptic Curve Discrete Log Proof Circuit + +This repository contains a Noir circuit for proving knowledge of the discrete logarithm on the secp256k1 elliptic curve. The circuit demonstrates, in zero-knowledge, that the prover knows a secret scalar \( k \) such that \( Q = k \cdot G \), where \( G \) is a public point and \( Q \) is the resulting public point. + +## Features + +- **Proves knowledge of discrete log:** + Given a base point \( G = (x, y) \), a secret scalar \( k \) (kept private), and a result point \( Q = (x', y') \), the circuit proves that \( Q = k \cdot G \) without revealing \( k \). + +- **Curve Membership Checks:** + Both \( G \) and \( Q \) are asserted to be on the secp256k1 curve. + +- **Flexible Test Suite:** + Includes tests for: + - Correct proofs (valid \( k \), \( G \), \( Q \)) + - Invalid results + - Non-curve points + - Edge cases (e.g., zero scalar, point at infinity) + +## Structure + +- `src/main.nr` + Main Noir circuit, containing the core logic and tests. +- `src/` + May contain additional helper or test files. +- `README.md` + This file. + +## Usage + +### Requirements + +- [Noir](https://noir-lang.org/) (v0.18+ recommended) +- [nargo](https://noir-lang.org/docs/getting_started/quick_start#installation) (Noir package manager) +- Rust (for installing Noir) + +### Running Tests + +To run all tests: + +```bash +nargo test \ No newline at end of file diff --git a/discrete_log_example/circuits/Nargo.toml b/discrete_log_example/circuits/Nargo.toml new file mode 100644 index 0000000..89cb089 --- /dev/null +++ b/discrete_log_example/circuits/Nargo.toml @@ -0,0 +1,9 @@ +[package] +name = "discrete_log_example" +type = "bin" +authors = [""] +compiler_version = ">=1.0.0" + +[dependencies] +noir_bigcurve = { git = "https://github.com/noir-lang/noir_bigcurve", tag = "v0.9.0" } +bignum = { tag = "v0.7.3", git = "https://github.com/noir-lang/noir-bignum" } \ No newline at end of file diff --git a/discrete_log_example/circuits/Prover.toml b/discrete_log_example/circuits/Prover.toml new file mode 100644 index 0000000..978e596 --- /dev/null +++ b/discrete_log_example/circuits/Prover.toml @@ -0,0 +1,14 @@ +[g_x] +limbs = ["809934545436666192144300149831112600", "532189659306663695932703699144214274", "31166"] + +[g_y] +limbs = ["123079417438355278731207347528586424", "1134337383257087261818981465599813885", "18490"] + +[k] +limbs = ["2", "0", "0"] + +[q_x] +limbs = ["620769414058672675662360539292540645", "662428720985405666719129047941306460", "50692"] + +[q_y] +limbs = ["1278327165322711450801813382677652778", "545163776316525295403132726738087671", "6881"] diff --git a/discrete_log_example/circuits/src/main.nr b/discrete_log_example/circuits/src/main.nr new file mode 100644 index 0000000..e161961 --- /dev/null +++ b/discrete_log_example/circuits/src/main.nr @@ -0,0 +1,78 @@ +use noir_bigcurve::curves::secp256k1::Secp256k1; +use noir_bigcurve::curves::secp256k1::Secp256k1Scalar; +use noir_bigcurve::scalar_field::ScalarFieldTrait; +use noir_bigcurve::BigCurveTrait; +use bignum::{Secp256k1_Fq, Secp256k1_Fr, BigNum}; + +// No 'pub' on these +fn prove_discrete_log( + g_x: Secp256k1_Fq, + g_y: Secp256k1_Fq, + k: Secp256k1_Fr, + q_x: Secp256k1_Fq, + q_y: Secp256k1_Fq, +) { + let G = Secp256k1 { x: g_x, y: g_y, is_infinity: false }; + assert(!G.is_infinity); + G.validate_on_curve(); + + let Q = Secp256k1 { x: q_x, y: q_y, is_infinity: false }; + Q.validate_on_curve(); + + let k_scalar: Secp256k1Scalar = Secp256k1Scalar::from_bignum(k); + let computed_Q = G.mul(k_scalar); + + assert(computed_Q.x == q_x); + assert(computed_Q.y == q_y); +} + +// Only 'pub' in main for public inputs +pub fn main( + g_x: pub Secp256k1_Fq, + g_y: pub Secp256k1_Fq, + k: Secp256k1_Fr, + q_x: pub Secp256k1_Fq, + q_y: pub Secp256k1_Fq, +) { + prove_discrete_log(g_x, g_y, k, q_x, q_y); +} +// Example test: Prove knowledge of k such that Q = kG +#[test] +fn test_prove_discrete_log() { + let g_x = Secp256k1_Fq::from_limbs([809934545436666192144300149831112600, 532189659306663695932703699144214274, 31166]); + let g_y = Secp256k1_Fq::from_limbs([123079417438355278731207347528586424, 1134337383257087261818981465599813885, 18490]); + + // Secret scalar k (witness) + let k = Secp256k1_Fr::from_limbs([2,0,0]); + + // Public Q = k * G + let q_x = Secp256k1_Fq::from_limbs([620769414058672675662360539292540645, 662428720985405666719129047941306460, 50692]); + let q_y = Secp256k1_Fq::from_limbs([1278327165322711450801813382677652778, 545163776316525295403132726738087671, 6881]); + + prove_discrete_log(g_x, g_y, k, q_x, q_y); +} + +#[test(should_fail)] +fn test_prove_discrete_log_wrong_Q() { + let g_x = Secp256k1_Fq::from_limbs([809934545436666192144300149831112600, 532189659306663695932703699144214274, 31166]); + let g_y = Secp256k1_Fq::from_limbs([123079417438355278731207347528586424, 1134337383257087261818981465599813885, 18490]); + + let k = Secp256k1_Fr::from_limbs([2,0,0]); + + // Wrong Q + let q_x = Secp256k1_Fq::from_limbs([258484535409603203050605737993582329, 716568843669635254349561846039718325, 63792]); + let q_y = Secp256k1_Fq::from_limbs([3439865459799723184042666981123698, 638964607539318458049780617139410533, 14479]); + + prove_discrete_log(g_x, g_y, k, q_x, q_y); +} +#[test(should_fail)] +fn test_prove_discrete_log_wrong_point() { + // Deliberately choose a point NOT on secp256k1 + let bad_x = Secp256k1_Fq::from_limbs([258484535409603203050605737993582330, 716568843669635254349561846039718325, 63792]); + let bad_y = Secp256k1_Fq::from_limbs([3439865459799723184042666981123699, 638964607539318458049780617139410533, 14479]); + let k = Secp256k1_Fr::from_limbs([2,0,0]); + let q_x = Secp256k1_Fq::from_limbs([516969070819206406101211480282132933, 103909691554354635795316631799092074, 62049]); + let q_y = Secp256k1_Fq::from_limbs([6879730919599446368085333962247398, 1277929215078636916099561234278821066, 28958]); + + prove_discrete_log(bad_x, bad_y, k, q_x, q_y); +} \ No newline at end of file From 329fafdecf0a5f16df39de67eb370a0104598f5c Mon Sep 17 00:00:00 2001 From: cypriansakwa Date: Mon, 6 Oct 2025 19:51:20 +0300 Subject: [PATCH 4/4] Remove problematic GitHub workflow: discrete_log_example.yml --- .github/workflows/discrete_log_example.yml | 43 ---------------------- 1 file changed, 43 deletions(-) delete mode 100644 .github/workflows/discrete_log_example.yml diff --git a/.github/workflows/discrete_log_example.yml b/.github/workflows/discrete_log_example.yml deleted file mode 100644 index 4364db0..0000000 --- a/.github/workflows/discrete_log_example.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Run discrete_log_example Tests on PR -on: - pull_request: - paths: - - "discrete_log_example/**" - schedule: - - cron: "0 2 * * *" - workflow_dispatch: - -jobs: - test: - defaults: - run: - working-directory: discrete_log_example - permissions: - issues: write - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install Nargo - uses: noir-lang/noirup@v0.1.2 - with: - toolchain: stable - - - name: Run Noir unit tests - working-directory: discrete_log_example/circuits - run: | - nargo test - - - name: Create issue on failure (nightly) - if: failure() && github.event_name == 'schedule' - uses: actions/github-script@v6 - with: - script: | - github.issues.create({ - owner: context.repo.owner, - repo: context.repo.repo, - title: '[Nightly] discrete_log_example workflow failed', - body: `The nightly discrete_log_example workflow failed. Please investigate.\n\n/cc @noir-lang/developerrelations`, - labels: ['nightly', 'bug'] - }) \ No newline at end of file