Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of encryption and decryption #82

Merged
merged 37 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
915c69e
Initial implementation - bigint issues
emmorais May 7, 2024
912f93c
Implement divq
emmorais May 9, 2024
3d5455a
Unit tests for divq
emmorais May 9, 2024
c5e1bcc
Decryption working
emmorais May 13, 2024
7970c08
Benchmark and PR review
emmorais May 13, 2024
5845707
Update comments
emmorais May 13, 2024
2cf4f0b
Merge branch 'main' into yashe-enc-dec
teor2345 May 13, 2024
95079ce
Fix benchmarks to use new traits
teor2345 May 14, 2024
323197a
Actually run benchmarks
teor2345 May 14, 2024
b836b6d
Convert tests to trait configs
teor2345 May 14, 2024
b7f6ea6
Replace config fields with trait constants, fix imports, whitespace
teor2345 May 14, 2024
53a08e4
Split out ERROR_DELTA and KEY_DELTA
teor2345 May 14, 2024
9efb82e
Add u128 conversion convenience methods to trait
teor2345 May 14, 2024
678b4cf
Rewrite encryption to use existing u128 conversion methods and arithm…
teor2345 May 14, 2024
34b5e88
Fix missing truncations after coefficient mul
teor2345 May 14, 2024
808d422
Add a convenience method for u128 MODULUS_MINUS_ONE_DIV_TWO
teor2345 May 14, 2024
1ace9ec
Add coeffs_mut() on Poly
teor2345 May 14, 2024
109e09e
Add a Coeff to u128 convenience method
teor2345 May 14, 2024
9f48369
Re-implement u128 calculations and update tests
teor2345 May 14, 2024
27b9588
Simplify sampling code
teor2345 May 14, 2024
2900859
Track encryption and decryption in benchmark PR comments
teor2345 May 14, 2024
847206a
Use shorter benchmark name constants
teor2345 May 14, 2024
113ff8a
Update eyelid-match-ops/src/primitives/yashe.rs
emmorais May 16, 2024
d011fcd
Remove unneeded assert
emmorais May 16, 2024
68cad52
Merge branch 'main' into yashe-enc-dec
teor2345 May 16, 2024
11d4f9b
Fix T values in configs
teor2345 May 16, 2024
9848ebb
Delete unused import
teor2345 May 16, 2024
45a7428
Fix formatting
teor2345 May 16, 2024
4566620
Remove unused import, make conditional code consistent with Aurel's PR
teor2345 May 16, 2024
3d7d8b5
Reduce tiny_poly deltas to match T
teor2345 May 16, 2024
eaaf8bf
Smaller deltas
teor2345 May 17, 2024
0783a49
Smaller deltas
teor2345 May 17, 2024
4b56a20
Try zero error and zero key randomness in tiny poly tests
teor2345 May 17, 2024
b131c6e
Note that tiny parameters don't work for encryption
teor2345 May 17, 2024
dabc7de
Follow the constraints for tiny poly even if they don't work
teor2345 May 17, 2024
9426102
Try IrisBits and FullRes for encryption and decryption instead
teor2345 May 17, 2024
c0ff1e9
Fix IrisBits polynomial size to the next power of two
teor2345 May 17, 2024
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: 1 addition & 1 deletion .github/workflows/ci-bench-changes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
run: |
export RUSTFLAGS="-D warnings"
echo "Warning: benchmark timings are unreliable in CI due to virtualization"
cargo bench --features benchmark -- 'match|mul|inv|keygen' --output-format bencher | tee output.txt
cargo bench --features benchmark -- 'match|mul|inv|keygen|enc|dec' --output-format bencher | tee output.txt
echo "Warning: benchmark timings are unreliable in CI due to virtualization"

# Download previous benchmark result from the most recent `main` branch cache (if any exists).
Expand Down
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ ark-ff = "0.4.2"
ark-poly = "0.4.2"
ark-std = "0.4.0"
num-bigint = "0.4.4"
num-traits = "0.2.19"

bitvec = "1.0.1"
itertools = "0.10.5"
Expand Down
1 change: 1 addition & 0 deletions eyelid-match-ops/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ itertools.workspace = true
ark-ff.workspace = true
ark-poly.workspace = true
num-bigint.workspace = true
num-traits.workspace = true

bitvec.workspace = true

Expand Down
69 changes: 66 additions & 3 deletions eyelid-match-ops/benches/match-ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use eyelid_match_ops::{
},
primitives::{
poly::{self, test::gen::rand_poly, IrisBits, Poly, PolyConf, TestRes},
yashe::{self, Yashe},
yashe::{self, Ciphertext, Message, Yashe},
},
};

Expand Down Expand Up @@ -79,6 +79,22 @@ criterion_group! {
targets = bench_keygen
}

criterion_group! {
name = bench_encryption;
// This can be any expression that returns a `Criterion` object.
config = Criterion::default().sample_size(10);
// List encryption implementations here.
targets = bench_enc
}

criterion_group! {
name = bench_decryption;
// This can be any expression that returns a `Criterion` object.
config = Criterion::default().sample_size(10);
// List decryption implementations here.
targets = bench_dec
}

// Iris-length polynomial benchmarks.
// These benchmarks provide an upper bound for the performance of iris operations.
// They also help us decide if we need smaller or larger polynomial sizes.
Expand Down Expand Up @@ -127,6 +143,8 @@ criterion_main!(
bench_polynomial_modulus,
bench_inverse,
bench_key_generation,
bench_encryption,
bench_decryption,
bench_cyclotomic_multiplication_iris,
);

