1use crate::error::{Result, SdkError};
8
9#[cfg(feature = "fhe")]
10use crate::fhe::FheKeys;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum FheValueKind {
15 Bool,
16 U8,
17 U16,
18 U32,
19 U64,
20}
21
22impl std::fmt::Display for FheValueKind {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 match self {
25 FheValueKind::Bool => write!(f, "Bool"),
26 FheValueKind::U8 => write!(f, "U8"),
27 FheValueKind::U16 => write!(f, "U16"),
28 FheValueKind::U32 => write!(f, "U32"),
29 FheValueKind::U64 => write!(f, "U64"),
30 }
31 }
32}
33
34#[cfg(feature = "fhe")]
36enum FheValueInner {
37 Bool(tfhe::FheBool),
38 U8(tfhe::FheUint8),
39 U16(tfhe::FheUint16),
40 U32(tfhe::FheUint32),
41 U64(tfhe::FheUint64),
42}
43
44pub struct FheValue {
55 #[cfg(feature = "fhe")]
56 inner: FheValueInner,
57 #[cfg(not(feature = "fhe"))]
58 _placeholder: (),
59}
60
61impl FheValue {
62 pub fn kind(&self) -> FheValueKind {
64 #[cfg(feature = "fhe")]
65 {
66 match &self.inner {
67 FheValueInner::Bool(_) => FheValueKind::Bool,
68 FheValueInner::U8(_) => FheValueKind::U8,
69 FheValueInner::U16(_) => FheValueKind::U16,
70 FheValueInner::U32(_) => FheValueKind::U32,
71 FheValueInner::U64(_) => FheValueKind::U64,
72 }
73 }
74 #[cfg(not(feature = "fhe"))]
75 {
76 FheValueKind::Bool
77 }
78 }
79}
80
81#[cfg(not(feature = "fhe"))]
82impl FheValue {
83 pub fn encrypt_bool(_val: bool, _keys: &crate::fhe::FheKeys) -> Result<Self> {
85 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
86 }
87
88 pub fn encrypt_u8(_val: u8, _keys: &crate::fhe::FheKeys) -> Result<Self> {
90 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
91 }
92
93 pub fn encrypt_u16(_val: u16, _keys: &crate::fhe::FheKeys) -> Result<Self> {
95 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
96 }
97
98 pub fn encrypt_u32(_val: u32, _keys: &crate::fhe::FheKeys) -> Result<Self> {
100 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
101 }
102
103 pub fn encrypt_u64(_val: u64, _keys: &crate::fhe::FheKeys) -> Result<Self> {
105 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
106 }
107
108 pub fn add(&self, _other: &Self) -> Result<Self> {
110 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
111 }
112
113 pub fn sub(&self, _other: &Self) -> Result<Self> {
115 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
116 }
117
118 pub fn mul(&self, _other: &Self) -> Result<Self> {
120 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
121 }
122
123 pub fn eq(&self, _other: &Self) -> Result<Self> {
125 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
126 }
127
128 pub fn ne(&self, _other: &Self) -> Result<Self> {
130 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
131 }
132
133 pub fn lt(&self, _other: &Self) -> Result<Self> {
135 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
136 }
137
138 pub fn le(&self, _other: &Self) -> Result<Self> {
140 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
141 }
142
143 pub fn gt(&self, _other: &Self) -> Result<Self> {
145 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
146 }
147
148 pub fn ge(&self, _other: &Self) -> Result<Self> {
150 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
151 }
152
153 pub fn and(&self, _other: &Self) -> Result<Self> {
155 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
156 }
157
158 pub fn or(&self, _other: &Self) -> Result<Self> {
160 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
161 }
162
163 pub fn xor(&self, _other: &Self) -> Result<Self> {
165 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
166 }
167
168 pub fn not(&self) -> Result<Self> {
170 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
171 }
172
173 pub fn decrypt_bool(&self, _keys: &crate::fhe::FheKeys) -> Result<bool> {
175 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
176 }
177
178 pub fn decrypt_u8(&self, _keys: &crate::fhe::FheKeys) -> Result<u8> {
180 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
181 }
182
183 pub fn decrypt_u16(&self, _keys: &crate::fhe::FheKeys) -> Result<u16> {
185 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
186 }
187
188 pub fn decrypt_u32(&self, _keys: &crate::fhe::FheKeys) -> Result<u32> {
190 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
191 }
192
193 pub fn decrypt_u64(&self, _keys: &crate::fhe::FheKeys) -> Result<u64> {
195 Err(SdkError::Fhe("fhe feature not enabled".to_string()))
196 }
197}
198
199#[cfg(feature = "fhe")]
200impl FheValue {
201 pub fn encrypt_bool(val: bool, keys: &FheKeys) -> Result<Self> {
203 use tfhe::prelude::FheEncrypt;
204 let encrypted = tfhe::FheBool::encrypt(val, keys.client_key());
205 Ok(Self {
206 inner: FheValueInner::Bool(encrypted),
207 })
208 }
209
210 pub fn encrypt_u8(val: u8, keys: &FheKeys) -> Result<Self> {
212 use tfhe::prelude::FheEncrypt;
213 let encrypted = tfhe::FheUint8::encrypt(val, keys.client_key());
214 Ok(Self {
215 inner: FheValueInner::U8(encrypted),
216 })
217 }
218
219 pub fn encrypt_u16(val: u16, keys: &FheKeys) -> Result<Self> {
221 use tfhe::prelude::FheEncrypt;
222 let encrypted = tfhe::FheUint16::encrypt(val, keys.client_key());
223 Ok(Self {
224 inner: FheValueInner::U16(encrypted),
225 })
226 }
227
228 pub fn encrypt_u32(val: u32, keys: &FheKeys) -> Result<Self> {
230 use tfhe::prelude::FheEncrypt;
231 let encrypted = tfhe::FheUint32::encrypt(val, keys.client_key());
232 Ok(Self {
233 inner: FheValueInner::U32(encrypted),
234 })
235 }
236
237 pub fn encrypt_u64(val: u64, keys: &FheKeys) -> Result<Self> {
239 use tfhe::prelude::FheEncrypt;
240 let encrypted = tfhe::FheUint64::encrypt(val, keys.client_key());
241 Ok(Self {
242 inner: FheValueInner::U64(encrypted),
243 })
244 }
245
246 pub fn decrypt_bool(&self, keys: &FheKeys) -> Result<bool> {
248 use tfhe::prelude::FheDecrypt;
249 match &self.inner {
250 FheValueInner::Bool(v) => Ok(v.decrypt(keys.client_key())),
251 _ => Err(SdkError::Fhe(format!(
252 "type mismatch: expected Bool, got {}",
253 self.kind()
254 ))),
255 }
256 }
257
258 pub fn decrypt_u8(&self, keys: &FheKeys) -> Result<u8> {
260 use tfhe::prelude::FheDecrypt;
261 match &self.inner {
262 FheValueInner::U8(v) => Ok(v.decrypt(keys.client_key())),
263 _ => Err(SdkError::Fhe(format!(
264 "type mismatch: expected U8, got {}",
265 self.kind()
266 ))),
267 }
268 }
269
270 pub fn decrypt_u16(&self, keys: &FheKeys) -> Result<u16> {
272 use tfhe::prelude::FheDecrypt;
273 match &self.inner {
274 FheValueInner::U16(v) => Ok(v.decrypt(keys.client_key())),
275 _ => Err(SdkError::Fhe(format!(
276 "type mismatch: expected U16, got {}",
277 self.kind()
278 ))),
279 }
280 }
281
282 pub fn decrypt_u32(&self, keys: &FheKeys) -> Result<u32> {
284 use tfhe::prelude::FheDecrypt;
285 match &self.inner {
286 FheValueInner::U32(v) => Ok(v.decrypt(keys.client_key())),
287 _ => Err(SdkError::Fhe(format!(
288 "type mismatch: expected U32, got {}",
289 self.kind()
290 ))),
291 }
292 }
293
294 pub fn decrypt_u64(&self, keys: &FheKeys) -> Result<u64> {
296 use tfhe::prelude::FheDecrypt;
297 match &self.inner {
298 FheValueInner::U64(v) => Ok(v.decrypt(keys.client_key())),
299 _ => Err(SdkError::Fhe(format!(
300 "type mismatch: expected U64, got {}",
301 self.kind()
302 ))),
303 }
304 }
305
306 pub fn add(&self, other: &Self) -> Result<Self> {
308 match (&self.inner, &other.inner) {
309 (FheValueInner::U8(a), FheValueInner::U8(b)) => Ok(Self {
310 inner: FheValueInner::U8(a + b),
311 }),
312 (FheValueInner::U16(a), FheValueInner::U16(b)) => Ok(Self {
313 inner: FheValueInner::U16(a + b),
314 }),
315 (FheValueInner::U32(a), FheValueInner::U32(b)) => Ok(Self {
316 inner: FheValueInner::U32(a + b),
317 }),
318 (FheValueInner::U64(a), FheValueInner::U64(b)) => Ok(Self {
319 inner: FheValueInner::U64(a + b),
320 }),
321 _ => Err(SdkError::Fhe(format!(
322 "type mismatch in add: {} vs {}",
323 self.kind(),
324 other.kind()
325 ))),
326 }
327 }
328
329 pub fn sub(&self, other: &Self) -> Result<Self> {
331 match (&self.inner, &other.inner) {
332 (FheValueInner::U8(a), FheValueInner::U8(b)) => Ok(Self {
333 inner: FheValueInner::U8(a - b),
334 }),
335 (FheValueInner::U16(a), FheValueInner::U16(b)) => Ok(Self {
336 inner: FheValueInner::U16(a - b),
337 }),
338 (FheValueInner::U32(a), FheValueInner::U32(b)) => Ok(Self {
339 inner: FheValueInner::U32(a - b),
340 }),
341 (FheValueInner::U64(a), FheValueInner::U64(b)) => Ok(Self {
342 inner: FheValueInner::U64(a - b),
343 }),
344 _ => Err(SdkError::Fhe(format!(
345 "type mismatch in sub: {} vs {}",
346 self.kind(),
347 other.kind()
348 ))),
349 }
350 }
351
352 pub fn mul(&self, other: &Self) -> Result<Self> {
354 match (&self.inner, &other.inner) {
355 (FheValueInner::U8(a), FheValueInner::U8(b)) => Ok(Self {
356 inner: FheValueInner::U8(a * b),
357 }),
358 (FheValueInner::U16(a), FheValueInner::U16(b)) => Ok(Self {
359 inner: FheValueInner::U16(a * b),
360 }),
361 (FheValueInner::U32(a), FheValueInner::U32(b)) => Ok(Self {
362 inner: FheValueInner::U32(a * b),
363 }),
364 (FheValueInner::U64(a), FheValueInner::U64(b)) => Ok(Self {
365 inner: FheValueInner::U64(a * b),
366 }),
367 _ => Err(SdkError::Fhe(format!(
368 "type mismatch in mul: {} vs {}",
369 self.kind(),
370 other.kind()
371 ))),
372 }
373 }
374
375 pub fn eq(&self, other: &Self) -> Result<Self> {
377 use tfhe::prelude::FheEq;
378 match (&self.inner, &other.inner) {
379 (FheValueInner::U8(a), FheValueInner::U8(b)) => Ok(Self {
380 inner: FheValueInner::Bool(a.eq(b)),
381 }),
382 (FheValueInner::U16(a), FheValueInner::U16(b)) => Ok(Self {
383 inner: FheValueInner::Bool(a.eq(b)),
384 }),
385 (FheValueInner::U32(a), FheValueInner::U32(b)) => Ok(Self {
386 inner: FheValueInner::Bool(a.eq(b)),
387 }),
388 (FheValueInner::U64(a), FheValueInner::U64(b)) => Ok(Self {
389 inner: FheValueInner::Bool(a.eq(b)),
390 }),
391 _ => Err(SdkError::Fhe(format!(
392 "type mismatch in eq: {} vs {}",
393 self.kind(),
394 other.kind()
395 ))),
396 }
397 }
398
399 pub fn ne(&self, other: &Self) -> Result<Self> {
401 use tfhe::prelude::FheEq;
402 match (&self.inner, &other.inner) {
403 (FheValueInner::U8(a), FheValueInner::U8(b)) => Ok(Self {
404 inner: FheValueInner::Bool(a.ne(b)),
405 }),
406 (FheValueInner::U16(a), FheValueInner::U16(b)) => Ok(Self {
407 inner: FheValueInner::Bool(a.ne(b)),
408 }),
409 (FheValueInner::U32(a), FheValueInner::U32(b)) => Ok(Self {
410 inner: FheValueInner::Bool(a.ne(b)),
411 }),
412 (FheValueInner::U64(a), FheValueInner::U64(b)) => Ok(Self {
413 inner: FheValueInner::Bool(a.ne(b)),
414 }),
415 _ => Err(SdkError::Fhe(format!(
416 "type mismatch in ne: {} vs {}",
417 self.kind(),
418 other.kind()
419 ))),
420 }
421 }
422
423 pub fn lt(&self, other: &Self) -> Result<Self> {
425 use tfhe::prelude::FheOrd;
426 match (&self.inner, &other.inner) {
427 (FheValueInner::U8(a), FheValueInner::U8(b)) => Ok(Self {
428 inner: FheValueInner::Bool(a.lt(b)),
429 }),
430 (FheValueInner::U16(a), FheValueInner::U16(b)) => Ok(Self {
431 inner: FheValueInner::Bool(a.lt(b)),
432 }),
433 (FheValueInner::U32(a), FheValueInner::U32(b)) => Ok(Self {
434 inner: FheValueInner::Bool(a.lt(b)),
435 }),
436 (FheValueInner::U64(a), FheValueInner::U64(b)) => Ok(Self {
437 inner: FheValueInner::Bool(a.lt(b)),
438 }),
439 _ => Err(SdkError::Fhe(format!(
440 "type mismatch in lt: {} vs {}",
441 self.kind(),
442 other.kind()
443 ))),
444 }
445 }
446
447 pub fn le(&self, other: &Self) -> Result<Self> {
449 use tfhe::prelude::FheOrd;
450 match (&self.inner, &other.inner) {
451 (FheValueInner::U8(a), FheValueInner::U8(b)) => Ok(Self {
452 inner: FheValueInner::Bool(a.le(b)),
453 }),
454 (FheValueInner::U16(a), FheValueInner::U16(b)) => Ok(Self {
455 inner: FheValueInner::Bool(a.le(b)),
456 }),
457 (FheValueInner::U32(a), FheValueInner::U32(b)) => Ok(Self {
458 inner: FheValueInner::Bool(a.le(b)),
459 }),
460 (FheValueInner::U64(a), FheValueInner::U64(b)) => Ok(Self {
461 inner: FheValueInner::Bool(a.le(b)),
462 }),
463 _ => Err(SdkError::Fhe(format!(
464 "type mismatch in le: {} vs {}",
465 self.kind(),
466 other.kind()
467 ))),
468 }
469 }
470
471 pub fn gt(&self, other: &Self) -> Result<Self> {
473 use tfhe::prelude::FheOrd;
474 match (&self.inner, &other.inner) {
475 (FheValueInner::U8(a), FheValueInner::U8(b)) => Ok(Self {
476 inner: FheValueInner::Bool(a.gt(b)),
477 }),
478 (FheValueInner::U16(a), FheValueInner::U16(b)) => Ok(Self {
479 inner: FheValueInner::Bool(a.gt(b)),
480 }),
481 (FheValueInner::U32(a), FheValueInner::U32(b)) => Ok(Self {
482 inner: FheValueInner::Bool(a.gt(b)),
483 }),
484 (FheValueInner::U64(a), FheValueInner::U64(b)) => Ok(Self {
485 inner: FheValueInner::Bool(a.gt(b)),
486 }),
487 _ => Err(SdkError::Fhe(format!(
488 "type mismatch in gt: {} vs {}",
489 self.kind(),
490 other.kind()
491 ))),
492 }
493 }
494
495 pub fn ge(&self, other: &Self) -> Result<Self> {
497 use tfhe::prelude::FheOrd;
498 match (&self.inner, &other.inner) {
499 (FheValueInner::U8(a), FheValueInner::U8(b)) => Ok(Self {
500 inner: FheValueInner::Bool(a.ge(b)),
501 }),
502 (FheValueInner::U16(a), FheValueInner::U16(b)) => Ok(Self {
503 inner: FheValueInner::Bool(a.ge(b)),
504 }),
505 (FheValueInner::U32(a), FheValueInner::U32(b)) => Ok(Self {
506 inner: FheValueInner::Bool(a.ge(b)),
507 }),
508 (FheValueInner::U64(a), FheValueInner::U64(b)) => Ok(Self {
509 inner: FheValueInner::Bool(a.ge(b)),
510 }),
511 _ => Err(SdkError::Fhe(format!(
512 "type mismatch in ge: {} vs {}",
513 self.kind(),
514 other.kind()
515 ))),
516 }
517 }
518
519 pub fn and(&self, other: &Self) -> Result<Self> {
521 match (&self.inner, &other.inner) {
522 (FheValueInner::Bool(a), FheValueInner::Bool(b)) => Ok(Self {
523 inner: FheValueInner::Bool(a & b),
524 }),
525 _ => Err(SdkError::Fhe(format!(
526 "type mismatch in and: expected Bool, got {} and {}",
527 self.kind(),
528 other.kind()
529 ))),
530 }
531 }
532
533 pub fn or(&self, other: &Self) -> Result<Self> {
535 match (&self.inner, &other.inner) {
536 (FheValueInner::Bool(a), FheValueInner::Bool(b)) => Ok(Self {
537 inner: FheValueInner::Bool(a | b),
538 }),
539 _ => Err(SdkError::Fhe(format!(
540 "type mismatch in or: expected Bool, got {} and {}",
541 self.kind(),
542 other.kind()
543 ))),
544 }
545 }
546
547 pub fn xor(&self, other: &Self) -> Result<Self> {
549 match (&self.inner, &other.inner) {
550 (FheValueInner::Bool(a), FheValueInner::Bool(b)) => Ok(Self {
551 inner: FheValueInner::Bool(a ^ b),
552 }),
553 _ => Err(SdkError::Fhe(format!(
554 "type mismatch in xor: expected Bool, got {} and {}",
555 self.kind(),
556 other.kind()
557 ))),
558 }
559 }
560
561 pub fn not(&self) -> Result<Self> {
563 match &self.inner {
564 FheValueInner::Bool(v) => Ok(Self {
565 inner: FheValueInner::Bool(!v),
566 }),
567 _ => Err(SdkError::Fhe(format!(
568 "type mismatch in not: expected Bool, got {}",
569 self.kind()
570 ))),
571 }
572 }
573}
574
575#[cfg(all(test, feature = "fhe"))]
576mod tests {
577 use super::*;
578 use crate::fhe::FheKeys;
579
580 #[test]
581 fn test_fhe_value_arithmetic() {
582 let keys = FheKeys::generate().expect("generate keys");
583 keys.set_as_global_server_key();
584
585 let a = FheValue::encrypt_u8(10, &keys).expect("encrypt a");
586 let b = FheValue::encrypt_u8(5, &keys).expect("encrypt b");
587
588 let sum = a.add(&b).expect("add");
589 let result: u8 = sum.decrypt_u8(&keys).expect("decrypt sum");
590 assert_eq!(result, 15);
591
592 let diff = a.sub(&b).expect("sub");
593 let result: u8 = diff.decrypt_u8(&keys).expect("decrypt diff");
594 assert_eq!(result, 5);
595
596 let product = a.mul(&b).expect("mul");
597 let result: u8 = product.decrypt_u8(&keys).expect("decrypt product");
598 assert_eq!(result, 50);
599 }
600
601 #[test]
602 fn test_fhe_value_comparison() {
603 let keys = FheKeys::generate().expect("generate keys");
604 keys.set_as_global_server_key();
605
606 let a = FheValue::encrypt_u8(10, &keys).expect("encrypt a");
607 let b = FheValue::encrypt_u8(5, &keys).expect("encrypt b");
608 let c = FheValue::encrypt_u8(10, &keys).expect("encrypt c");
609
610 let gt = a.gt(&b).expect("gt");
611 assert!(gt.decrypt_bool(&keys).expect("decrypt gt"));
612
613 let lt = a.lt(&b).expect("lt");
614 assert!(!lt.decrypt_bool(&keys).expect("decrypt lt"));
615
616 let eq_result = a.eq(&c).expect("eq");
617 assert!(eq_result.decrypt_bool(&keys).expect("decrypt eq"));
618
619 let ne_result = a.ne(&b).expect("ne");
620 assert!(ne_result.decrypt_bool(&keys).expect("decrypt ne"));
621
622 let le = b.le(&a).expect("le");
623 assert!(le.decrypt_bool(&keys).expect("decrypt le"));
624
625 let ge = a.ge(&c).expect("ge");
626 assert!(ge.decrypt_bool(&keys).expect("decrypt ge"));
627 }
628
629 #[test]
630 fn test_fhe_value_boolean() {
631 let keys = FheKeys::generate().expect("generate keys");
632 keys.set_as_global_server_key();
633
634 let t = FheValue::encrypt_bool(true, &keys).expect("encrypt true");
635 let f = FheValue::encrypt_bool(false, &keys).expect("encrypt false");
636 let t2 = FheValue::encrypt_bool(true, &keys).expect("encrypt true2");
637
638 let and_result = t.and(&f).expect("and");
639 assert!(!and_result.decrypt_bool(&keys).expect("decrypt and"));
640
641 let or_result = t2.or(&f).expect("or");
642 assert!(or_result.decrypt_bool(&keys).expect("decrypt or"));
643
644 let xor_result = t.xor(&f).expect("xor");
645 assert!(xor_result.decrypt_bool(&keys).expect("decrypt xor"));
646
647 let not_t = t2.not().expect("not");
648 assert!(!not_t.decrypt_bool(&keys).expect("decrypt not"));
649 }
650
651 #[test]
652 fn test_fhe_value_type_mismatch() {
653 let keys = FheKeys::generate().expect("generate keys");
654 keys.set_as_global_server_key();
655
656 let a = FheValue::encrypt_u8(10, &keys).expect("encrypt u8");
657 let b = FheValue::encrypt_u16(5, &keys).expect("encrypt u16");
658
659 assert!(a.add(&b).is_err(), "should fail on type mismatch");
660 assert!(a.sub(&b).is_err(), "should fail on type mismatch");
661
662 let bool_val = FheValue::encrypt_bool(true, &keys).expect("encrypt bool");
663 assert!(bool_val.add(&a).is_err(), "bool + u8 should fail");
664 assert!(a.and(&b).is_err(), "u8 and u16 should fail on and");
665 }
666}