mirror of
https://github.com/arnaucube/fhe-study.git
synced 2026-01-24 04:33:52 +01:00
90 lines
3.2 KiB
Markdown
90 lines
3.2 KiB
Markdown
# fhe-study
|
|
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]/(X^N+1)$, $R=\mathbb{Z}[X]/(X^N+1)$, $\mathbb{T}_q[X]/(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 implementation
|
|
- `ckks`: https://eprint.iacr.org/2016/421.pdf scheme implementation
|
|
- `tfhe`: https://eprint.iacr.org/2018/421.pdf scheme implementation
|
|
|
|
|
|
## Run tests
|
|
`cargo test --release`
|
|
|
|
## Example of usage
|
|
> 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 usage of `TLWE` by `CKKS` or `BFV`.
|
|
|
|
```rust
|
|
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::rng();
|
|
let msg_dist = Uniform::new(0_u64, param.t);
|
|
|
|
let (sk, pk) = TLWE::new_key(&mut rng, ¶m)?;
|
|
|
|
// get three random msgs in Rt
|
|
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 = TLWE::new_const(¶m, &m3); // as constant/public value
|
|
|
|
// encrypt p1 and m2
|
|
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);
|
|
```
|
|
|
|
|
|
## Status of the implementation
|
|
|
|
- TFHE
|
|
- {TLWE, TGLWE, TLev, TGLev, TGSW, TGGSW} encryption & decryption
|
|
- addition of ciphertexts, addition & multiplication of ciphertext by a plaintext
|
|
- external products of ciphertexts
|
|
- TGSW x TLWE
|
|
- TGGSW x TGLWE
|
|
- {TGSW, TGGSW} CMux gate
|
|
- blind rotation, key switching, mod switching
|
|
- bootstrapping
|
|
- CKKS
|
|
- encoding & decoding
|
|
- encryption & decryption
|
|
- addition & substraction of ciphertexts
|
|
- BFV
|
|
- encryption & decryption
|
|
- addition & substraction of ciphertexts
|
|
- addition & multiplication of ciphertext by a plaintext
|
|
- multiplication of ciphertexts with relinearization
|
|
- GFHE (generalized FHE)
|
|
- {GLWE & GLev} encryption & decryption
|
|
- key switching, mod switching
|
|
- addition & substraction of ciphertexts
|
|
- addition & multiplication of ciphertext by a plaintext
|
|
- arith
|
|
- base arithmetic for $\mathbb{Z}_q,~~ R_q=\mathbb{Z}_q[X]/(X^N+1),~~ R=\mathbb{Z}[X]/(X^N+1),~~ \mathbb{T}_q[X]/(X^N +1)$
|
|
- NTT implementation (negacyclic convolution)
|