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 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 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 ```rust
let param = Param { 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)?; 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 m1 = Rq::rand_u64(&mut rng, msg_dist, &param.pt())?;
let m2 = 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())?; 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 // encode the msgs into the plaintext space
let p1 = TLWE::encode(&param, &m1); // plaintext let p1 = TLWE::encode(&param, &m1); // plaintext
let p2 = TLWE::encode(&param, &m2); // 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 c1 = TLWE::encrypt(&mut rng, &param, &pk, &p1)?;
let c2 = TLWE::encrypt(&mut rng, &param, &pk, &p2)?; 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); let pt = pt.mul_div_round(p, u64::MAX);
Rq::from_vec_u64(&param.pt(), pt.coeffs().iter().map(|c| c.0).collect()) 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) /// encrypts with the given SecretKey (instead of PublicKey)
pub fn encrypt_s(rng: impl Rng, param: &Param, sk: &SecretKey, p: &Tn) -> Result<Self> { 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 m1 = Rq::rand_u64(&mut rng, msg_dist, &param.pt())?;
let m2 = 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); 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)?; 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); let p = p.mul_div_round(param.t, u64::MAX);
Rq::from_vec_u64(&param.pt(), p.coeffs().iter().map(|c| c.0).collect()) 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) // encrypts with the given SecretKey (instead of PublicKey)
pub fn encrypt_s(rng: impl Rng, param: &Param, sk: &SecretKey, p: &T64) -> Result<Self> { 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 m1 = Rq::rand_u64(&mut rng, msg_dist, &param.pt())?;
let m2 = 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); 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)?; let c1 = TLWE::encrypt(&mut rng, &param, &pk, &p1)?;

Loading…
Cancel
Save