Enables external circuits to be called
Jean-Philippe Bossuat jeanphilippe.bossuat@gmail.com
Fri, 31 Oct 2025 09:59:08 +0100
12 files changed,
66 insertions(+),
116 deletions(-)
jump to
M
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/add_codegen.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/add_codegen.rs
@@ -1,4 +1,4 @@
-use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitInfo, Circuit, GetBitCircuitInfo, Node}; +use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitFamily, BitCircuitInfo, Circuit, Node}; pub(crate) enum AnyBitCircuit { B0(BitCircuit<4>), B1(BitCircuit<8>),@@ -72,16 +72,9 @@ }
} } -impl GetBitCircuitInfo<u32> for Circuit<AnyBitCircuit, 32usize> { - fn input_size(&self) -> usize { - 2 * u32::BITS as usize - } - fn output_size(&self) -> usize { - u32::BITS as usize - } - fn get_circuit(&self, bit: usize) -> (&[Node], usize) { - self.0[bit].info() - } +impl BitCircuitFamily for AnyBitCircuit { + const INPUT_BITS: usize = 64; + const OUTPUT_BITS: usize = 32; } pub(crate) static OUTPUT_CIRCUITS: Circuit<AnyBitCircuit, 32usize> = Circuit([
M
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/and_codegen.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/and_codegen.rs
@@ -1,4 +1,4 @@
-use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitInfo, Circuit, GetBitCircuitInfo, Node}; +use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitFamily, BitCircuitInfo, Circuit, Node}; pub(crate) enum AnyBitCircuit { B0(BitCircuit<4>), B1(BitCircuit<4>),@@ -72,16 +72,9 @@ }
} } -impl GetBitCircuitInfo<u32> for Circuit<AnyBitCircuit, 32usize> { - fn input_size(&self) -> usize { - 2 * u32::BITS as usize - } - fn output_size(&self) -> usize { - u32::BITS as usize - } - fn get_circuit(&self, bit: usize) -> (&[Node], usize) { - self.0[bit].info() - } +impl BitCircuitFamily for AnyBitCircuit { + const INPUT_BITS: usize = 64; + const OUTPUT_BITS: usize = 32; } pub(crate) static OUTPUT_CIRCUITS: Circuit<AnyBitCircuit, 32usize> = Circuit([
M
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/or_codegen.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/or_codegen.rs
@@ -1,4 +1,4 @@
-use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitInfo, Circuit, GetBitCircuitInfo, Node}; +use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitFamily, BitCircuitInfo, Circuit, Node}; pub(crate) enum AnyBitCircuit { B0(BitCircuit<4>), B1(BitCircuit<4>),@@ -72,16 +72,9 @@ }
} } -impl GetBitCircuitInfo<u32> for Circuit<AnyBitCircuit, 32usize> { - fn input_size(&self) -> usize { - 2 * u32::BITS as usize - } - fn output_size(&self) -> usize { - u32::BITS as usize - } - fn get_circuit(&self, bit: usize) -> (&[Node], usize) { - self.0[bit].info() - } +impl BitCircuitFamily for AnyBitCircuit { + const INPUT_BITS: usize = 64; + const OUTPUT_BITS: usize = 32; } pub(crate) static OUTPUT_CIRCUITS: Circuit<AnyBitCircuit, 32usize> = Circuit([
M
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/sll_codegen.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/sll_codegen.rs
@@ -1,4 +1,4 @@
-use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitInfo, Circuit, GetBitCircuitInfo, Node}; +use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitFamily, BitCircuitInfo, Circuit, Node}; pub(crate) enum AnyBitCircuit { B0(BitCircuit<12>), B1(BitCircuit<18>),@@ -72,16 +72,9 @@ }
} } -impl GetBitCircuitInfo<u32> for Circuit<AnyBitCircuit, 32usize> { - fn input_size(&self) -> usize { - 2 * u32::BITS as usize - } - fn output_size(&self) -> usize { - u32::BITS as usize - } - fn get_circuit(&self, bit: usize) -> (&[Node], usize) { - self.0[bit].info() - } +impl BitCircuitFamily for AnyBitCircuit { + const INPUT_BITS: usize = 37; + const OUTPUT_BITS: usize = 32; } pub(crate) static OUTPUT_CIRCUITS: Circuit<AnyBitCircuit, 32usize> = Circuit([
M
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/slt_codegen.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/slt_codegen.rs
@@ -1,4 +1,4 @@
-use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitInfo, Circuit, GetBitCircuitInfo, Node}; +use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitFamily, BitCircuitInfo, Circuit, Node}; pub(crate) enum AnyBitCircuit { B0(BitCircuit<256>), }@@ -10,16 +10,9 @@ }
} } -impl GetBitCircuitInfo<u32> for Circuit<AnyBitCircuit, 1usize> { - fn input_size(&self) -> usize { - 2 * u32::BITS as usize - } - fn output_size(&self) -> usize { - 1 - } - fn get_circuit(&self, bit: usize) -> (&[Node], usize) { - self.0[bit].info() - } +impl BitCircuitFamily for AnyBitCircuit { + const INPUT_BITS: usize = 64; + const OUTPUT_BITS: usize = 1; } pub(crate) static OUTPUT_CIRCUITS: Circuit<AnyBitCircuit, 1usize> = Circuit([AnyBitCircuit::B0(BitCircuit::new(
M
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/sltu_codegen.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/sltu_codegen.rs
@@ -1,4 +1,4 @@
-use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitInfo, Circuit, GetBitCircuitInfo, Node}; +use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitFamily, BitCircuitInfo, Circuit, Node}; pub(crate) enum AnyBitCircuit { B0(BitCircuit<256>), }@@ -10,16 +10,9 @@ }
} } -impl GetBitCircuitInfo<u32> for Circuit<AnyBitCircuit, 1usize> { - fn input_size(&self) -> usize { - 2 * u32::BITS as usize - } - fn output_size(&self) -> usize { - 1 - } - fn get_circuit(&self, bit: usize) -> (&[Node], usize) { - self.0[bit].info() - } +impl BitCircuitFamily for AnyBitCircuit { + const INPUT_BITS: usize = 64; + const OUTPUT_BITS: usize = 1; } pub(crate) static OUTPUT_CIRCUITS: Circuit<AnyBitCircuit, 1usize> = Circuit([AnyBitCircuit::B0(BitCircuit::new(
M
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/sra_codegen.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/sra_codegen.rs
@@ -1,4 +1,4 @@
-use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitInfo, Circuit, GetBitCircuitInfo, Node}; +use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitFamily, BitCircuitInfo, Circuit, Node}; pub(crate) enum AnyBitCircuit { B0(BitCircuit<192>), B1(BitCircuit<186>),@@ -72,16 +72,9 @@ }
} } -impl GetBitCircuitInfo<u32> for Circuit<AnyBitCircuit, 32usize> { - fn input_size(&self) -> usize { - 2 * u32::BITS as usize - } - fn output_size(&self) -> usize { - u32::BITS as usize - } - fn get_circuit(&self, bit: usize) -> (&[Node], usize) { - self.0[bit].info() - } +impl BitCircuitFamily for AnyBitCircuit { + const INPUT_BITS: usize = 37; + const OUTPUT_BITS: usize = 32; } pub(crate) static OUTPUT_CIRCUITS: Circuit<AnyBitCircuit, 32usize> = Circuit([
M
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/srl_codegen.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/srl_codegen.rs
@@ -1,4 +1,4 @@
-use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitInfo, Circuit, GetBitCircuitInfo, Node}; +use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitFamily, BitCircuitInfo, Circuit, Node}; pub(crate) enum AnyBitCircuit { B0(BitCircuit<192>), B1(BitCircuit<192>),@@ -72,16 +72,9 @@ }
} } -impl GetBitCircuitInfo<u32> for Circuit<AnyBitCircuit, 32usize> { - fn input_size(&self) -> usize { - 2 * u32::BITS as usize - } - fn output_size(&self) -> usize { - u32::BITS as usize - } - fn get_circuit(&self, bit: usize) -> (&[Node], usize) { - self.0[bit].info() - } +impl BitCircuitFamily for AnyBitCircuit { + const INPUT_BITS: usize = 37; + const OUTPUT_BITS: usize = 32; } pub(crate) static OUTPUT_CIRCUITS: Circuit<AnyBitCircuit, 32usize> = Circuit([
M
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/sub_codegen.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/sub_codegen.rs
@@ -1,4 +1,4 @@
-use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitInfo, Circuit, GetBitCircuitInfo, Node}; +use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitFamily, BitCircuitInfo, Circuit, Node}; pub(crate) enum AnyBitCircuit { B0(BitCircuit<4>), B1(BitCircuit<8>),@@ -72,16 +72,9 @@ }
} } -impl GetBitCircuitInfo<u32> for Circuit<AnyBitCircuit, 32usize> { - fn input_size(&self) -> usize { - 2 * u32::BITS as usize - } - fn output_size(&self) -> usize { - u32::BITS as usize - } - fn get_circuit(&self, bit: usize) -> (&[Node], usize) { - self.0[bit].info() - } +impl BitCircuitFamily for AnyBitCircuit { + const INPUT_BITS: usize = 64; + const OUTPUT_BITS: usize = 32; } pub(crate) static OUTPUT_CIRCUITS: Circuit<AnyBitCircuit, 32usize> = Circuit([
M
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/xor_codegen.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/circuits/u32/xor_codegen.rs
@@ -1,4 +1,4 @@
-use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitInfo, Circuit, GetBitCircuitInfo, Node}; +use crate::tfhe::bdd_arithmetic::{BitCircuit, BitCircuitFamily, BitCircuitInfo, Circuit, Node}; pub(crate) enum AnyBitCircuit { B0(BitCircuit<4>), B1(BitCircuit<4>),@@ -72,16 +72,9 @@ }
} } -impl GetBitCircuitInfo<u32> for Circuit<AnyBitCircuit, 32usize> { - fn input_size(&self) -> usize { - 2 * u32::BITS as usize - } - fn output_size(&self) -> usize { - u32::BITS as usize - } - fn get_circuit(&self, bit: usize) -> (&[Node], usize) { - self.0[bit].info() - } +impl BitCircuitFamily for AnyBitCircuit { + const INPUT_BITS: usize = 64; + const OUTPUT_BITS: usize = 32; } pub(crate) static OUTPUT_CIRCUITS: Circuit<AnyBitCircuit, 32usize> = Circuit([
M
poulpy-schemes/src/tfhe/bdd_arithmetic/eval.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/eval.rs
@@ -19,13 +19,33 @@ fn output_size(&self) -> usize;
fn get_circuit(&self, bit: usize) -> (&[Node], usize); } -pub(crate) struct BitCircuit<const N: usize> { - pub(crate) nodes: [Node; N], - pub(crate) max_inter_state: usize, +pub struct BitCircuit<const N: usize> { + pub nodes: [Node; N], + pub max_inter_state: usize, +} + +pub trait BitCircuitFamily { + const INPUT_BITS: usize; + const OUTPUT_BITS: usize; } pub struct Circuit<C: BitCircuitInfo, const N: usize>(pub [C; N]); +impl<C, T: UnsignedInteger, const N: usize> GetBitCircuitInfo<T> for Circuit<C, N> +where + C: BitCircuitInfo + BitCircuitFamily, +{ + fn input_size(&self) -> usize { + C::INPUT_BITS + } + fn output_size(&self) -> usize { + C::OUTPUT_BITS + } + fn get_circuit(&self, bit: usize) -> (&[Node], usize) { + self.0[bit].info() + } +} + pub trait ExecuteBDDCircuit<T: UnsignedInteger, BE: Backend> { fn execute_bdd_circuit<C, G, O>(&self, out: &mut [GLWE<O>], inputs: &G, circuit: &C, scratch: &mut Scratch<BE>) where@@ -51,7 +71,7 @@ O: DataMut,
{ #[cfg(debug_assertions)] { - assert_eq!(inputs.bit_size(), circuit.input_size()); + assert!(inputs.bit_size() >= circuit.input_size()); assert!(out.len() >= circuit.output_size()); }@@ -119,7 +139,7 @@ }
} impl<const N: usize> BitCircuit<N> { - pub(crate) const fn new(nodes: [Node; N], max_inter_state: usize) -> Self { + pub const fn new(nodes: [Node; N], max_inter_state: usize) -> Self { Self { nodes, max_inter_state,
M
poulpy-schemes/src/tfhe/bdd_arithmetic/mod.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/mod.rs
@@ -9,7 +9,7 @@ pub use bdd_2w_to_1w::*;
pub use blind_rotation::*; pub use ciphertexts::*; pub(crate) use circuits::*; -pub(crate) use eval::*; +pub use eval::*; pub use key::*; pub mod tests;