diff --git a/crates/mpz-core/src/ggm_tree.rs b/crates/mpz-core/src/ggm_tree.rs index 913fffb6..840efcc6 100644 --- a/crates/mpz-core/src/ggm_tree.rs +++ b/crates/mpz-core/src/ggm_tree.rs @@ -32,33 +32,35 @@ impl GgmTree { assert_eq!(k0.len(), self.depth); assert_eq!(k1.len(), self.depth); let mut buf = [Block::ZERO; 8]; - self.tkprp.expand_1to2(tree, seed); - k0[0] = tree[0]; - k1[0] = tree[1]; + if self.depth > 1 { + self.tkprp.expand_1to2(tree, seed); + k0[0] = tree[0]; + k1[0] = tree[1]; - self.tkprp.expand_2to4(&mut buf, tree); - k0[1] = buf[0] ^ buf[2]; - k1[1] = buf[1] ^ buf[3]; - tree[0..4].copy_from_slice(&buf[0..4]); - - for h in 2..self.depth { - k0[h] = Block::ZERO; - k1[h] = Block::ZERO; - - // How many nodes there are in this layer - let sz = 1 << h; - for i in (0..=sz - 4).rev().step_by(4) { - self.tkprp.expand_4to8(&mut buf, &tree[i..]); - k0[h] ^= buf[0]; - k0[h] ^= buf[2]; - k0[h] ^= buf[4]; - k0[h] ^= buf[6]; - k1[h] ^= buf[1]; - k1[h] ^= buf[3]; - k1[h] ^= buf[5]; - k1[h] ^= buf[7]; + self.tkprp.expand_2to4(&mut buf, tree); + k0[1] = buf[0] ^ buf[2]; + k1[1] = buf[1] ^ buf[3]; + tree[0..4].copy_from_slice(&buf[0..4]); - tree[2 * i..2 * i + 8].copy_from_slice(&buf); + for h in 2..self.depth { + k0[h] = Block::ZERO; + k1[h] = Block::ZERO; + + // How many nodes there are in this layer + let sz = 1 << h; + for i in (0..=sz - 4).rev().step_by(4) { + self.tkprp.expand_4to8(&mut buf, &tree[i..]); + k0[h] ^= buf[0]; + k0[h] ^= buf[2]; + k0[h] ^= buf[4]; + k0[h] ^= buf[6]; + k1[h] ^= buf[1]; + k1[h] ^= buf[3]; + k1[h] ^= buf[5]; + k1[h] ^= buf[7]; + + tree[2 * i..2 * i + 8].copy_from_slice(&buf); + } } } } diff --git a/crates/mpz-core/src/lpn.rs b/crates/mpz-core/src/lpn.rs index 2543fdb2..26d44a07 100644 --- a/crates/mpz-core/src/lpn.rs +++ b/crates/mpz-core/src/lpn.rs @@ -113,7 +113,7 @@ impl LpnEncoder { } /// Lpn paramters -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Default)] pub struct LpnParameters { /// The length of output vecotrs. pub n: usize, diff --git a/crates/mpz-garble-core/benches/garble.rs b/crates/mpz-garble-core/benches/garble.rs index 143b0adb..c720bf01 100644 --- a/crates/mpz-garble-core/benches/garble.rs +++ b/crates/mpz-garble-core/benches/garble.rs @@ -1,83 +1,39 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use mpz_circuits::circuits::AES128; -use mpz_garble_core::{ChaChaEncoder, Encoder, Evaluator, Generator}; +use mpz_garble_core::{ChaChaEncoder, Encoder, Generator}; fn criterion_benchmark(c: &mut Criterion) { - let mut gb_group = c.benchmark_group("garble"); + let mut group = c.benchmark_group("garble_circuits"); let encoder = ChaChaEncoder::new([0u8; 32]); - let full_inputs = AES128 + let inputs = AES128 .inputs() .iter() .map(|value| encoder.encode_by_type(0, &value.value_type())) .collect::>(); - - let active_inputs = vec![ - full_inputs[0].clone().select([0u8; 16]).unwrap(), - full_inputs[1].clone().select([0u8; 16]).unwrap(), - ]; - - gb_group.bench_function("aes128", |b| { - let mut gen = Generator::default(); - b.iter(|| { - let mut gen_iter = gen - .generate(&AES128, encoder.delta(), full_inputs.clone()) - .unwrap(); - - let _: Vec<_> = gen_iter.by_ref().collect(); - - black_box(gen_iter.finish().unwrap()) - }) - }); - - gb_group.bench_function("aes128_batched", |b| { - let mut gen = Generator::default(); - b.iter(|| { - let mut gen_iter = gen - .generate_batched(&AES128, encoder.delta(), full_inputs.clone()) - .unwrap(); - - let _: Vec<_> = gen_iter.by_ref().collect(); - - black_box(gen_iter.finish().unwrap()) - }) - }); - - gb_group.bench_function("aes128_with_hash", |b| { - let mut gen = Generator::default(); + group.bench_function("aes128", |b| { b.iter(|| { - let mut gen_iter = gen - .generate(&AES128, encoder.delta(), full_inputs.clone()) - .unwrap(); - - gen_iter.enable_hasher(); + let mut gen = Generator::new(AES128.clone(), encoder.delta(), &inputs).unwrap(); - let _: Vec<_> = gen_iter.by_ref().collect(); + let mut enc_gates = Vec::with_capacity(AES128.and_count()); + for gate in gen.by_ref() { + enc_gates.push(gate); + } - black_box(gen_iter.finish().unwrap()) + black_box(gen.outputs().unwrap()) }) }); - - drop(gb_group); - - let mut ev_group = c.benchmark_group("evaluate"); - - ev_group.bench_function("aes128", |b| { - let mut gen = Generator::default(); - let mut gen_iter = gen - .generate(&AES128, encoder.delta(), full_inputs.clone()) - .unwrap(); - let gates: Vec<_> = gen_iter.by_ref().collect(); - - let mut ev = Evaluator::default(); + group.bench_function("aes128_with_hash", |b| { b.iter(|| { - let mut ev_consumer = ev.evaluate(&AES128, active_inputs.clone()).unwrap(); + let mut gen = + Generator::new_with_hasher(AES128.clone(), encoder.delta(), &inputs).unwrap(); - for gate in &gates { - ev_consumer.next(*gate); + let mut enc_gates = Vec::with_capacity(AES128.and_count()); + for gate in gen.by_ref() { + enc_gates.push(gate); } - black_box(ev_consumer.finish().unwrap()); + black_box(gen.outputs().unwrap()) }) }); } diff --git a/crates/mpz-garble-core/src/evaluator.rs b/crates/mpz-garble-core/src/evaluator.rs index f503ef0e..5f28b0b9 100644 --- a/crates/mpz-garble-core/src/evaluator.rs +++ b/crates/mpz-garble-core/src/evaluator.rs @@ -1,16 +1,12 @@ -use core::fmt; +use std::sync::Arc; use blake3::Hasher; use crate::{ circuit::EncryptedGate, encoding::{state, EncodedValue, Label}, - EncryptedGateBatch, DEFAULT_BATCH_SIZE, -}; -use mpz_circuits::{ - types::{BinaryRepr, TypeError}, - Circuit, CircuitError, Gate, }; +use mpz_circuits::{types::TypeError, Circuit, CircuitError, Gate}; use mpz_core::{ aes::{FixedKeyAes, FIXED_KEY_AES}, hash::Hash, @@ -58,34 +54,57 @@ pub(crate) fn and_gate( Label::new(w_g ^ w_e) } -/// Output of the evaluator. -#[derive(Debug)] -pub struct EvaluatorOutput { - /// Encoded outputs of the circuit. - pub outputs: Vec>, - /// Hash of the encrypted gates. - pub hash: Option, -} - -/// Garbled circuit evaluator. -#[derive(Debug, Default)] +/// Core evaluator type for evaluating a garbled circuit. pub struct Evaluator { - /// Buffer for the active labels. - buffer: Vec