Skip to content

Commit

Permalink
Refactoring ecdh to work properly as a lib, extending it to use with …
Browse files Browse the repository at this point in the history
…other curves (#29)
  • Loading branch information
signorecello authored Feb 20, 2025
1 parent 3c51973 commit ce5e584
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 257 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
bun-version: latest
- uses: noir-lang/noirup@v0.1.3
with:
toolchain: 0.39.0
toolchain: 1.0.0-beta.1
- run: bun i
- run: bun fmt

Expand All @@ -44,5 +44,5 @@ jobs:
- uses: actions/checkout@v4
- uses: noir-lang/noirup@v0.1.3
with:
toolchain: 0.39.0
toolchain: 1.0.0-beta.1
- run: nargo test
7 changes: 3 additions & 4 deletions packages/ecdh/Nargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
[package]
name = "ecdh"
type = "bin"
authors = ["YashBit"]
compiler_version = ">=0.39.0"
type = "lib"
authors = ["YashBit", "signorecello"]

[dependencies]
ec = { tag = "v0.1.2", git = "https://github.com/noir-lang/ec" }
ec = { tag = "master", git = "https://github.com/noir-lang/ec" }
68 changes: 0 additions & 68 deletions packages/ecdh/Prover.toml

This file was deleted.

39 changes: 16 additions & 23 deletions packages/ecdh/README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,28 @@
# ECDH Library using Baby JubJub Curve
# ECDH Library

This repository introduces a set of functions and utilities for elliptic curve cryptography using the Baby JubJub curve. The library provides essential operations for the Elliptic Curve Diffie-Hellman (ECDH) protocol, along with utility functions for key generation, field element conversion, and shared key computation.
This repository introduces a set of functions and utilities for elliptic curve cryptography using. The library provides essential operations for the Elliptic Curve Diffie-Hellman (ECDH) protocol, along with utility functions for key generation, field element conversion, and shared key computation.

## Features

- **Byte Array to Field Element Conversion:** Utility functions to convert byte arrays into field elements for use in elliptic curve operations.
- **Public Key Generation:** Generate public keys from private keys using the Baby JubJub curve, with both standard and optimized methods.
- **Shared Key Computation:** Compute shared keys for secure communication using the ECDH protocol.
- **Main Function:** A main function to generate ECDH shared keys, demonstrating the usage of the library.
- **Testing:** Comprehensive tests to verify the correctness of key derivation and field conversion functions.

## Compiling the Circuit
At the moment only Baby JubJub is supported, feel free to contribute with more curves.

To compile the circuit, navigate one directory above the source code and run the following command:
## Features

```bash
nargo compile
```
- **Public Key Generation:** Generate public keys from private keys.
- **Shared Key Computation:** Compute shared keys for secure communication.

## Running Tests
## Usage

To run the tests for this library, use the following command:
To use this library, add the dependency to your `Nargo.toml`:

```bash
bun run test
```toml
ecdh = { git = "https://github.com/privacy-scaling-explorations/zk-kit.noir", tag = "main", directory = "packages/ecdh" }
```

## Running Tests with Mocha
You can then import the ECDH implementation for the curve you're working with, like so:

To run the tests using Mocha with TypeScript, use the following command:
```rust
use ecdh::bjj::BJJ; // only Baby JubJub is supported at the moment
let ecdh = BJJ::new(your_private_key);
let public_key = ecdh.derive_public_key();

```bash
npx mocha -r ts-node/register tests/ecdh.tests.ts
let shared_key = ecdh.derive_shared_key(someone_elses_public_key);
```
24 changes: 24 additions & 0 deletions packages/ecdh/src/bjj.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::ECDHTrait;
use ec::consts::te::{baby_jubjub, BabyJubjub};
use ec::tecurve::affine::Point;

pub struct BJJ {
pub private_key: Field,
pub bjj: BabyJubjub,
}

impl ECDHTrait for BJJ {
fn new(private_key: Field) -> Self {
let bjj = baby_jubjub();
Self { bjj, private_key }
}

fn derive_public_key(self) -> Point {
self.bjj.curve.mul(self.private_key, self.bjj.base8)
}

fn derive_shared_key(self, public_key: Point) -> Field {
let shared_key = self.bjj.curve.mul(self.private_key, public_key);
shared_key.x
}
}
6 changes: 0 additions & 6 deletions packages/ecdh/src/globals.nr

This file was deleted.

62 changes: 6 additions & 56 deletions packages/ecdh/src/lib.nr
Original file line number Diff line number Diff line change
@@ -1,58 +1,8 @@
mod globals;
use ec::tecurve::affine::{Curve, Point};
mod bjj;
use ec::tecurve::affine::Point;

// @@@@@@ Core ECDH Implementation

/// Converts a byte array to a field element.
/// # Arguments
/// * `bytes` - A fixed-size array of 32 bytes.
/// * `big_endian` - A boolean indicating if the byte array is in big-endian format.
/// # Returns
/// A `Field` element representing the converted byte array.
pub fn field_from_bytes(bytes: [u8; 32], big_endian: bool) -> Field {
let mut as_field: Field = 0;
let mut offset: Field = 1;

for i in 0..32 {
let index = if big_endian { 31 - i } else { i };
as_field += (bytes[index] as Field) * offset;
offset *= 256;
}

as_field
}

/// Computes a public key from a private key using the Baby JubJub curve.
/// # Arguments
/// * `private_key` - The private key as a `Field` element.
/// # Returns
/// The corresponding `Point` on the Baby JubJub curve.
pub fn derive_public_key(private_key: Field) -> Point {
let base_point = Point::new(
5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203,
);
let baby_jubjub_curve = Curve::new(168700, 168696, base_point);
baby_jubjub_curve.mul(private_key, base_point)
}

/// Optimized public key derivation using Baby JubJub curve.
/// # Arguments
/// * `private_key` - The private key as a `Field` element.
/// # Returns
/// The public key as a `Point` on the Baby JubJub curve.
pub fn derive_public_key_optimized(private_key: Field) -> Point {
let X = globals::BJJ.curve.mul(private_key, globals::G);
X
}

/// Computes a shared secret key using ECDH with the Baby JubJub curve.
/// # Arguments
/// * `private_key` - The private key as a `Field` element.
/// * `public_key` - The public key as a `Point` on the Baby JubJub curve.
/// # Returns
/// The shared secret key as a `Field` element.
pub fn derive_shared_key(private_key: Field, public_key: Point) -> Field {
let shared_key = globals::BJJ.curve.mul(private_key, public_key);
shared_key.x
pub trait ECDHTrait {
fn new(private_key: Field) -> Self;
fn derive_public_key(self) -> Point;
fn derive_shared_key(self, public_key: Point) -> Field;
}
45 changes: 0 additions & 45 deletions packages/ecdh/src/main.nr

This file was deleted.

47 changes: 0 additions & 47 deletions packages/ecdh/tests/ecdh.test.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/merkle-trees/Nargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@
name = "merkle_trees"
type = "lib"
authors = ["fabianschu", "signorecello"]
compiler_version = ">=0.39.0"
9 changes: 5 additions & 4 deletions tests/Nargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
[package]
name = "merkle_trees"
name = "zk_kit_tests"
type = "lib"
authors = ["fabianschu", "signorecello"]
compiler_version = ">=0.39.0"
authors = ["signorecello"]

[dependencies]
bignum = { git = "https://github.com/noir-lang/noir-bignum", tag = "zpedro/default_trait" }
bignum = { git = "https://github.com/noir-lang/noir-bignum", tag = "main" }
trees = { path = "../packages/merkle-trees" }
ecdh = { path = "../packages/ecdh" }
ec = { tag = "master", git = "https://github.com/noir-lang/ec" }
30 changes: 30 additions & 0 deletions tests/src/ecdh/mod.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use ec::tecurve::affine::Point;
use ecdh::bjj::BJJ;

global alice_sk: Field = 0x60c0102756aac2cf5d7277792a469bff83dfe3d3e7e50ad5a55383f3a89283e;
global bob_sk: Field = 0x86cdaad8886954a2eb20142fb98468d476a2d6c7b2c571af42cdc041b1a923c;

#[test]
fn test_pk() {
let ecdh = BJJ::new(alice_sk);
let expected_pk = Point::new(
0x17d6ff45a37eee4ca071bb451c09b47184ed67492c6bac9279fb0a7d2d4ad1dc,
0x02d3a6338eee1ae8a38b278ce6c13179889c780f5e0d7294b904b0fa52c7dc3e,
);
let pk = ecdh.derive_public_key();
assert(pk == expected_pk);
}

#[test]
fn test_shared_k() {
let alice_ecdh = BJJ::new(alice_sk);
let bob_ecdh = BJJ::new(bob_sk);

let alice_pk: Point = alice_ecdh.derive_public_key();
let bob_pk: Point = bob_ecdh.derive_public_key();

let shared_key_with_bob = alice_ecdh.derive_shared_key(bob_pk);
let shared_key_with_alice = bob_ecdh.derive_shared_key(alice_pk);

assert(shared_key_with_bob == shared_key_with_alice);
}
1 change: 1 addition & 0 deletions tests/src/lib.nr
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
mod mt;
mod smt;
mod ecdh;
Loading

0 comments on commit ce5e584

Please sign in to comment.