Browse Source

Adding crate_usage example and minor imorovements

Hovsep Papoyan 1 year ago
parent
commit
494c11c6ba
5 changed files with 154 additions and 7 deletions
  1. 15 6
      README.md
  2. 1 1
      build.rs
  3. 11 0
      crate_usage/Cargo.toml
  4. 16 0
      crate_usage/build.rs
  5. 111 0
      crate_usage/src/main.rs

+ 15 - 6
README.md

@@ -25,7 +25,7 @@ To use OpenFHE-rs, you'll need to install several dependencies and follow the in
 Ensure you have the following dependencies installed:
 
 * `CMake >= 3.5.1`
-* `GCC >= 11.4`
+* `G++ >= 11.4`
 * `Rust >= 1.78`
 * `Git`
 
@@ -44,14 +44,14 @@ cd openfhe-development
 2. Configure CMake
 
 ```bash
-cmake -B ${OPENFHE_BUILD:-build} -DBUILD_SHARED=ON .       
+cmake -B ./build -DBUILD_SHARED=ON .
 ```
 
 3. Build and install the C++ OpenFHE library
 
 ```bash
-make -C ${OPENFHE_BUILD:-build} -j$(nproc)
-make -C ${OPENFHE_BUILD:-build} install
+make -C ./build -j$(nproc)
+make -C ./build install
 ```
 
 4. Update the cache for the linker
