Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ repository = "https://github.com/fairmath/openfhe-rs"

[dependencies]
cxx = "1.0"
num-bigint = { version = "0.4", default-features = false }
num-traits = "0.2"

[build-dependencies]
cxx-build = "1.0"
Expand Down
109 changes: 109 additions & 0 deletions examples/dcrt_poly.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use num_bigint::BigUint;
use num_traits::Num;
use openfhe::ffi::{self, GetMatrixElement};

fn main() {
let val = String::from("123456789099999");
// Parameters based on https://github.com/openfheorg/openfhe-development/blob/7b8346f4eac27121543e36c17237b919e03ec058/src/core/unittest/UnitTestTrapdoor.cpp#L314
let n: u32 = 16;
let size: usize = 4; // Number of CRT
let k_res: usize = 51;

let const_poly = ffi::DCRTPolyGenFromConst(n, size, k_res, &val);
// print the const_poly
println!("const_poly: {:?}", const_poly);

let modulus = ffi::GenModulus(n, size, k_res);
println!("modulus: {:?}", modulus);

let const_poly_2 = ffi::DCRTPolyGenFromConst(n, size, k_res, &val);
// print the const_poly_2
println!("const_poly_2: {:?}", const_poly_2);

// assert that the two const_poly are equal
assert_eq!(const_poly, const_poly_2);

let const_poly_one = ffi::DCRTPolyGenFromConst(n, size, k_res, &String::from("1"));
let negated_poly_one = const_poly_one.Negate();
println!("negated_poly_one: {:?}", negated_poly_one);

let coeffs = vec![
String::from("123456789099999"),
String::from("1234567842539099999"),
String::from("31232189328123893128912983"),
String::from("24535423544252452453"),
];

let poly = ffi::DCRTPolyGenFromVec(n, size, k_res, &coeffs);
let poly_2 = ffi::DCRTPolyGenFromVec(n, size, k_res, &coeffs);

// assert that the two poly are equal
assert_eq!(poly, poly_2);

// perform polynomial addition
let poly_add = ffi::DCRTPolyAdd(&poly, &poly_2);
println!("poly_add: {:?}", poly_add);

// perform polynomial multiplication
let poly_mul = ffi::DCRTPolyMul(&poly, &poly_2);
println!("poly_mul: {:?}", poly_mul);

// get the coefficients of the polynomials
let coeffs_poly = poly.GetCoefficients();
println!("coeffs_poly: {:?}", coeffs_poly);
let coeffs_poly_2 = poly_2.GetCoefficients();
println!("coeffs_poly_2: {:?}", coeffs_poly_2);
let coeffs_poly_add = poly_add.GetCoefficients();
println!("coeffs_poly_add: {:?}", coeffs_poly_add);

let poly_modulus = poly.GetModulus();
assert_eq!(poly_modulus, modulus);

let sigma = 4.57825;
let base = 2;
let modulus_big_uint = BigUint::from_str_radix(&modulus, 10).unwrap();
let k = modulus_big_uint.bits() as u32;

// ** gen trapdoor **
let trapdoor_output = ffi::DCRTTrapdoorGen(n, size, k_res, sigma, base, false);
let trapdoor = trapdoor_output.GetTrapdoorPair();
let public_matrix = trapdoor_output.GetPublicMatrix();

// sample a target polynomial
let u = ffi::DCRTPolyGenFromDug(n, size, k_res);

// generate a preimage such that public_matrix * preimage = target_polynomial
let _preimage = ffi::DCRTTrapdoorGaussSamp(n, k, &public_matrix, &trapdoor, &u, base, sigma);

// ** gen trapdoor for a square matrix target of size 2x2 **
let d = 2;
let trapdoor_output_square =
ffi::DCRTSquareMatTrapdoorGen(n, size, k_res, d, sigma, base, false);

let trapdoor_square = trapdoor_output_square.GetTrapdoorPair();
let public_matrix_square = trapdoor_output_square.GetPublicMatrix();

// build the target matrix by sampling a random polynomial for each element
let mut target_matrix = ffi::MatrixGen(n, size, k_res, d, d);
for i in 0..d {
for j in 0..d {
let poly = ffi::DCRTPolyGenFromDug(n, size, k_res);
ffi::SetMatrixElement(target_matrix.as_mut().unwrap(), i, j, &poly);
}
}

// generate a preimage such that public_matrix_square * preimage = target_matrix
let _preimage_square = ffi::DCRTSquareMatTrapdoorGaussSamp(
n,
k,
&public_matrix_square,
&trapdoor_square,
&target_matrix,
base,
sigma,
);

let dummy_poly = ffi::DCRTPolyGenFromDug(n, size, k_res);
let decomposed_poly = dummy_poly.Decompose();
let poly_0_0 = GetMatrixElement(&decomposed_poly, 0, 0);
}
19 changes: 0 additions & 19 deletions examples/trapdoor.rs

