Skip to content

Commit

Permalink
add ckks encoding and decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
Janmajayamall committed Feb 25, 2024
1 parent 3837669 commit 9aea88f
Show file tree
Hide file tree
Showing 5 changed files with 360 additions and 123 deletions.
70 changes: 53 additions & 17 deletions src/core_crypto/num/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use num_complex::Complex;
use num_bigint::{BigInt, BigUint};
use num_complex::{Complex, ComplexFloat};
use num_traits::{
AsPrimitive, CheckedShl, CheckedShr, MulAddAssign, Num, NumAssign, NumOps, One, Pow, PrimInt,
ToPrimitive, WrappingAdd, WrappingMul, WrappingShl, WrappingShr, WrappingSub, Zero,
AsPrimitive, CheckedShl, CheckedShr, Float, MulAddAssign, Num, NumAssign, NumCast, NumOps,
NumRef, One, Pow, PrimInt, RefNum, ToPrimitive, WrappingAdd, WrappingMul, WrappingShl,
WrappingShr, WrappingSub, Zero,
};
use std::{
fmt::{Debug, Display},
Expand Down Expand Up @@ -49,35 +51,69 @@ impl NumericConstants for u128 {
impl UnsignedInteger for u64 {}
impl UnsignedInteger for u128 {}

pub trait Float: num_traits::Float + From<u32> {
const PI: Self;
}

impl Float for f64 {
const PI: Self = std::f64::consts::PI * 2.0;
}

pub trait ComplexNumber<T>: Num + Div<T, Output = Self>
// TODO(Jay): How to add trait bound for impl Add<&T, Output = T> for {}. Doing
// this remove unecessary copy bounds in ckks/ops.rs
pub trait ComplexNumber<T>:
Num + NumRef + for<'r> Div<&'r T, Output = Self> + for<'r> Mul<&'r T, Output = Self>
where
T: Float,
T: BFloat,
{
fn new(re: T, im: T) -> Self;
fn nth_root(n: u32) -> Self;
fn powu(&self, exp: u32) -> Self;
fn re(&self) -> T;
fn img(&self) -> T;
}

impl<T: Debug + Float + Clone> ComplexNumber<T> for Complex<T> {
pub trait BUint: Num + NumRef + PartialOrd {}

pub trait BInt: Num + NumRef + PartialOrd {}

pub trait BFloat: Num + NumRef + Float + NumCast {
const TWICE_PI: Self;
}

// TODO(Jay): CastToZp<To> is unecessary since it is only used on simd_encode
// where it can easily be replaced with TryConvertFrom<[f64]> to M
pub trait CastToZp<To> {
fn cast(&self, q: &To) -> To;
}

pub trait ModInverse {
fn mod_inverse(&self, q: Self) -> Self;
}

impl<T: BFloat + Clone> ComplexNumber<T> for Complex<T> {
fn new(re: T, im: T) -> Self {
Complex::new(re, im)
}
fn nth_root(n: u32) -> Self {
Complex::<T>::from_polar(T::one(), T::PI / <T as From<u32>>::from(n))
Complex::<T>::from_polar(T::one(), T::TWICE_PI / T::from(n).unwrap())
}
fn powu(&self, exp: u32) -> Self {
self.powu(exp)
}
fn re(&self) -> T {
self.re
self.re.clone()
}
fn img(&self) -> T {
self.im
self.im.clone()
}
}

impl BFloat for f64 {
const TWICE_PI: Self = std::f64::consts::PI * 2.0;
}

impl BUint for BigUint {}

impl CastToZp<BigUint> for f64 {
fn cast(&self, q: &BigUint) -> BigUint {
let v = self.round();
if v < 0.0 {
q - (v.abs().to_u64().unwrap() % q)
} else {
v.to_u64().unwrap() % q
}
}
}
16 changes: 15 additions & 1 deletion src/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
MontgomeryBackend, MontgomeryScalar,
},
ntt::{Ntt, NttConfig},
num::UnsignedInteger,
num::{BFloat, ComplexNumber, UnsignedInteger},
},
utils::{mod_inverse, mod_inverse_big_unit},
};
Expand Down Expand Up @@ -140,3 +140,17 @@ pub trait BfvEncodingDecodingParameters: Parameters {
fn t_ntt_op(&self) -> &Self::NttOp;
fn modt_op(&self) -> &Self::ModOp;
}

// CKKS encoding decoding parameters
pub trait CkksEncodingDecodingParameters: Parameters {
type F: BFloat;
type Complex: ComplexNumber<Self::F>;
type BU;

fn delta(&self) -> Self::F;
fn psi_powers(&self) -> &[Self::Complex];
fn rot_group(&self) -> &[usize];
fn ring_size(&self) -> usize;
fn bigq_at_level(&self, level: usize) -> &Self::BU;
fn q_moduli_chain_at_level(&self, level: usize) -> &[Self::Scalar];
}
Loading

0 comments on commit 9aea88f

Please sign in to comment.