@@ -85,9 +85,18 @@ fn main
 }
 ```
 
-### Template repository
+To build and run a complete working example, go to the [crate_usage](https://github.com/fairmath/openfhe-rs/tree/master/create_usage) directory
+(assuming that the OpenFHE library is already installed),
 
-Instead of doing it manually, you can start your project by forking our [template repository](https://github.com/fairmath/openfhe-rs-template/tree/main).
+1. Build the application
+```bash
+cargo build
+```
+
+2. Run
+```bash
+cargo run
+```
 
 # Custom crate installation from the source
 

+ 1 - 1
build.rs

@@ -87,5 +87,5 @@ fn main()
     println!("cargo::rustc-link-arg=-fopenmp");
     
     // necessary to avoid LD_LIBRARY_PATH
-    println!("cargo::rustc-link-arg=-Wl,-rpath=/usr/local/lib");
+    println!("cargo::rustc-link-arg=-Wl,-rpath,/usr/local/lib");
 }

+ 11 - 0
crate_usage/Cargo.toml

@@ -0,0 +1,11 @@
+[package]
+name = "polynomial_evaluation"
+version = "0.1.0"
+edition = "2021"
+description = "An example of using the OpenFHE Fully Homomorphic Encryption Library Rust package."
+license = "BSD-2-Clause"
+documentation = "https://github.com/fairmath/openfhe-rs/blob/master/README.md"
+repository = "https://github.com/fairmath/openfhe-rs"
+
+[dependencies]
+openfhe = "0.1.6"

+ 16 - 0
crate_usage/build.rs

@@ -0,0 +1,16 @@
+fn main()
+{
+    println!("cargo::rerun-if-changed=src/main.rs");
+
+    // linking openFHE
+    println!("cargo::rustc-link-arg=-L/usr/local/lib");
+    println!("cargo::rustc-link-arg=-lOPENFHEpke");
+    println!("cargo::rustc-link-arg=-lOPENFHEbinfhe");
+    println!("cargo::rustc-link-arg=-lOPENFHEcore");
+
+    // linking OpenMP
+    println!("cargo::rustc-link-arg=-fopenmp");
+
+    // necessary to avoid LD_LIBRARY_PATH
+    println!("cargo::rustc-link-arg=-Wl,-rpath,/usr/local/lib");
+}

+ 111 - 0
crate_usage/src/main.rs

@@ -0,0 +1,111 @@
+use openfhe::cxx::{CxxVector};
+use openfhe::ffi as ffi;
+
+fn main()
+{
+    use std::time::Instant;
+    println!("\n======EXAMPLE FOR EVALPOLY========\n");
+
+    let mut _cc_params_ckksrns = ffi::GenParamsCKKSRNS();
+    _cc_params_ckksrns.pin_mut().SetMultiplicativeDepth(6);
+    _cc_params_ckksrns.pin_mut().SetScalingModSize(50);
+
+    let _cc = ffi::DCRTPolyGenCryptoContextByParamsCKKSRNS(&_cc_params_ckksrns);
+    _cc.EnableByFeature(ffi::PKESchemeFeature::PKE);
+    _cc.EnableByFeature(ffi::PKESchemeFeature::KEYSWITCH);
+    _cc.EnableByFeature(ffi::PKESchemeFeature::LEVELEDSHE);
+    _cc.EnableByFeature(ffi::PKESchemeFeature::ADVANCEDSHE);
+
+    let mut _input = CxxVector::<ffi::ComplexPair>::new();
+    _input.pin_mut().push(ffi::ComplexPair{re: 0.5, im: 0.0});
+    _input.pin_mut().push(ffi::ComplexPair{re: 0.7, im: 0.0});
+    _input.pin_mut().push(ffi::ComplexPair{re: 0.9, im: 0.0});
+    _input.pin_mut().push(ffi::ComplexPair{re: 0.95, im: 0.0});
+    _input.pin_mut().push(ffi::ComplexPair{re: 0.93, im: 0.0});
+    let _encoded_length = _input.len();
+
+    let mut _coefficients_1 = CxxVector::<f64>::new();
+    _coefficients_1.pin_mut().push(0.15);
+    _coefficients_1.pin_mut().push(0.75);
+    _coefficients_1.pin_mut().push(0.0);
+    _coefficients_1.pin_mut().push(1.25);
+    _coefficients_1.pin_mut().push(0.0);
+    _coefficients_1.pin_mut().push(0.0);
+    _coefficients_1.pin_mut().push(1.0);
+    _coefficients_1.pin_mut().push(0.0);
+    _coefficients_1.pin_mut().push(1.0);
+    _coefficients_1.pin_mut().push(2.0);
+    _coefficients_1.pin_mut().push(0.0);
+    _coefficients_1.pin_mut().push(1.0);
+    _coefficients_1.pin_mut().push(0.0);
+    _coefficients_1.pin_mut().push(0.0);
+    _coefficients_1.pin_mut().push(0.0);
+    _coefficients_1.pin_mut().push(0.0);
+    _coefficients_1.pin_mut().push(1.0);
+
+    let mut _coefficients_2 = CxxVector::<f64>::new();
+    _coefficients_2.pin_mut().push(1.0);
+    _coefficients_2.pin_mut().push(2.0);
+    _coefficients_2.pin_mut().push(3.0);
+    _coefficients_2.pin_mut().push(4.0);
+    _coefficients_2.pin_mut().push(5.0);
+    _coefficients_2.pin_mut().push(-1.0);
+    _coefficients_2.pin_mut().push(-2.0);
+    _coefficients_2.pin_mut().push(-3.0);
+    _coefficients_2.pin_mut().push(-4.0);
+    _coefficients_2.pin_mut().push(-5.0);
+    _coefficients_2.pin_mut().push(0.1);
+    _coefficients_2.pin_mut().push(0.2);
+    _coefficients_2.pin_mut().push(0.3);
+    _coefficients_2.pin_mut().push(0.4);
+    _coefficients_2.pin_mut().push(0.5);
+    _coefficients_2.pin_mut().push(-0.1);
+    _coefficients_2.pin_mut().push(-0.2);
+    _coefficients_2.pin_mut().push(-0.3);
+    _coefficients_2.pin_mut().push(-0.4);
+    _coefficients_2.pin_mut().push(-0.5);
+    _coefficients_2.pin_mut().push(0.1);
+    _coefficients_2.pin_mut().push(0.2);
+    _coefficients_2.pin_mut().push(0.3);
+    _coefficients_2.pin_mut().push(0.4);
+    _coefficients_2.pin_mut().push(0.5);
+    _coefficients_2.pin_mut().push(-0.1);
+    _coefficients_2.pin_mut().push(-0.2);
+    _coefficients_2.pin_mut().push(-0.3);
+    _coefficients_2.pin_mut().push(-0.4);
+    _coefficients_2.pin_mut().push(-0.5);
+
+    let _dcrt_poly_params = ffi::DCRTPolyGenNullParams();
+    let _plain_text_1 = _cc.MakeCKKSPackedPlaintextByVectorOfComplex(&_input, 1, 0, &_dcrt_poly_params, 0);
+    let _key_pair = _cc.KeyGen();
+    print!("Generating evaluation key for homomorphic multiplication...");
+    _cc.EvalMultKeyGen(&_key_pair.GetPrivateKey());
+    println!("Completed.\n");
+    let mut _cipher_text_1 = _cc.EncryptByPublicKey(&_key_pair.GetPublicKey(), &_plain_text_1);
+
+    let mut _start = Instant::now();
+    let _result = _cc.EvalPoly(&_cipher_text_1, &_coefficients_1);
+    let _time_eval_poly_1 = _start.elapsed();
+
+    _start = Instant::now();
+    let _result_2 = _cc.EvalPoly(&_cipher_text_1, &_coefficients_2);
+    let _time_eval_poly_2 = _start.elapsed();
+
+    let mut _plain_text_dec = ffi::GenNullPlainText();
+    _cc.DecryptByPrivateKeyAndCiphertext(&_key_pair.GetPrivateKey(), &_result, _plain_text_dec.pin_mut());
+    _plain_text_dec.SetLength(_encoded_length);
+    let mut _plain_text_dec_2 = ffi::GenNullPlainText();
+    _cc.DecryptByPrivateKeyAndCiphertext(&_key_pair.GetPrivateKey(), &_result_2, _plain_text_dec_2.pin_mut());
+    _plain_text_dec_2.SetLength(_encoded_length);
+
+    println!("\n Original Plaintext #1:");
+    println!("{}", _plain_text_1.GetString());
+    println!("\n Result of evaluating a polynomial with coefficients [{} ]", _coefficients_1.iter().fold(String::new(), |acc, &arg| acc + " " + &arg.to_string()));
+    println!("{}", _plain_text_dec.GetString());
+    println!("\n Expected result: (0.70519107, 1.38285078, 3.97211180, 5.60215665, 4.86357575)");
+    println!("\n Evaluation time: {:.0?}", _time_eval_poly_1);
+    println!("\n Result of evaluating a polynomial with coefficients [{} ]", _coefficients_2.iter().fold(String::new(), |acc, &arg| acc + " " + &arg.to_string()));
+    println!("{}\n", _plain_text_dec_2.GetString());
+    println!(" Expected result: (3.4515092326, 5.3752765397, 4.8993108833, 3.2495023573, 4.0485229982)");
+    print!("\n Evaluation time: {:.0?}\n", _time_eval_poly_2);
+}