Browse Source

add methods for encoding constants for ct-pt-multiplication

rm-const-generics
arnaucube 2 weeks ago
parent
commit
9c214486ec
3 changed files with 22 additions and 10 deletions
  1. +4
    -3
      README.md
  2. +11
    -5
      tfhe/src/tglwe.rs
  3. +7
    -2
      tfhe/src/tlwe.rs

+ 4
- 3
README.md

@ -16,7 +16,7 @@ Implementations from scratch done while studying some FHE papers; do not use in
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>`.
and the usage of `TLWE` by `CKKS` or `BFV`.
```rust
let param = Param {
@ -31,7 +31,7 @@ let msg_dist = Uniform::new(0_u64, param.t);
let (sk, pk) = TLWE::new_key(&mut rng, &param)?;
// get two random msgs in Z_t
// get three random msgs in Rt
let m1 = Rq::rand_u64(&mut rng, msg_dist, &param.pt())?;
let m2 = Rq::rand_u64(&mut rng, msg_dist, &param.pt())?;
let m3 = Rq::rand_u64(&mut rng, msg_dist, &param.pt())?;
@ -39,8 +39,9 @@ let m3 = Rq::rand_u64(&mut rng, msg_dist, ¶m.pt())?;
// encode the msgs into the plaintext space
let p1 = TLWE::encode(&param, &m1); // plaintext
let p2 = TLWE::encode(&param, &m2); // plaintext
let c3_const: T64 = T64(m3.coeffs()[0].v); // encode it as constant
let c3_const = TLWE::new_const(&param, &m3); // as constant/public value
// encrypt p1 and m2
let c1 = TLWE::encrypt(&mut rng, &param, &pk, &p1)?;
let c2 = TLWE::encrypt(&mut rng, &param, &pk, &p2)?;

+ 11
- 5
tfhe/src/tglwe.rs

@ -61,6 +61,16 @@ impl TGLWE {
let pt = pt.mul_div_round(p, u64::MAX);
Rq::from_vec_u64(&param.pt(), pt.coeffs().iter().map(|c| c.0).collect())
}
/// encodes the given message as a TGLWE constant/public value, for using it
/// in ct-pt-multiplication.
pub fn new_const(param: &Param, m: &Rq) -> Tn {
debug_assert_eq!(param.t, m.param.q);
// don't scale up m, set the Tn element directly from m's coefficients
Tn {
param: param.ring,
coeffs: m.coeffs().iter().map(|c_i| T64(c_i.v)).collect(),
}
}
/// encrypts with the given SecretKey (instead of PublicKey)
pub fn encrypt_s(rng: impl Rng, param: &Param, sk: &SecretKey, p: &Tn) -> Result<Self> {
@ -310,11 +320,7 @@ mod tests {
let m1 = Rq::rand_u64(&mut rng, msg_dist, &param.pt())?;
let m2 = Rq::rand_u64(&mut rng, msg_dist, &param.pt())?;
let p1: Tn = TGLWE::encode(&param, &m1);
// don't scale up p2, set it directly from m2
let p2: Tn = Tn {
param: param.ring,
coeffs: m2.coeffs().iter().map(|c_i| T64(c_i.v)).collect(),
};
let p2: Tn = TGLWE::new_const(&param, &m2); // as constant/public value
let c1 = TGLWE::encrypt(&mut rng, &param, &pk, &p1)?;

+ 7
- 2
tfhe/src/tlwe.rs

@ -61,6 +61,12 @@ impl TLWE {
let p = p.mul_div_round(param.t, u64::MAX);
Rq::from_vec_u64(&param.pt(), p.coeffs().iter().map(|c| c.0).collect())
}
/// encodes the given message as a TLWE constant/public value, for using it
/// in ct-pt-multiplication.
pub fn new_const(param: &Param, m: &Rq) -> T64 {
debug_assert_eq!(param.t, m.param.q);
T64(m.coeffs()[0].v)
}
// encrypts with the given SecretKey (instead of PublicKey)
pub fn encrypt_s(rng: impl Rng, param: &Param, sk: &SecretKey, p: &T64) -> Result<Self> {
@ -400,8 +406,7 @@ mod tests {
let m1 = Rq::rand_u64(&mut rng, msg_dist, &param.pt())?;
let m2 = Rq::rand_u64(&mut rng, msg_dist, &param.pt())?;
let p1: T64 = TLWE::encode(&param, &m1);
// don't scale up p2, set it directly from m2
let p2: T64 = T64(m2.coeffs()[0].v);
let p2: T64 = TLWE::new_const(&param, &m2); // as constant/public value
let c1 = TLWE::encrypt(&mut rng, &param, &pk, &p1)?;

Loading…
Cancel
Save