Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ digest = "0.10.7"
generic-array = "0.14.7"
getrandom = "0.3.3"
getset = "0.1.6"
hex = "0.4.3"
Comment thread
jadnohra marked this conversation as resolved.
hex-literal = "1.0.0"
either = "1.11.0"
itertools = "0.14.0"
Expand Down
2 changes: 2 additions & 0 deletions crates/examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ base64.workspace = true
blake2.workspace = true
jwt-simple.workspace = true
sha2.workspace = true
hex.workspace = true
k256 = { workspace = true, features = ["arithmetic"] }
Comment thread
graphite-app[bot] marked this conversation as resolved.

[dev-dependencies]
criterion.workspace = true
Expand Down
10 changes: 10 additions & 0 deletions crates/examples/examples/semaphore_ecdsa.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use anyhow::Result;
use binius_examples::{Cli, circuits::semaphore_ecdsa::SemaphoreExample};

fn main() -> Result<()> {
let _tracing_guard = tracing_profile::init_tracing()?;

Cli::<SemaphoreExample>::new("semaphore_ecdsa")
.about("Anonymous group membership proofs with nullifiers using ECDSA key derivation")
.run()
}
11 changes: 11 additions & 0 deletions crates/examples/snapshots/semaphore_ecdsa.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
semaphore_ecdsa circuit
--
Number of gates: 475686
Number of evaluation instructions: 563535
Number of AND constraints: 609289
Number of MUL constraints: 48536
Length of value vec: 1048576
Constants: 72
Inout: 11
Witness: 97
Internal: 887101
1 change: 1 addition & 0 deletions crates/examples/src/circuits/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod blake2s;
pub mod ethsign;
pub mod keccak;
pub mod semaphore_ecdsa;
pub mod sha256;
pub mod sha512;
pub mod zklogin;
112 changes: 112 additions & 0 deletions crates/examples/src/circuits/semaphore_ecdsa.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use anyhow::{Result, ensure};
use binius_frontend::{
circuits::semaphore_ecdsa::{IdentityECDSA, MerkleTree, SemaphoreProofECDSA},
compiler::{CircuitBuilder, circuit::WitnessFiller},
};
use clap::Args;

use crate::ExampleCircuit;

/// Semaphore anonymous group membership proof with ECDSA key derivation
pub struct SemaphoreExample {
circuit: SemaphoreProofECDSA,
tree_height: usize,
message_len_bytes: usize,
scope_len_bytes: usize,
}

#[derive(Args, Debug, Clone)]
pub struct Params {
/// Height of the Merkle tree (determines max group size = 2^height)
#[arg(long, default_value_t = 2)]
pub tree_height: usize,

/// Maximum message length in bytes
#[arg(long, default_value_t = 32)]
pub message_len_bytes: usize,

/// Maximum scope length in bytes
#[arg(long, default_value_t = 24)]
pub scope_len_bytes: usize,
}

#[derive(Args, Debug, Clone)]
pub struct Instance {
/// Number of group members to create
#[arg(long, default_value_t = 4)]
pub group_size: usize,

/// Index of the member generating the proof (0-based)
#[arg(long, default_value_t = 1)]
pub prover_index: usize,

/// Message to include in the proof
#[arg(long, default_value = "I vote YES on proposal #42")]
pub message: String,

/// Scope for this signal (prevents double-signaling within scope)
#[arg(long, default_value = "dao_vote_2024_q1")]
pub scope: String,
}

impl ExampleCircuit for SemaphoreExample {
type Params = Params;
type Instance = Instance;

fn build(params: Params, builder: &mut CircuitBuilder) -> Result<Self> {
ensure!(params.tree_height > 0, "Tree height must be > 0");
ensure!(params.message_len_bytes > 0, "Message length must be > 0");
ensure!(params.scope_len_bytes > 0, "Scope length must be > 0");

let circuit = SemaphoreProofECDSA::new(
builder,
params.tree_height,
params.message_len_bytes,
params.scope_len_bytes,
);

Ok(Self {
circuit,
tree_height: params.tree_height,
message_len_bytes: params.message_len_bytes,
scope_len_bytes: params.scope_len_bytes,
})
}

fn populate_witness(&self, instance: Instance, witness: &mut WitnessFiller) -> Result<()> {
// Validate inputs
ensure!(instance.group_size > 0, "Group size must be > 0");
ensure!(instance.prover_index < instance.group_size, "Prover index must be < group size");
ensure!(instance.group_size <= (1 << self.tree_height), "Group size exceeds tree capacity");
ensure!(instance.message.len() <= self.message_len_bytes, "Message too long");
ensure!(instance.scope.len() <= self.scope_len_bytes, "Scope too long");

// Create ECDSA identities
let mut identities = Vec::new();
for i in 0..instance.group_size {
let secret_scalar = [((i + 42) as u8); 32];
identities.push(IdentityECDSA::new(secret_scalar));
}

// Build Merkle tree
let mut tree = MerkleTree::new(self.tree_height);
for identity in &identities {
tree.add_leaf(identity.commitment());
}

// Get proof for the prover
let prover_identity = &identities[instance.prover_index];
let merkle_proof = tree.proof(instance.prover_index);

// Populate witness
self.circuit.populate_witness(
witness,
prover_identity,
&merkle_proof,
instance.message.as_bytes(),
instance.scope.as_bytes(),
);

Ok(())
}
}
1 change: 1 addition & 0 deletions crates/frontend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ serde_json.workspace = true
sha2.workspace = true
sha3.workspace = true
smallvec.workspace = true
k256 = { workspace = true, features = ["arithmetic"] }

[dev-dependencies]
base64 = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions crates/frontend/src/circuits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub mod popcount;
pub mod ripemd;
pub mod rs256;
pub mod secp256k1;
pub mod semaphore_ecdsa;
pub mod sha256;
pub mod sha512;
pub mod skein512;
Expand Down
Loading
Loading