This file was deleted.

186 changes: 181 additions & 5 deletions src/DCRTPoly.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "DCRTPoly.h"
#include "openfhe/src/lib.rs.h"
#include <sstream>

namespace openfhe
{
Expand All @@ -8,6 +8,157 @@ DCRTPoly::DCRTPoly(lbcrypto::DCRTPoly&& poly) noexcept
: m_poly(std::move(poly))
{ }

const lbcrypto::DCRTPoly& DCRTPoly::GetPoly() const noexcept
{
return m_poly;
}


rust::String DCRTPoly::GetString() const
{
std::stringstream stream;
stream << m_poly;
return rust::String(stream.str());
}

rust::String DCRTPoly::GetModulus() const
{
return m_poly.GetModulus().ToString();
}

bool DCRTPoly::IsEqual(const DCRTPoly& other) const noexcept
{
return m_poly == other.m_poly;
}

rust::Vec<rust::String> DCRTPoly::GetCoefficients() const
{
auto tempPoly = m_poly;
tempPoly.SetFormat(Format::COEFFICIENT);

lbcrypto::DCRTPoly::PolyLargeType polyLarge = tempPoly.CRTInterpolate();

const lbcrypto::BigVector &coeffs = polyLarge.GetValues();

rust::Vec<rust::String> result;
for (size_t i = 0; i < coeffs.GetLength(); ++i)
{
result.push_back(rust::String(coeffs[i].ToString()));
}

return result;
}

std::unique_ptr<DCRTPoly> DCRTPoly::Negate() const
{
return std::make_unique<DCRTPoly>(-m_poly);
}

std::unique_ptr<Matrix> DCRTPoly::Decompose() const
{
std::vector<lbcrypto::DCRTPoly> decomposed = m_poly.CRTDecompose(1);

auto zero_alloc = lbcrypto::DCRTPoly::Allocator(m_poly.GetParams(), Format::COEFFICIENT);
lbcrypto::Matrix<lbcrypto::DCRTPoly> decomposedMatrix(zero_alloc, 1, decomposed.size());

for (size_t i = 0; i < decomposed.size(); i++) {
decomposedMatrix(0, i) = decomposed[i];
}

return std::make_unique<Matrix>(std::move(decomposedMatrix));
}

// Arithmetic
std::unique_ptr<DCRTPoly> DCRTPolyAdd(const DCRTPoly& rhs, const DCRTPoly& lhs)
{
return std::make_unique<DCRTPoly>(rhs.GetPoly() + lhs.GetPoly());
}

std::unique_ptr<DCRTPoly> DCRTPolyMul(const DCRTPoly& rhs, const DCRTPoly& lhs)
{
return std::make_unique<DCRTPoly>(rhs.GetPoly() * lhs.GetPoly());
}

// Generator functions
std::unique_ptr<DCRTPoly> DCRTPolyGenFromConst(
usint n,
size_t size,
size_t kRes,
const rust::String& value)
{
// Create params
auto params = std::make_shared<lbcrypto::ILDCRTParams<lbcrypto::BigInteger>>(2 * n, size, kRes);

// Create a BigVector
lbcrypto::BigVector bigVec(params -> GetRingDimension(), params ->GetModulus());
bigVec[0] = lbcrypto::BigInteger(std::string(value));

// Create a Poly that supports BigInteger coefficients)
lbcrypto::PolyImpl<lbcrypto::BigVector> polyLarge(params, Format::COEFFICIENT);
polyLarge.SetValues(bigVec, Format::COEFFICIENT);

// Convert polyLarge to a DCRTPoly
lbcrypto::DCRTPoly dcrtPoly(polyLarge, params);

// switch dcrtPoly to EVALUATION format
dcrtPoly.SetFormat(Format::EVALUATION);

return std::make_unique<DCRTPoly>(std::move(dcrtPoly));
}

std::unique_ptr<DCRTPoly> DCRTPolyGenFromVec(
usint n,
size_t size,
size_t kRes,
const rust::Vec<rust::String>& values)
{
// Create params
auto params = std::make_shared<lbcrypto::ILDCRTParams<lbcrypto::BigInteger>>(2 * n, size, kRes);

// Create a BigVector
lbcrypto::BigVector bigVec(params->GetRingDimension(), params->GetModulus());
for (size_t i = 0; i < values.size() && i < params->GetRingDimension(); i++) {
bigVec[i] = lbcrypto::BigInteger(std::string(values[i]));
}

// Create a Poly that supports BigInteger coefficients
lbcrypto::PolyImpl<lbcrypto::BigVector> polyLarge(params, Format::COEFFICIENT);
polyLarge.SetValues(bigVec, Format::COEFFICIENT);

// Convert polyLarge to a DCRTPoly
lbcrypto::DCRTPoly dcrtPoly(polyLarge, params);

// switch dcrtPoly to EVALUATION format
dcrtPoly.SetFormat(Format::EVALUATION);

return std::make_unique<DCRTPoly>(std::move(dcrtPoly));
}

std::unique_ptr<DCRTPoly> DCRTPolyGenFromBug(usint n, size_t size, size_t kRes)
{
auto params = std::make_shared<lbcrypto::ILDCRTParams<lbcrypto::BigInteger>>(2 * n, size, kRes);
typename lbcrypto::DCRTPoly::BugType bug;
auto poly = lbcrypto::DCRTPoly(bug, params, Format::EVALUATION);
return std::make_unique<DCRTPoly>(std::move(poly));
}

std::unique_ptr<DCRTPoly> DCRTPolyGenFromDug(usint n, size_t size, size_t kRes)
{
auto params = std::make_shared<lbcrypto::ILDCRTParams<lbcrypto::BigInteger>>(2 * n, size, kRes);
typename lbcrypto::DCRTPoly::DugType dug;
auto poly = lbcrypto::DCRTPoly(dug, params, Format::EVALUATION);
return std::make_unique<DCRTPoly>(std::move(poly));
}

std::unique_ptr<DCRTPoly> DCRTPolyGenFromDgg(usint n, size_t size, size_t kRes, double sigma)
{
auto params = std::make_shared<lbcrypto::ILDCRTParams<lbcrypto::BigInteger>>(2 * n, size, kRes);
typename lbcrypto::DCRTPoly::DggType dgg(sigma);
auto poly = lbcrypto::DCRTPoly(dgg, params, Format::EVALUATION);
return std::make_unique<DCRTPoly>(std::move(poly));
}


DCRTPolyParams::DCRTPolyParams(const std::shared_ptr<lbcrypto::DCRTPoly::Params>& params) noexcept
: m_params(params)
{ }
Expand All @@ -22,11 +173,36 @@ std::unique_ptr<DCRTPolyParams> DCRTPolyGenNullParams()
return std::make_unique<DCRTPolyParams>();
}

