Skip to content

Instantly share code, notes, and snippets.

@mukeshtiwari
Created September 13, 2026 14:30
Show Gist options
  • Select an option

  • Save mukeshtiwari/d44df0ae58397df5828d78da6cd37636 to your computer and use it in GitHub Desktop.

Select an option

Save mukeshtiwari/d44df0ae58397df5828d78da6cd37636 to your computer and use it in GitHub Desktop.
use curve25519_dalek::ristretto::RistrettoPoint as G;
use group::Group;
use sigma_proofs::composition::{ComposedRelation, ComposedWitness};
use sigma_proofs::traits::{SigmaProtocol, SigmaProtocolSimulator};
mod relations;
pub use relations::*;
fn wrong<R: rand::RngCore + rand::CryptoRng>(n: usize, rng: &mut R) -> Vec<<G as Group>::Scalar> {
(0..n).map(|_| <G as Group>::Scalar::random(&mut *rng)).collect()
}
// Control: a simulated transcript of a flat OR must verify under the
// challenge the simulator returns.
#[test]
fn simulated_flat_or_verifies() {
let mut rng = rand::thread_rng();
let (r1, _) = dleq::<G>(&mut rng);
let (r2, _) = dleq::<G>(&mut rng);
let or = ComposedRelation::<G>::or([r1, r2]);
let (comm, ch, resp) = or.simulate_transcript(&mut rng).unwrap();
assert!(or.verifier(&comm, &ch, &resp).is_ok(), "flat OR simulator inconsistent");
}
// Inner OR is the branch WITHOUT a witness: the outer OR must simulate it.
#[test]
fn nested_or_simulated_inner_branch() {
let mut rng = rand::thread_rng();
let (r1, w1) = dleq::<G>(&mut rng);
let (r2, w2) = dleq::<G>(&mut rng);
let (r3, w3) = dleq::<G>(&mut rng);
let inner = ComposedRelation::<G>::or([r1, r2]);
let inner_w = ComposedWitness::or([wrong(w1.len(), &mut rng), wrong(w2.len(), &mut rng)]);
let outer = ComposedRelation::or([inner, r3.into()]);
let outer_w = ComposedWitness::or([inner_w, w3.into()]);
let nizk = outer.into_nizk(b"nested-or");
let proof = nizk.prove_batchable(&outer_w, &mut rng).unwrap();
assert!(nizk.verify_batchable(&proof).is_ok(), "nested OR (inner simulated) does not verify");
}
// Inner OR is the branch WITH a witness: only the leaf r3 is simulated.
#[test]
fn nested_or_honest_inner_branch() {
let mut rng = rand::thread_rng();
let (r1, w1) = dleq::<G>(&mut rng);
let (r2, w2) = dleq::<G>(&mut rng);
let (r3, w3) = dleq::<G>(&mut rng);
let inner = ComposedRelation::<G>::or([r1, r2]);
let inner_w = ComposedWitness::or([w1, wrong(w2.len(), &mut rng)]);
let outer = ComposedRelation::or([inner, r3.into()]);
let outer_w = ComposedWitness::or([inner_w, wrong(w3.len(), &mut rng).into()]);
let nizk = outer.into_nizk(b"nested-or");
let proof = nizk.prove_batchable(&outer_w, &mut rng).unwrap();
assert!(nizk.verify_batchable(&proof).is_ok(), "nested OR (inner honest) does not verify");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment