pub mod batcher;
#[allow(clippy::module_inception)]
pub mod circuit;
mod compressed_circuit;
pub mod errors;
pub mod gate;
#[cfg(any(test, feature = "dev"))]
pub mod mock_eval;
pub mod ops;
pub mod preprocessing;
pub mod slice;
pub use circuit::*;
pub use gate::*;
pub use ops::*;
pub use preprocessing::*;
use serde::{Deserialize, Serialize};
pub use slice::*;
use wincode::{SchemaRead, SchemaWrite};
use crate::circuit::errors::ConversionError;
pub type GateIndex = u32;
pub type BatchSize = GateIndex;
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Hash,
Serialize,
Deserialize,
SchemaRead,
SchemaWrite,
PartialOrd,
Ord,
)]
#[repr(C)]
pub enum FieldType {
BaseField,
ScalarField,
Mersenne107,
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Hash,
Serialize,
Deserialize,
SchemaRead,
SchemaWrite,
PartialOrd,
Ord,
)]
#[repr(C)]
pub enum AlgebraicType {
BaseField,
ScalarField,
Point,
Bit,
Mersenne107,
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Hash,
Serialize,
Deserialize,
SchemaRead,
SchemaWrite,
PartialOrd,
Ord,
)]
#[repr(C)]
pub enum ShareOrPlaintext {
Share,
Plaintext,
}
impl From<FieldType> for AlgebraicType {
fn from(field_type: FieldType) -> Self {
match field_type {
FieldType::BaseField => AlgebraicType::BaseField,
FieldType::ScalarField => AlgebraicType::ScalarField,
FieldType::Mersenne107 => AlgebraicType::Mersenne107,
}
}
}
impl TryFrom<AlgebraicType> for FieldType {
type Error = ConversionError;
fn try_from(value: AlgebraicType) -> Result<Self, Self::Error> {
match value {
AlgebraicType::BaseField => Ok(FieldType::BaseField),
AlgebraicType::ScalarField => Ok(FieldType::ScalarField),
AlgebraicType::Point => Err(ConversionError::IntoFieldTypeError(value)),
AlgebraicType::Bit => Err(ConversionError::IntoFieldTypeError(value)),
AlgebraicType::Mersenne107 => Ok(FieldType::Mersenne107),
}
}
}
#[cfg(test)]
mod tests {
use itertools::Itertools;
use primitives::algebra::elliptic_curve::Curve;
use crate::circuit::{AlgebraicType, Circuit, FieldShareBinaryOp, Gate, Input};
pub fn create_add_tree_circuit<C: Curve>(depth: usize) -> Circuit<C> {
let mut circuit = Circuit::<C>::new();
let inputs = (0..(1 << depth))
.map(|_| {
circuit
.add_gate(Gate::Input(Input::SecretPlaintext {
inputer: 0,
algebraic_type: AlgebraicType::Mersenne107,
batch_size: 3,
}))
.unwrap()
})
.collect_vec();
let mut level_gates = inputs;
while level_gates.len() > 1 {
let mut next_level = vec![];
for chunk in level_gates.chunks(2) {
let index = if chunk.len() == 2 {
circuit
.add_gate(Gate::FieldShareBinaryOp {
x: chunk[0],
y: chunk[1],
op: FieldShareBinaryOp::Add,
})
.unwrap()
} else {
assert_eq!(chunk.len(), 1);
chunk[0]
};
next_level.push(index);
}
level_gates = next_level;
}
assert_eq!(level_gates.len(), 1);
circuit.add_output(level_gates[0]).unwrap();
circuit
}
pub fn create_mul_tree_circuit<C: Curve>(depth: usize) -> Circuit<C> {
let mut circuit = Circuit::<C>::new();
let inputs = (0..(1 << depth))
.map(|_| {
circuit
.add_gate(Gate::Input(Input::SecretPlaintext {
inputer: 0,
algebraic_type: AlgebraicType::Mersenne107,
batch_size: 3,
}))
.unwrap()
})
.collect_vec();
let mut level_gates = inputs;
while level_gates.len() > 1 {
let mut next_level = vec![];
for chunk in level_gates.chunks(2) {
let index = if chunk.len() == 2 {
circuit
.add_gate(Gate::FieldShareBinaryOp {
x: chunk[0],
y: chunk[1],
op: FieldShareBinaryOp::Mul,
})
.unwrap()
} else {
assert_eq!(chunk.len(), 1);
chunk[0]
};
next_level.push(index);
}
level_gates = next_level;
}
assert_eq!(level_gates.len(), 1);
circuit.add_output(level_gates[0]).unwrap();
circuit
}
}