Skip to content

Commit

Permalink
Add Cipher module
Browse files Browse the repository at this point in the history
  • Loading branch information
xevisalle committed Apr 5, 2024
1 parent 529035e commit ffb2542
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ subtle = { version = "^2.2.1", default-features = false }
rkyv = { version = "0.7", optional = true, default-features = false }
bytecheck = { version = "0.6", optional = true, default-features = false }
ff = { version = "0.13", default-features = false }
aes-gcm = "0.10"
blake3 = "1.5"

[dev-dependencies]
assert_matches = "1.3"
Expand Down
71 changes: 71 additions & 0 deletions src/cipher.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use alloc::vec::Vec;
use dusk_jubjub::JubJubAffine;
use rand_core::OsRng;

use blake3;

use aes_gcm::{
aead::{Aead, AeadCore, KeyInit},
Aes256Gcm, Nonce, Key
};

type NonceSize = <Aes256Gcm as AeadCore>::NonceSize;

/// Encrypts a plaintext given a shared DH secret key, returning the ciphertext and a 96-bit nonce
pub fn encrypt(secret_key: JubJubAffine, plaintext: Vec<u8>) -> (Vec<u8>, Nonce<NonceSize>) {
// To encrypt using AES256 we need 32-bytes keys. Thus, we hash
// the 64-bytes serialization of the DH key into a 32-bytes digest.
let key = blake3::hash(&secret_key.to_bytes());
let key = Key::<Aes256Gcm>::from_slice(key.as_bytes());

let cipher = Aes256Gcm::new(&key);
let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
let ciphertext = cipher.encrypt(&nonce, plaintext.as_ref()).expect("Encryption failed.");

(ciphertext, nonce)
}

/// Decrypts a ciphertext given a shared DH secret key and a nonce, returning the plaintext
pub fn decrypt(secret_key: JubJubAffine, nonce: Nonce<NonceSize>, ciphertext: Vec<u8>) -> Vec<u8> {
// To decrypt using AES256 we need 32-bytes keys. Thus, we hash
// the 64-bytes serialization of the DH key into a 32-bytes digest.
let key = blake3::hash(&secret_key.to_bytes());
let key = Key::<Aes256Gcm>::from_slice(key.as_bytes());

let cipher = Aes256Gcm::new(&key);
cipher.decrypt(&nonce, ciphertext.as_ref()).expect("Decryption failed.")
}

#[cfg(test)]
mod tests {
use dusk_jubjub::{GENERATOR, JubJubScalar, JubJubAffine};
use dusk_bls12_381::BlsScalar;
use dusk_bytes::DeserializableSlice;

use crate::cipher::{encrypt, decrypt};

#[test]
fn test_encrypt_and_decrypt() {
// testing values
let plaintext = b"00112233445566778899";
let plaintext_scalar = BlsScalar::from(1234u64);
let secret_key = JubJubAffine::from(GENERATOR * JubJubScalar::from(1234u64));

let (ciphertext, nonce) = encrypt(secret_key, plaintext.to_vec());
let dec_plaintext = decrypt(secret_key, nonce, ciphertext);

assert_eq!(dec_plaintext, plaintext);

let (ciphertext, nonce) = encrypt(secret_key, plaintext_scalar.to_bytes().to_vec());
let dec_plaintext_scalar = decrypt(secret_key, nonce, ciphertext);
let dec_plaintext_scalar = BlsScalar::from_slice(&dec_plaintext_scalar).unwrap();

assert_eq!(dec_plaintext_scalar, plaintext_scalar);
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ pub mod note;
/// Phoenix Core Keys & Addresses
mod keys;

/// Encryption and decryption methods
#[cfg(feature = "alloc")]
pub mod cipher;

/// Hash function
pub use keys::hash;
/// Public (Spend) Key
Expand Down

0 comments on commit ffb2542

Please sign in to comment.