use sunscreen::{ fhe_program, types::{bfv::Signed, Cipher}, Compiler, FheProgramInput, PlainModulusConstraint, Runtime, }; use std::ops::*; fn add_fn(a: T, b: U) -> R where T: Add, { a + b } #[test] fn can_add_cipher_cipher() { #[fhe_program(scheme = "bfv")] fn add(a: Cipher, b: Cipher) -> Cipher { add_fn(a, b) } let app = Compiler::new() .fhe_program(add) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(15); let a_c = runtime.encrypt(a, &public_key).unwrap(); let b = Signed::from(-5); let b_c = runtime.encrypt(b, &public_key).unwrap(); let args: Vec = vec![a_c.into(), b_c.into()]; let result = runtime .run(app.get_program(add).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, add_fn(a, b)); } #[test] fn can_add_cipher_plain() { #[fhe_program(scheme = "bfv")] fn add(a: Cipher, b: Signed) -> Cipher { add_fn(a, b) } let app = Compiler::new() .fhe_program(add) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(15); let a_c = runtime.encrypt(a, &public_key).unwrap(); let b = Signed::from(-5); let args: Vec = vec![a_c.into(), b.into()]; let result = runtime .run(app.get_program(add).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, add_fn(a, b)); } #[test] fn can_add_plain_cipher() { #[fhe_program(scheme = "bfv")] fn add(a: Signed, b: Cipher) -> Cipher { add_fn(a, b) } let app = Compiler::new() .fhe_program(add) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(-5); let b = Signed::from(15); let b_c = runtime.encrypt(b, &public_key).unwrap(); let args: Vec = vec![a.into(), b_c.into()]; let result = runtime .run(app.get_program(add).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, add_fn(a, b)); } #[test] fn can_add_cipher_literal() { #[fhe_program(scheme = "bfv")] fn add(a: Cipher) -> Cipher { add_fn(a, -4) } let app = Compiler::new() .fhe_program(add) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(15); let a_c = runtime.encrypt(a, &public_key).unwrap(); let args: Vec = vec![a_c.into()]; let result = runtime .run(app.get_program(add).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, add_fn(a, -4)); } #[test] fn can_add_literal_cipher() { #[fhe_program(scheme = "bfv")] fn add(a: Cipher) -> Cipher { add_fn(-4, a) } let app = Compiler::new() .fhe_program(add) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(15); let a_c = runtime.encrypt(a, &public_key).unwrap(); let args: Vec = vec![a_c.into()]; let result = runtime .run(app.get_program(add).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, add_fn(-4, a)); } fn sub_fn(a: T, b: U) -> R where T: Sub, { a - b } #[test] fn can_sub_cipher_cipher() { #[fhe_program(scheme = "bfv")] fn sub(a: Cipher, b: Cipher) -> Cipher { sub_fn(a, b) } let app = Compiler::new() .fhe_program(sub) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(15); let a_c = runtime.encrypt(a, &public_key).unwrap(); let b = Signed::from(-5); let b_c = runtime.encrypt(b, &public_key).unwrap(); let args: Vec = vec![a_c.into(), b_c.into()]; let result = runtime .run(app.get_program(sub).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, sub_fn(a, b)); } #[test] fn can_sub_cipher_plain() { #[fhe_program(scheme = "bfv")] fn sub(a: Cipher, b: Signed) -> Cipher { sub_fn(a, b) } let app = Compiler::new() .fhe_program(sub) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(15); let a_c = runtime.encrypt(a, &public_key).unwrap(); let b = Signed::from(-5); let args: Vec = vec![a_c.into(), b.into()]; let result = runtime .run(app.get_program(sub).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, sub_fn(a, b)); } #[test] fn can_sub_plain_cipher() { #[fhe_program(scheme = "bfv")] fn sub(a: Signed, b: Cipher) -> Cipher { sub_fn(a, b) } let app = Compiler::new() .fhe_program(sub) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(-5); let b = Signed::from(15); let b_c = runtime.encrypt(b, &public_key).unwrap(); let args: Vec = vec![a.into(), b_c.into()]; let result = runtime .run(app.get_program(sub).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, sub_fn(a, b)); } #[test] fn can_sub_cipher_literal() { #[fhe_program(scheme = "bfv")] fn sub(a: Cipher) -> Cipher { sub_fn(a, -4) } let app = Compiler::new() .fhe_program(sub) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(15); let a_c = runtime.encrypt(a, &public_key).unwrap(); let args: Vec = vec![a_c.into()]; let result = runtime .run(app.get_program(sub).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, sub_fn(a, -4)); } #[test] fn can_sub_literal_cipher() { #[fhe_program(scheme = "bfv")] fn sub(a: Cipher) -> Cipher { sub_fn(-4, a) } let app = Compiler::new() .fhe_program(sub) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(15); let a_c = runtime.encrypt(a, &public_key).unwrap(); let args: Vec = vec![a_c.into()]; let result = runtime .run(app.get_program(sub).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, sub_fn(-4, a)); } fn mul_fn(a: T, b: U) -> R where T: Mul, { a * b } #[test] fn can_mul_cipher_cipher() { #[fhe_program(scheme = "bfv")] fn mul(a: Cipher, b: Cipher) -> Cipher { mul_fn(a, b) } let app = Compiler::new() .fhe_program(mul) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(15); let a_c = runtime.encrypt(a, &public_key).unwrap(); let b = Signed::from(-5); let b_c = runtime.encrypt(b, &public_key).unwrap(); let args: Vec = vec![a_c.into(), b_c.into()]; let result = runtime .run(app.get_program(mul).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, mul_fn(a, b)); } #[test] fn can_mul_cipher_plain() { #[fhe_program(scheme = "bfv")] fn mul(a: Cipher, b: Signed) -> Cipher { mul_fn(a, b) } let app = Compiler::new() .fhe_program(mul) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(15); let a_c = runtime.encrypt(a, &public_key).unwrap(); let b = Signed::from(-5); let args: Vec = vec![a_c.into(), b.into()]; let result = runtime .run(app.get_program(mul).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, mul_fn(a, b)); } #[test] fn can_mul_plain_cipher() { #[fhe_program(scheme = "bfv")] fn mul(a: Signed, b: Cipher) -> Cipher { mul_fn(a, b) } let app = Compiler::new() .fhe_program(mul) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(-5); let b = Signed::from(15); let b_c = runtime.encrypt(b, &public_key).unwrap(); let args: Vec = vec![a.into(), b_c.into()]; let result = runtime .run(app.get_program(mul).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, mul_fn(a, b)); } #[test] fn can_mul_cipher_literal() { #[fhe_program(scheme = "bfv")] fn mul(a: Cipher) -> Cipher { mul_fn(a, -4) } let app = Compiler::new() .fhe_program(mul) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(15); let a_c = runtime.encrypt(a, &public_key).unwrap(); let args: Vec = vec![a_c.into()]; let result = runtime .run(app.get_program(mul).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, mul_fn(a, -4)); } #[test] fn can_mul_literal_cipher() { #[fhe_program(scheme = "bfv")] fn mul(a: Cipher) -> Cipher { mul_fn(-4, a) } let app = Compiler::new() .fhe_program(mul) .additional_noise_budget(5) .plain_modulus_constraint(PlainModulusConstraint::Raw(500)) .compile() .unwrap(); let runtime = Runtime::new(app.params()).unwrap(); let (public_key, private_key) = runtime.generate_keys().unwrap(); let a = Signed::from(15); let a_c = runtime.encrypt(a, &public_key).unwrap(); let args: Vec = vec![a_c.into()]; let result = runtime .run(app.get_program(mul).unwrap(), args, &public_key) .unwrap(); let c: Signed = runtime.decrypt(&result[0], &private_key).unwrap(); assert_eq!(c, mul_fn(-4, a)); } #[test] fn can_create_default() { assert_eq!(Into::::into(Signed::default()), 0); }