Skip to content

Commit

Permalink
More tests and Empty checks
Browse files Browse the repository at this point in the history
  • Loading branch information
zanderlewis committed Jan 8, 2025
1 parent bcb527a commit d3e4498
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 4 deletions.
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "daily"
assignees:
- "zanderlewis"
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Changelog
All notable changes to this project will be documented in this file.

## [v0.1.0] - 1/6/2025
- Inital Release for v2

## [v0.1.1] - 1/8/2025
- Added more tests
- Added bounds checking (for empty data/salts/passwords/keypairs)
- Added Dependabot for automatic updates/security checks
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "laqf2"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
authors = ["Zander Lewis <zander@zanderlewis.dev>"]
description = "v2 of the LAQ-Fort Encryption Scheme"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ It is also the second version of the LAQ-Fort (Lattice Authenticated Quantum For
## Methods
- `new()`: Create a new Laqf2 instance.
- `generate_salt() -> Vec<u8>`: Generate a random salt.
- `generate_kyber_keypair()`: Generate a Kyber keypair.
- `generate_kyber_keypair() -> (PublicKey, SecretKey)`: Generate a Kyber keypair.
- `encrypt(data: &[u8], password: &str, pk: &PublicKey, salt: &[u8]) -> Vec<u8>`: Encrypt data using Kyber and AES-GCM.
- `decrypt(encrypted_data: &[u8], password: &str, sk: &SecretKey, salt: &[u8]) -> Vec<u8>`: Decrypt data using Kyber and AES-GCM.

Expand Down
43 changes: 41 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ struct MandelbrotPoint {
## Methods
- `new()`: Create a new Laqf2 instance.
- `generate_salt()`: Generate a salt.
- `generate_kyber_keypair()`: Generate a Kyber keypair.
- `generate_salt() -> Vec<u8>`: Generate a salt.
- `generate_kyber_keypair() -> (PublicKey, SecretKey)`: Generate a Kyber keypair.
- `encrypt(data: &[u8], password: &str, pk: &PublicKey, salt: &[u8]) -> Vec<u8>`: Encrypt data using Kyber and AES-GCM.
- `decrypt(encrypted_data: &[u8], password: &str, sk: &SecretKey, salt: &[u8]) -> Vec<u8>`: Decrypt data using Kyber and AES-GCM.
Expand Down Expand Up @@ -216,8 +216,44 @@ impl Laqf2 {
data
}

fn check_key(&self, pk: Option<&PublicKey>, sk: Option<&SecretKey>) {
match (pk, sk) {
(Some(_), Some(_)) => {
// Do nothing
}
(None, Some(sk)) => {
if sk.is_empty() {
panic!("Secret key is empty.");
}
}
(Some(pk), None) => {
if pk.is_empty() {
panic!("Public key is empty.");
}
}
(None, None) => {
panic!("Both keys are missing.");
}
}
}

fn check_bounds(&self, data: &[u8], password: &str, salt: &[u8]) {
if data.is_empty() {
panic!("Data is empty.");
}
if password.is_empty() {
panic!("Password is empty.");
}
if salt.is_empty() {
panic!("Salt is empty.");
}
}

/// Encrypt using Laqf2 hybrid encryption scheme.
pub fn encrypt(&self, data: &[u8], password: &str, pk: &PublicKey, salt: &[u8]) -> Vec<u8> {
self.check_bounds(data, password, salt);
self.check_key(Some(pk), None);

let aes_key = self.derive_aes_key(password, salt);
let nonce = self.generate_nonce();

Expand Down Expand Up @@ -261,6 +297,9 @@ impl Laqf2 {
sk: &SecretKey,
salt: &[u8],
) -> Vec<u8> {
self.check_bounds(encrypted_data, password, salt);
self.check_key(None, Some(sk));

let aes_key = self.derive_aes_key(password, salt);

// Ensure the encrypted_data has at least the minimum required length
Expand Down
123 changes: 123 additions & 0 deletions tests/lib_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,126 @@ fn test_wrong_data() {

assert!(result.is_err());
}

#[test]
fn test_empty_data() {
let result = std::panic::catch_unwind(|| {
let laqf = Laqf2::new();
let (pk, sk) = laqf.generate_kyber_keypair();

let data = b"";
let password = "password";
let salt = laqf.generate_salt();

let encrypted_data = laqf.encrypt(data, password, &pk, &salt);
let decrypted_data = laqf.decrypt(&encrypted_data, password, &sk, &salt);

// Should be the same
assert_eq!(data, decrypted_data.as_slice());
});

assert!(result.is_err());
}

#[test]
fn test_empty_password() {
let result = std::panic::catch_unwind(|| {
let laqf = Laqf2::new();
let (pk, sk) = laqf.generate_kyber_keypair();

let data = b"Hello, world!";
let password = "";
let salt = laqf.generate_salt();

let encrypted_data = laqf.encrypt(data, password, &pk, &salt);
let decrypted_data = laqf.decrypt(&encrypted_data, password, &sk, &salt);

// Should be the same
assert_eq!(data, decrypted_data.as_slice());
});

assert!(result.is_err());
}

#[test]
fn test_empty_salt() {
let result = std::panic::catch_unwind(|| {
let laqf = Laqf2::new();
let (pk, sk) = laqf.generate_kyber_keypair();

let data = b"Hello, world!";
let password = "password";
let salt = vec![];

let encrypted_data = laqf.encrypt(data, password, &pk, &salt);
let decrypted_data = laqf.decrypt(&encrypted_data, password, &sk, &salt);

// Should be the same
assert_eq!(data, decrypted_data.as_slice());
});

assert!(result.is_err());
}

#[test]
fn test_empty_keypair() {
let result = std::panic::catch_unwind(|| {
let laqf = Laqf2::new();
let empty_pk = [0u8; 1568];
let empty_sk = [0u8; 3168];

let data = b"Hello, world!";
let password = "password";
let salt = laqf.generate_salt();

let encrypted_data = laqf.encrypt(data, password, &empty_pk, &salt);
let decrypted_data = laqf.decrypt(&encrypted_data, password, &empty_sk, &salt);

// Should not be the same
assert_ne!(data, decrypted_data.as_slice());
});

assert!(result.is_err());
}

#[test]
fn test_empty_pubkey() {
let result = std::panic::catch_unwind(|| {
let laqf = Laqf2::new();
let (_, sk) = laqf.generate_kyber_keypair();
let empty_pk = [0u8; 1568];

let data = b"Hello, world!";
let password = "password";
let salt = laqf.generate_salt();

let encrypted_data = laqf.encrypt(data, password, &empty_pk, &salt);
let decrypted_data = laqf.decrypt(&encrypted_data, password, &sk, &salt);

// Should not be the same
assert_ne!(data, decrypted_data.as_slice());
});

assert!(result.is_err());
}

#[test]
fn test_empty_privkey() {
let result = std::panic::catch_unwind(|| {
let laqf = Laqf2::new();
let (pk, _) = laqf.generate_kyber_keypair();
let empty_sk = [0u8; 3168];

let data = b"Hello, world!";
let password = "password";
let salt = laqf.generate_salt();

let encrypted_data = laqf.encrypt(data, password, &pk, &salt);
let decrypted_data = laqf.decrypt(&encrypted_data, password, &empty_sk, &salt);

// Should not be the same
assert_ne!(data, decrypted_data.as_slice());
});

assert!(result.is_err());
}

0 comments on commit d3e4498

Please sign in to comment.