Skip to content
Open
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
788 changes: 462 additions & 326 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ cargo run -r --bin dv-snark

Server configuration: 32 core, 480G RAM

| Program | Gates | Cycles | Peak memory | Garbling(s) | Spliting(s) | Single Execution(s) |
|-----------------------------------|---------------------------------------------------------------------------------------|------------------|-------------|-------------|-------------------|---------------------|
| deserialize_compressed_g2_circuit | and variants: 122185357, xor variants: 350864003, not: 550724, total:473600084 | 4268330910 * 68 | 51G | 33s | 480M/(IOPS) = 188 | 178 |
| groth16_verifier_circuit | and variants: 2718558275, xor variants: 7617087185, not: 62381441, total: 10398026901 | | | | |
| dv_snark (use poseidon2) | and variants: 8796030, xor variants: 2365188084, total: 2373984114 | 296796620 * 2374 | 292G | 70s | |
| Program | Gates | Cycles | Peak memory | Garbling(s) | Spliting(s) | Single Execution(s) |
|--------------------------------------------------------|---------------------------------------------------------------------------------------|------------------|-------------|-------------|-------------------|---------------------|
| deserialize_compressed_g2_circuit | and variants: 122185357, xor variants: 350864003, not: 550724, total:473600084 | 4268330910 * 68 | 51G | 33s | 480M/(IOPS) = 188 | 178 |
| groth16_verifier_circuit | and variants: 2718558275, xor variants: 7617087185, not: 62381441, total: 10398026901 | | | | |
| dv_snark with hinted double scalar mul (use poseidon2) | and variants: 6707171, xor variants: 3370130781, total: 3376837952 | 76323964 * 3377 | 374G | 136s | |