std::unique_ptr<DCRTPolyImpl> DCRTPolyGenFromDug(const ILDCRTParams& params)
// Matrix functions
std::unique_ptr<Matrix> MatrixGen(
usint n,
size_t size,
size_t kRes,
size_t nrow,
size_t ncol)
{
auto params = std::make_shared<lbcrypto::ILDCRTParams<lbcrypto::BigInteger>>(2 * n, size, kRes);
auto zero_alloc = lbcrypto::DCRTPoly::Allocator(params, Format::EVALUATION);
Matrix matrix(zero_alloc, nrow, ncol);
return std::make_unique<Matrix>(std::move(matrix));
}

void SetMatrixElement(
Matrix& matrix,
size_t row,
size_t col,
const DCRTPoly& element)
{
matrix(row, col) = element.GetPoly();
}

std::unique_ptr<DCRTPoly> GetMatrixElement(
const Matrix& matrix,
size_t row,
size_t col)
{
std::shared_ptr<ILDCRTParams> params_ptr = std::make_shared<ILDCRTParams>(params);
typename DCRTPolyImpl::DugType dug;
return std::make_unique<DCRTPolyImpl>(dug, params_ptr, Format::EVALUATION);
lbcrypto::DCRTPoly copy = matrix(row, col);
return std::make_unique<DCRTPoly>(std::move(copy));
}

} // openfhe
Loading