confium_tc_fhe_bfv/
lib.rs1#![forbid(unsafe_code)]
13#![allow(missing_docs)] use serde::{Deserialize, Serialize};
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct BfvParams {
20 pub polynomial_degree: usize,
22 pub plaintext_modulus: u64,
24 pub coefficient_modulus: Vec<u64>,
26 pub security_level: u32,
28}
29
30impl BfvParams {
31 pub fn recommended_128() -> Self {
33 Self {
34 polynomial_degree: 4096,
35 plaintext_modulus: 65537,
36 coefficient_modulus: vec![0xFFFFFFFFFFFFFFF7u64],
37 security_level: 128,
38 }
39 }
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct BfvPublicKey {
45 pub params: BfvParams,
47 pub bytes: Vec<u8>,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct BfvSecretKeyShare {
54 pub party_index: u32,
56 pub bytes: Vec<u8>,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct BfvCiphertext {
63 pub c1: Vec<u8>,
65 pub c2: Vec<u8>,
67}
68
69#[derive(Debug, thiserror::Error)]
71pub enum BfvError {
72 #[error("parameters incompatible: {0}")]
74 IncompatibleParams(String),
75 #[error("threshold not met: have {have}, need {need}")]
77 ThresholdNotMet {
78 have: usize,
80 need: u32,
82 },
83 #[error("threshold BFV is research-only (P3): {0}")]
85 ResearchOnly(String),
86}
87
88pub fn validate_params(params: &BfvParams) -> Result<(), BfvError> {
90 if params.polynomial_degree < 1024 {
91 return Err(BfvError::IncompatibleParams(format!(
92 "polynomial_degree too small: {}",
93 params.polynomial_degree
94 )));
95 }
96 if !params.polynomial_degree.is_power_of_two() {
97 return Err(BfvError::IncompatibleParams(format!(
98 "polynomial_degree must be power of two: {}",
99 params.polynomial_degree
100 )));
101 }
102 if params.security_level < 128 {
103 return Err(BfvError::IncompatibleParams(format!(
104 "security_level below 128: {}",
105 params.security_level
106 )));
107 }
108 Ok(())
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn recommended_params_validate() {
117 let params = BfvParams::recommended_128();
118 validate_params(¶ms).unwrap();
119 }
120
121 #[test]
122 fn non_power_of_two_rejected() {
123 let params = BfvParams {
124 polynomial_degree: 5000, ..BfvParams::recommended_128()
126 };
127 let result = validate_params(¶ms);
128 assert!(matches!(result, Err(BfvError::IncompatibleParams(_))));
129 }
130
131 #[test]
132 fn low_security_rejected() {
133 let params = BfvParams {
134 security_level: 64,
135 ..BfvParams::recommended_128()
136 };
137 let result = validate_params(¶ms);
138 assert!(matches!(result, Err(BfvError::IncompatibleParams(_))));
139 }
140}