Proving efficiency: 300k Poseidon2 hashes/s on a single RTX 4090 card.
43 changes: 22 additions & 21 deletions garbled-snark-verifier/src/circuits/dv_snark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub fn dv_snark_verifier_circuit(witness: &VerifierPayloadRef) -> Circuit {
println!("Compile time: {:?}", start.elapsed());

let start = Instant::now();
let circuit = builder.build(witness.to_bits());
let circuit = builder.build(&witness.to_bits());
println!("build circuit time:{:?}", start.elapsed());

circuit
Expand All @@ -29,55 +29,56 @@ mod test {
fn test_dv_snark_verifier_circuit() {
// Prepare VerifierPayloadRef
let tau = FrRef::from_str(
"490782060457092443021184404188169115419401325819878347174959236155604",
"2730322210350266333305929438402339624225511456370264338590718619370571",
)
.unwrap();
let delta = FrRef::from_str(
"409859792668509615016679153954612494269657711226760893245268993658466",
"1668197219006303135911300995268563595632072044933469744573172589503162",
)
.unwrap();
let epsilon = FrRef::from_str(
"2880039972651592580549544494658966441531834740391411845954153637005104",
"180534986784443382108991383036395393569817197959638310564367496650276",
)
.unwrap();
let commit_p = AffinePointRef {
x: [
130, 16, 132, 245, 115, 118, 110, 233, 235, 58, 5, 190, 187, 230, 138, 225, 149,
231, 32, 45, 41, 29, 94, 89, 248, 158, 54, 19, 86, 0,
243, 1, 124, 124, 28, 184, 224, 34, 217, 222, 182, 31, 42, 252, 194, 222, 40, 36,
80, 223, 106, 184, 193, 142, 55, 102, 25, 112, 7, 0,
],
s: [
93, 74, 178, 168, 173, 38, 101, 88, 181, 49, 78, 207, 89, 78, 130, 42, 242, 245,
88, 5, 253, 250, 54, 182, 177, 249, 82, 57, 147, 0,
229, 76, 122, 168, 191, 162, 130, 195, 248, 229, 89, 69, 135, 106, 178, 161, 172,
29, 249, 224, 109, 160, 41, 54, 63, 164, 235, 10, 145, 1,
],
};
let kzg_k = AffinePointRef {
x: [
36, 69, 122, 22, 89, 79, 186, 56, 138, 8, 183, 193, 186, 98, 21, 62, 9, 143, 173,
24, 89, 195, 126, 73, 241, 118, 71, 103, 223, 0,
240, 171, 68, 224, 177, 62, 73, 178, 215, 175, 231, 231, 151, 89, 104, 111, 7, 40,
91, 33, 151, 83, 118, 199, 88, 68, 165, 164, 151, 1,
],
s: [
12, 122, 106, 168, 104, 248, 117, 18, 171, 218, 85, 138, 31, 80, 250, 230, 176,
136, 74, 129, 137, 78, 181, 48, 88, 180, 21, 139, 39, 1,
182, 120, 142, 188, 144, 198, 242, 204, 84, 254, 121, 254, 72, 190, 109, 99, 198,
59, 168, 17, 124, 224, 37, 14, 69, 114, 133, 198, 2, 1,
],
};
let a0 = FrRef::from_str(
"1858232303623355521215721639157430371979542022979851183514844283900649",
"1132675792798759308127577893315934115126328231089219585842855711650311",
)
.unwrap();
let b0 = FrRef::from_str(
"3045644831070136055562137919853497607898653327126781771795842528553732",
"3028379641311591322528948616897330931030750894712035609973261306086667",
)
.unwrap();

let public_inputs = [
FrRef::from_str("9487159538405616582219466419827834782293111327936747259752845028149")
.unwrap(),
FrRef::from_str("22596372664815072823112258091854569627353949811861389086305200952659")
.unwrap(),
];
let x1 =
(FrRef::from_str("8201062243878067778315015938357284675413750549").unwrap(), false);
let x2 =
(FrRef::from_str("12188555815513519027948129212942953563582264060").unwrap(), true);
let z = (FrRef::from_str("2328416288857173011062977552890912854869626082").unwrap(), true);

let public_inputs = [FrRef::from_str("24").unwrap(), FrRef::from_str("13").unwrap()];

let witness = VerifierPayloadRef {
proof: ProofRef { commit_p, kzg_k, a0, b0 },
proof: ProofRef { commit_p, kzg_k, a0, b0, x1, x2, z },
public_input: PublicInputsRef { public_inputs },
trapdoor: TrapdoorRef { tau, delta, epsilon },
};
Expand Down
9 changes: 4 additions & 5 deletions garbled-snark-verifier/src/circuits/sect233k1/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use std::collections::HashMap;
use std::fmt;
use std::time::Instant;

use crate::circuits::sect233k1::dv_ckt::WITNESS_BIT_LEN;
use rayon::iter::{
IndexedParallelIterator, IntoParallelIterator, IntoParallelRefIterator, ParallelExtend,
ParallelIterator,
Expand Down Expand Up @@ -224,7 +223,7 @@ impl core::ops::Sub for GateCounts {
}

impl CircuitAdapter {
pub(crate) fn build(&self, witness: [bool; WITNESS_BIT_LEN]) -> Circuit {
pub(crate) fn build(&self, witness: &[bool]) -> Circuit {
let n_wires = self.next_wire;
println!("wires: {n_wires}");

Expand All @@ -235,7 +234,7 @@ impl CircuitAdapter {
if i.is_multiple_of(10_000_000) {
println!("wires: {} M", i / 1_000_000);
}
wires.push(new_wirex());
wires.push(new_wirex_with_id(i as u32));
}
println!("init wires took:{:?}", start.elapsed());

Expand Down Expand Up @@ -304,8 +303,8 @@ impl CircuitAdapter {

// The circuit output is assumed to be the last wire.
// Using `expect` for a clearer error message if `wires` is empty.
let output_wire = wires.last().expect("Circuit must have at least one wire").clone();
Circuit::new(vec![output_wire], gates)
// let output_wire = wires.last().expect("Circuit must have at least one wire").clone();
Circuit::new(wires, gates)
}
}

Expand Down
99 changes: 93 additions & 6 deletions garbled-snark-verifier/src/circuits/sect233k1/curve_ckt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,43 @@ pub(crate) fn emit_point_add<T: CircuitTrait>(
CurvePoint { x: p3_x, s: p3_s, z: p3_z, t: p3_t }
}

// Negation of (X, S, Z, T) is (X, S + T, Z, T)
// Ref: https://github.com/blake-pro/c-xs233/blob/c484485fde47c032594368a915c34d2430378458/xsb233.c#L478
pub(crate) fn emit_neg_point_with_neg_selector<T: CircuitTrait>(
bld: &mut T,
p1: &CurvePoint,
neg: usize,
) -> CurvePoint {
let mut r = CurvePoint::identity(bld);
r.x = p1.x;
r.z = p1.z;
r.t = p1.t;
let neg_s = emit_gf_add(bld, &p1.s, &p1.t);
for i in 0..GF_LEN {
let d = bld.xor_wire(p1.s[i], neg_s[i]);
let xd = bld.and_wire(d, neg);
r.s[i] = bld.xor_wire(p1.s[i], xd);
}
r
}
pub(crate) fn emit_neg_point_with_pos_selector<T: CircuitTrait>(
bld: &mut T,
p1: &CurvePoint,
pos: usize,
) -> CurvePoint {
let mut r = CurvePoint::identity(bld);
r.x = p1.x;
r.z = p1.z;
r.t = p1.t;
let neg_s = emit_gf_add(bld, &p1.s, &p1.t);
for i in 0..GF_LEN {
let d = bld.xor_wire(p1.s[i], neg_s[i]);
let xd = bld.and_wire(d, pos);
r.s[i] = bld.xor_wire(neg_s[i], xd);
}
r
}

/// Apply the Frobenius endomorphism on a point (i.e. square all coordinates).
///
/// Squares all coordinates of a xsk233 curve point.
Expand Down Expand Up @@ -295,21 +332,18 @@ pub(crate) fn template_emit_point_add() -> Template {
mod test {
use std::{str::FromStr, time::Instant};

use crate::circuits::sect233k1::{
builder::CircuitTrait,
gf_ref::bits_to_gfref,
};
use crate::circuits::sect233k1::{builder::CircuitTrait, gf_ref::bits_to_gfref};
use num_bigint::{BigUint, RandomBits};
use rand::Rng;

use super::{CurvePoint, emit_point_add};
use crate::circuits::sect233k1::curve_ref::CurvePointRef;
use crate::circuits::sect233k1::{
builder::CircuitAdapter,
curve_ref::{CurvePointRef as InnerPointRef, point_add as ref_point_add},
gf_ref::{gfref_mul, gfref_to_bits},
};

use super::{CurvePoint, emit_point_add};

// Creates a random point ensuring T = X*Z
fn random_point() -> InnerPointRef {
let mut rng = rand::thread_rng();
Expand Down Expand Up @@ -377,4 +411,57 @@ mod test {
let c_ptadd_val = InnerPointRef { x: c_ptadd_x, s: c_ptadd_s, z: c_ptadd_z, t: c_ptadd_t };
assert_eq!(c_ptadd_val, ptadd);
}

#[test]
fn test_negative_point_with_neg_selector() {
let p1 = InnerPointRef {
x: BigUint::from_str(
"13283792768796718556929275469989697816663440403339868882741001477299174",
)
.unwrap(),
s: BigUint::from_str(
"6416386389908495168242210184454780244589215014363767030073322872085145",
)
.unwrap(),
z: BigUint::from_str("1").unwrap(),
t: BigUint::from_str(
"13283792768796718556929275469989697816663440403339868882741001477299174",
)
.unwrap(),
};
let p1_double = ref_point_add(&p1, &p1);
let identity = CurvePointRef::identity();

let mut rng = rand::thread_rng();
let neg_witness = rng.gen_bool(0.5);
println!("neg_witness: {:?}", neg_witness);

let mut bld = CircuitAdapter::default();
let c_p1 = CurvePoint { x: bld.fresh(), s: bld.fresh(), z: bld.fresh(), t: bld.fresh() };
let neg = bld.fresh_one();

let c_neg_p1 = super::emit_neg_point_with_neg_selector(&mut bld, &c_p1, neg);
println!("number of neg gates: {:?}", bld.gate_counts());
let sum = super::emit_point_add(&mut bld, &c_p1, &c_neg_p1);

let mut witness = Vec::<bool>::with_capacity(233 * 4 + 1);
witness.extend(gfref_to_bits(&p1.x));
witness.extend(gfref_to_bits(&p1.s));
witness.extend(gfref_to_bits(&p1.z));
witness.extend(gfref_to_bits(&p1.t));
witness.push(neg_witness);
let wires = bld.eval_gates(&witness);

let c_ptadd_x = bits_to_gfref(&sum.x.map(|w_id| wires[w_id]));
let c_ptadd_s = bits_to_gfref(&sum.s.map(|w_id| wires[w_id]));
let c_ptadd_z = bits_to_gfref(&sum.z.map(|w_id| wires[w_id]));
let c_ptadd_t = bits_to_gfref(&sum.t.map(|w_id| wires[w_id]));

let c_ptadd_val = InnerPointRef { x: c_ptadd_x, s: c_ptadd_s, z: c_ptadd_z, t: c_ptadd_t };
if neg_witness {
assert_eq!(c_ptadd_val, identity);
} else {
assert_eq!(c_ptadd_val, p1_double);
}
}
}
10 changes: 10 additions & 0 deletions garbled-snark-verifier/src/circuits/sect233k1/curve_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,16 @@ pub(crate) fn point_add(p1: &CurvePointRef, p2: &CurvePointRef) -> CurvePointRef
p3
}

// Negation of (X, S, Z, T) is (X, S + T, Z, T)
pub(crate) fn neg_point(p: &CurvePointRef) -> CurvePointRef {
let mut np = CurvePointRef::new();
np.x = p.x.clone();
np.s = gfref_add(&p.s, &p.t);
np.z = p.z.clone();
np.t = p.t.clone();
np
}

/// Apply the Frobenius endomorphism on a point (i.e. square all coordinates).
///
/// Squares all coordinates of a xsk233 curve point.
Expand Down
Loading