Skip to content

Commit

Permalink
completed refactor and bench updates
Browse files Browse the repository at this point in the history
  • Loading branch information
Dr. Capybara committed Oct 17, 2023
1 parent 851a13f commit 1f2562b
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 242 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ Add the following line to your `Cargo.toml` file:
capycrypt = "0.3.1"
```

### Note: Building the `rug` Crate

This library uses an FFI to GMP by means of the rug crate. To successfully build the `rug` crate, please ensure that you have the `m4` library installed on your system. `m4` is a prerequisite for certain components of the build process. You can install it on debian-like systems with:
```bash
apt-get install m4
```

## Benches
This library uses the criterion crate for benches. Running:
```bash
Expand Down
65 changes: 33 additions & 32 deletions benches/benchmark_e222_256.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,62 @@
use capycrypt::curves::{
ArbitraryPoint, EdCurvePoint,
EdCurves::{self, E222},
use capycrypt::{
curves::EdCurves::{self, E222},
KeyEncryptable, KeyPair, Message, PwEncryptable, Signable,
};
use capycrypt::ops::Message;

use capycrypt::sha3::aux_functions::byte_utils::get_random_bytes;
use criterion::{criterion_group, criterion_main, Criterion};
use std::borrow::BorrowMut;

const SELECTED_CURVE: EdCurves = E222;

/// Symmetric encrypt and decrypt roundtrip
fn sym_enc(pw: &mut Vec<u8>, mut message: Message) {
let mut cg2 = Box::new(encrypt_with_pw(&mut pw.clone(), &mut message, 256));
decrypt_with_pw(&mut pw.clone(), &mut cg2.borrow_mut(), 256);
fn sym_enc(pw: &mut Vec<u8>, mut msg: Message) {
msg.pw_encrypt(&mut pw.clone(), 256);
msg.pw_decrypt(&mut pw.clone(), 256);
}

/// Asymmetric encrypt and decrypt roundtrip + keygen
fn key_gen_enc_dec(pw: &mut Vec<u8>, mut message: Box<Vec<u8>>) {
let owner = "test key".to_string();
let key_obj = gen_keypair(&mut pw.clone(), owner, 256);
let x = key_obj.pub_x;
let y = key_obj.pub_y;
let pub_key = EdCurvePoint::arbitrary_point(SELECTED_CURVE, x, y);
let mut enc = encrypt_with_key(pub_key, &mut message, 256);
decrypt_with_key(&mut pw.clone(), enc.borrow_mut(), 256);
fn key_gen_enc_dec(pw: &mut Vec<u8>, mut msg: Message) {
let key_pair = KeyPair::new(pw, "test key".to_string(), SELECTED_CURVE, 256);
msg.key_encrypt(&key_pair.pub_key, 256);
msg.key_decrypt(&key_pair.priv_key, 256);
}

/// Signature generation + verification roundtrip
pub fn sign_verify(pw: &mut Vec<u8>, mut message: Box<Vec<u8>>) {
let key_obj = gen_keypair(&mut pw.clone(), "test".to_string(), 256);
let x = key_obj.pub_x;
let y = key_obj.pub_y;
let key = EdCurvePoint::arbitrary_point(SELECTED_CURVE, x, y);
let sig = sign_with_key(&mut pw.clone(), &mut message, 256);
verify_signature(&sig, key, &mut message, 256);
pub fn sign_verify(mut key_pair: KeyPair, mut msg: Message) {
msg.sign(&mut key_pair.priv_key, 512);
msg.verify(key_pair.pub_key, 512);
}

fn bench_sign_verify(c: &mut Criterion) {
let pw = get_random_bytes(16);
let message = Box::new(get_random_bytes(5242880).to_owned());
c.bench_function("Signature Generation + Verification Roundtrip", |b| {
b.iter(|| sign_verify(&mut pw.clone(), message.clone()))
b.iter(|| {
sign_verify(
KeyPair::new(&get_random_bytes(16), "test key".to_string(), SELECTED_CURVE, 512),
Message::new(&mut get_random_bytes(5242880)),
)
});
});
}

fn bench_sym_enc(c: &mut Criterion) {
let pw = get_random_bytes(16);
let message = Box::new(get_random_bytes(5242880).to_owned());
c.bench_function("Symmetric Encrypt + Decrypt Roundtrip", |b| {
b.iter(|| sym_enc(&mut pw.clone(), message.clone()))
b.iter(|| {
sym_enc(
&mut get_random_bytes(64),
Message::new(&mut get_random_bytes(5242880)),
)
});
});
}

fn bench_key_gen_enc_dec(c: &mut Criterion) {
let pw = get_random_bytes(16);
let message = Box::new(get_random_bytes(5242880).to_owned());
c.bench_function("Keygen + Asymmetric Encrypt + Decrypt Roundtrip", |b| {
b.iter(|| key_gen_enc_dec(&mut pw.clone(), message.clone()))
b.iter(|| {
key_gen_enc_dec(
&mut KeyPair::new(&get_random_bytes(32), "test key".to_string(), SELECTED_CURVE, 256).priv_key,
Message::new(&mut get_random_bytes(5242880)),
)
});
});
}

Expand Down
68 changes: 33 additions & 35 deletions benches/benchmark_e521_512.rs
Original file line number Diff line number Diff line change
@@ -1,64 +1,62 @@
use capycrypt::curves::{
ArbitraryPoint, EdCurvePoint,
EdCurves::{self, E521},
};
use capycrypt::ops::{
decrypt_with_key, decrypt_with_pw, encrypt_with_key, encrypt_with_pw, gen_keypair,
sign_with_key, verify_signature,
use capycrypt::{
curves::EdCurves::{self, E521},
KeyEncryptable, KeyPair, Message, PwEncryptable, Signable,
};

use capycrypt::sha3::aux_functions::byte_utils::get_random_bytes;
use criterion::{criterion_group, criterion_main, Criterion};
use std::borrow::BorrowMut;

const SELECTED_CURVE: EdCurves = E521;

/// Symmetric encrypt and decrypt roundtrip
fn sym_enc(pw: &mut Vec<u8>, mut message: Box<Vec<u8>>) {
let mut cg2 = Box::new(encrypt_with_pw(&mut pw.clone(), &mut message, 512));
decrypt_with_pw(&mut pw.clone(), &mut cg2.borrow_mut(), 512);
fn sym_enc(pw: &mut Vec<u8>, mut msg: Message) {
msg.pw_encrypt(&mut pw.clone(), 512);
msg.pw_decrypt(&mut pw.clone(), 512);
}

/// Asymmetric encrypt and decrypt roundtrip + keygen
fn key_gen_enc_dec(pw: &mut Vec<u8>, mut message: Box<Vec<u8>>) {
let owner = "test key".to_string();
let key_obj = gen_keypair(&mut pw.clone(), owner, 512);
let x = key_obj.pub_x;
let y = key_obj.pub_y;
let pub_key = EdCurvePoint::arbitrary_point(SELECTED_CURVE, x, y);
let mut enc = encrypt_with_key(pub_key, &mut message, 512);
decrypt_with_key(&mut pw.clone(), enc.borrow_mut(), 512);
fn key_gen_enc_dec(pw: &mut Vec<u8>, mut msg: Message) {
let key_pair = KeyPair::new(pw, "test key".to_string(), SELECTED_CURVE, 512);
msg.key_encrypt(&key_pair.pub_key, 512);
msg.key_decrypt(&key_pair.priv_key, 512);
}

/// Signature generation + verification roundtrip
pub fn sign_verify(pw: &mut Vec<u8>, mut message: Box<Vec<u8>>) {
let key_obj = gen_keypair(&mut pw.clone(), "test".to_string(), 512);
let x = key_obj.pub_x;
let y = key_obj.pub_y;
let key = EdCurvePoint::arbitrary_point(SELECTED_CURVE, x, y);
let sig = sign_with_key(&mut pw.clone(), &mut message, 512);
verify_signature(&sig, key, &mut message, 512);
pub fn sign_verify(mut key_pair: KeyPair, mut msg: Message) {
msg.sign(&mut key_pair.priv_key, 512);
msg.verify(key_pair.pub_key, 512);
}

fn bench_sign_verify(c: &mut Criterion) {
let pw = get_random_bytes(16);
let message = Box::new(get_random_bytes(5242880).to_owned());
c.bench_function("Signature Generation + Verification Roundtrip", |b| {
b.iter(|| sign_verify(&mut pw.clone(), message.clone()))
b.iter(|| {
sign_verify(
KeyPair::new(&get_random_bytes(16), "test key".to_string(), SELECTED_CURVE, 512),
Message::new(&mut get_random_bytes(5242880)),
)
});
});
}

fn bench_sym_enc(c: &mut Criterion) {
let pw = get_random_bytes(16);
let message = Box::new(get_random_bytes(5242880).to_owned());
c.bench_function("Symmetric Encrypt + Decrypt Roundtrip", |b| {
b.iter(|| sym_enc(&mut pw.clone(), message.clone()))
b.iter(|| {
sym_enc(
&mut get_random_bytes(64),
Message::new(&mut get_random_bytes(5242880)),
)
});
});
}

fn bench_key_gen_enc_dec(c: &mut Criterion) {
let pw = get_random_bytes(16);
let message = Box::new(get_random_bytes(5242880).to_owned());
c.bench_function("Keygen + Asymmetric Encrypt + Decrypt Roundtrip", |b| {
b.iter(|| key_gen_enc_dec(&mut pw.clone(), message.clone()))
b.iter(|| {
key_gen_enc_dec(
&mut KeyPair::new(&get_random_bytes(32), "test key".to_string(), SELECTED_CURVE, 512).priv_key,
Message::new(&mut get_random_bytes(5242880)),
)
});
});
}

Expand Down
39 changes: 7 additions & 32 deletions src/curves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,6 @@ pub trait Generator {
fn generator(curve: EdCurves, msb: bool) -> EdCurvePoint;
}

/// Specifies the function for producing a coordinate pair.
/// Does not check that point is on curve.
pub trait ArbitraryPoint {
fn arbitrary_point(curve: EdCurves, x: rug::Integer, y: rug::Integer) -> EdCurvePoint;
}

/// Specifies the function for verifying that a point is on the curve.
pub trait IsPoint {
fn is_point(&self) -> bool;
Expand All @@ -102,7 +96,7 @@ impl Add<&EdCurvePoint> for EdCurvePoint {
/// excessive cloning in this function is a consequence of the
/// Rug Integer GMP FFI which does not implement ```copy``` trait. Observed complexity
/// impact appears minimal.
fn add(self, p2: &EdCurvePoint) -> EdCurvePoint {
fn add(mut self, p2: &EdCurvePoint) -> EdCurvePoint {
let x1 = &self.x;
let y1 = &self.y;
let x2 = p2.x.clone();
Expand Down Expand Up @@ -130,7 +124,9 @@ impl Add<&EdCurvePoint> for EdCurvePoint {
let new_x = ((x1y2y1x2_sum * one_plus_dx1x2y1y2inv) % p.clone() + p.clone()) % p.clone();
// (y₁y₂ − x₁x₂) / (1 − dx₁x₂y₁y₂)
let new_y = ((y1y2x1x2_difference * one_minus_dx1x2y1y2inv) % p.clone() + p.clone()) % p;
EdCurvePoint::arbitrary_point(self.curve, new_x, new_y)
self.x = new_x;
self.y = new_y;
self
}
}

Expand Down Expand Up @@ -233,8 +229,9 @@ impl Mul<Integer> for EdCurvePoint {
/// If a point is defined as (x, y) then its negation is (-x, y)
impl Neg for EdCurvePoint {
type Output = EdCurvePoint;
fn neg(self) -> EdCurvePoint {
EdCurvePoint::arbitrary_point(self.curve, self.p - self.x, self.y)
fn neg(mut self) -> EdCurvePoint {
self.x = self.p.clone() - self.x.clone();
self
}
}

Expand All @@ -245,28 +242,6 @@ impl PartialEq for EdCurvePoint {
}
}

/// Returns CurvePoint(x, y) for any x, y. Assumes valid curve point.
///
/// # Arguments
///
/// * `x: rug::Integer` x-coordinate for point.
/// * `y: rug::Integer` y-coordinate for point.
///
/// # Examples
impl ArbitraryPoint for EdCurvePoint {
fn arbitrary_point(req_curve: EdCurves, x: Integer, y: Integer) -> EdCurvePoint {
EdCurvePoint {
x,
y,
p: curve_p(req_curve),
d: curve_d(req_curve),
r: curve_r(req_curve),
n: order(req_curve),
curve: req_curve,
}
}
}

/// Performs modular inverse via euclidian algorithm.
/// * `n`: Integer value to mod
/// * `p`: modulus
Expand Down
48 changes: 47 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use curves::EdCurvePoint;
use curves::{EdCurvePoint, EdCurves};
use rug::Integer;

/*
Expand Down Expand Up @@ -50,4 +50,50 @@ pub struct KeyPair {
pub priv_key: Vec<u8>,
/// Date key was generated
pub date_created: String,
/// Selected curve type
pub curve: EdCurves
}

impl Message {
pub fn new(data: &mut Vec<u8>) -> Message {
Message {
msg: Box::new(data.to_owned()),
sym_nonce: None,
asym_nonce: None,
digest: None,
op_result: None,
sig: None,
}
}
}

#[derive(Debug)]
/// Message type for which cryptographic traits are defined.
pub struct Message {
pub msg: Box<Vec<u8>>,
pub sym_nonce: Option<Vec<u8>>,
pub asym_nonce: Option<EdCurvePoint>,
pub digest: Option<Vec<u8>>,
pub op_result: Option<bool>,
pub sig: Option<Signature>,
}

pub trait Hashable {
fn compute_sha3_hash(&mut self, d: u64);
fn compute_tagged_hash(&mut self, pw: &mut Vec<u8>, s: &str, d: u64);
}

pub trait PwEncryptable {
fn pw_encrypt(&mut self, pw: &[u8], d: u64);
fn pw_decrypt(&mut self, pw: &[u8], d: u64);
}

pub trait KeyEncryptable {
fn key_encrypt(&mut self, pub_key: &EdCurvePoint, d: u64);
fn key_decrypt(&mut self, pw: &[u8], d: u64);
}

pub trait Signable {
fn sign(&mut self, pw: &mut Vec<u8>, d: u64);
fn verify(&mut self, pub_key: EdCurvePoint, d: u64);
}
Loading

0 comments on commit 1f2562b

Please sign in to comment.