Expand Down Expand Up @@ -368,7 +386,7 @@ pub fn bench_inv(settings: &mut Criterion) {

let ctx: Yashe<TestRes> = Yashe::new();

let p = ctx.sample_gaussian(&mut rng);
let p = ctx.sample_key(&mut rng);

settings.bench_with_input(
BenchmarkId::new("Inverse poly", SMALL_RANDOM_NAME),
Expand All @@ -395,7 +413,7 @@ pub fn bench_inv_iris(settings: &mut Criterion) {

let ctx: Yashe<IrisBits> = Yashe::new();

let p = ctx.sample_gaussian(&mut rng);
let p = ctx.sample_gaussian(params.delta, &mut rng);

settings.bench_with_input(
BenchmarkId::new("Inverse full poly", SMALL_RANDOM_NAME),
Expand Down Expand Up @@ -429,6 +447,49 @@ pub fn bench_keygen(settings: &mut Criterion) {
);
}

/// Run [`Yashe::enc()`] as a Criterion benchmark with random data.
pub fn bench_enc(settings: &mut Criterion) {
// Setup parameters
let mut rng = rand::thread_rng();
let ctx: Yashe<TestRes> = Yashe::new();

let (_private_key, public_key) = ctx.keygen(&mut rng);
let m = ctx.sample_message(&mut rng);

settings.bench_with_input(
BenchmarkId::new("YASHE enc", SMALL_RANDOM_NAME),
&ctx,
|benchmark, ctx| {
// To avoid timing dropping the return value, we require it to be returned from the closure.
benchmark.iter_with_large_drop(|| -> Ciphertext<TestRes> {
ctx.encrypt(m.clone(), public_key.clone(), &mut rng)
})
},
);
}

/// Run [`Yashe::dec()`] as a Criterion benchmark with random data.
pub fn bench_dec(settings: &mut Criterion) {
// Setup parameters
let mut rng = rand::thread_rng();
let ctx: Yashe<TestRes> = Yashe::new();

let (private_key, public_key) = ctx.keygen(&mut rng);
let m = ctx.sample_message(&mut rng);
let c = ctx.encrypt(m, public_key, &mut rng);

settings.bench_with_input(
BenchmarkId::new("YASHE dec", SMALL_RANDOM_NAME),
&ctx,
|benchmark, ctx| {
// To avoid timing dropping the return value, we require it to be returned from the closure.
benchmark.iter_with_large_drop(|| -> Message<TestRes> {
ctx.decrypt(c.clone(), private_key.clone())
})
},
);
}

/// Run [`Yashe::keygen()`] as a Criterion benchmark with random data on the full number of iris bits.
#[cfg(slow_benchmarks)]
pub fn bench_keygen_iris(settings: &mut Criterion) {
Expand All @@ -453,3 +514,5 @@ pub fn bench_keygen_iris(settings: &mut Criterion) {
},
);
}

// TODO: add iris-length encryption and decryption benchmarks
12 changes: 12 additions & 0 deletions eyelid-match-ops/src/primitives/poly/modular_poly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,18 @@ impl<C: PolyConf> Poly<C> {
Self::from_coefficients_vec(coeffs.to_vec())
}

/// Returns the coefficients of `self` as a mutable slice.
/// `use ark_poly::DenseUVPolynomial` for the read-only `coeffs()` method.
///
/// After using this low-level accessor, callers must ensure the polynomial is in a canonical
/// form, by calling either:
/// - [`Poly::reduce_mod_poly()`], if the degree could have increased, or
/// - [`Poly::truncate_to_canonical_form()`], if the degree has not increased, but coefficients
/// could have been set to zero.
pub fn coeffs_mut(&mut self) -> &mut [C::Coeff] {
self.coeffs.as_mut_slice()
}

// Shadow DensePolynomial methods, so the types are all `Poly`

/// Perform a naive `O(n^2)` multiplication of `self` by `other`.
Expand Down
2 changes: 1 addition & 1 deletion eyelid-match-ops/src/primitives/poly/modular_poly/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub trait PolyConf: Copy + Clone + Debug + Eq + PartialEq {
pub struct IrisBits;

impl PolyConf for IrisBits {
const MAX_POLY_DEGREE: usize = crate::IRIS_BIT_LENGTH;
const MAX_POLY_DEGREE: usize = crate::IRIS_BIT_LENGTH.next_power_of_two();

type Coeff = Fq79;

Expand Down
2 changes: 2 additions & 0 deletions eyelid-match-ops/src/primitives/poly/modular_poly/mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl<C: PolyConf> MulAssign<C::Coeff> for Poly<C> {
for coeff in &mut self.0.coeffs {
*coeff *= rhs;
}
self.truncate_to_canonical_form();
teor2345 marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand All @@ -27,6 +28,7 @@ impl<C: PolyConf> MulAssign<C::Coeff> for &mut Poly<C> {
for coeff in &mut self.0.coeffs {
*coeff *= rhs;
}
self.truncate_to_canonical_form();
}
}

Expand Down
2 changes: 1 addition & 1 deletion eyelid-match-ops/src/primitives/poly/test/inv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn test_key_generation_and_inverse() {
let mut rng = rand::thread_rng();

let ctx: Yashe<TestRes> = Yashe::new();
let f = ctx.sample_gaussian(&mut rng);
let f = ctx.sample_key(&mut rng);

// REMARK: For our parameter choices it is very likely to find
// the inverse in the first attempt.
Expand Down
Loading
Loading