|
|
3 months ago | |
|---|---|---|
| arith | 3 months ago | |
| bfv | 3 months ago | |
| ckks | 3 months ago | |
| gfhe | 3 months ago | |
| tfhe | 3 months ago | |
| .gitignore | 4 months ago | |
| Cargo.toml | 3 months ago | |
| LICENSE | 4 months ago | |
| README.md | 3 months ago | |
| rust-analyzer.toml | 4 months ago | |
| rust-toolchain.toml | 4 months ago | |
| rustfmt.toml | 4 months ago | |
Implementations from scratch done while studying some FHE papers; do not use in production.
arith: contains $\mathbb{Z}_q$, $R_q=\mathbb{Z}_q/(X^N+1)$, $R=\mathbb{Z}/(X^N+1)$, $\mathbb{T}_q/(X^N +1)$ arithmetic implementations, together with the NTT implementation.gfhe: (gfhe=generalized-fhe) contains the structs and logic for RLWE, GLWE, GLev, GGSW, RGSW cryptosystems, and modulus switching and key switching methods, which can be used by concrete FHE schemes.bfv: https://eprint.iacr.org/2012/144.pdf scheme implementationckks: https://eprint.iacr.org/2016/421.pdf scheme implementationtfhe: https://eprint.iacr.org/2018/421.pdf scheme implementationcargo test --release
the repo is a work in progress, interfaces will change.
This example shows usage of TFHE, but the idea is that the same interface would
work for using CKKS & BFV, the only thing to be changed would be the parameters
and the line type S = TWLE<K> to use CKKS<Q, N> or BFV<Q, N, T>.
let param = Param {
err_sigma: crate::ERR_SIGMA,
ring: RingParam { q: u64::MAX, n: 1 },
k: 256,
t: 128, // plaintext modulus
};
let mut rng = rand::thread_rng();
let msg_dist = Uniform::new(0_u64, param.t);
let (sk, pk) = TLWE::new_key(&mut rng, ¶m)?;
// get two random msgs in Z_t
let m1 = Rq::rand_u64(&mut rng, msg_dist, ¶m.pt())?;
let m2 = Rq::rand_u64(&mut rng, msg_dist, ¶m.pt())?;
let m3 = Rq::rand_u64(&mut rng, msg_dist, ¶m.pt())?;
// encode the msgs into the plaintext space
let p1 = TLWE::encode(¶m, &m1); // plaintext
let p2 = TLWE::encode(¶m, &m2); // plaintext
let c3_const: T64 = T64(m3.coeffs()[0].v); // encode it as constant
let c1 = TLWE::encrypt(&mut rng, ¶m, &pk, &p1)?;
let c2 = TLWE::encrypt(&mut rng, ¶m, &pk, &p2)?;
// now we can do encrypted operations (notice that we do them using simple
// operation notation by rust's operator overloading):
let c_12 = c1 + c2;
let c4 = c_12 * c3_const;
// decrypt & decode
let p4_recovered = c4.decrypt(&sk);
let m4 = TLWE::decode(¶m, &p4_recovered);
// m4 is equal to (m1+m2)*m3
assert_eq!(((m1 + m2).to_r() * m3.to_r()).to_rq(param.t), m4);