Skip to content

Commit

Permalink
[refactor] hyperledger-iroha#3237: Fix clippy lints
Browse files Browse the repository at this point in the history
- make the signature implementations not use the &self, they are all stateless anyway
- remove redundant Result returns
- add docs on errors

Signed-off-by: Nikita Strygin <[email protected]>
  • Loading branch information
DCNick3 committed Nov 13, 2023
1 parent c2116a4 commit c6fcee5
Show file tree
Hide file tree
Showing 21 changed files with 321 additions and 323 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1702,7 +1702,7 @@ mod tests {
),
private_key: Some(iroha_crypto::PrivateKey::from_hex(
iroha_crypto::Algorithm::Ed25519,
"9AC47ABF59B356E0BD7DCBBBB4DEC080E302156A48CA907E47CB6AEA1D32719E7233BFC89DCBD68C19FDE6CE6158225298EC1131B6A130D1AEB454C1AB5183C0".as_ref()
"9AC47ABF59B356E0BD7DCBBBB4DEC080E302156A48CA907E47CB6AEA1D32719E7233BFC89DCBD68C19FDE6CE6158225298EC1131B6A130D1AEB454C1AB5183C0"
).expect("Private key not hex encoded")),
account_id: Some(
"alice@wonderland"
Expand Down
2 changes: 1 addition & 1 deletion config/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub mod tests {
.expect("Public key not in multihash format");
let private_key = PrivateKey::from_hex(
iroha_crypto::Algorithm::Ed25519,
"D748E18CE60CB30DEA3E73C9019B7AF45A8D465E3D71BCC9A5EF99A008205E534CFFD0EE429B1BDD36B3910EC570852B8BB63F18750341772FB46BC856C5CAAF".as_ref()
"D748E18CE60CB30DEA3E73C9019B7AF45A8D465E3D71BCC9A5EF99A008205E534CFFD0EE429B1BDD36B3910EC570852B8BB63F18750341772FB46BC856C5CAAF"
).expect("Private key not hex encoded");

KeyPair::new(public_key, private_key).expect("Key pair mismatch")
Expand Down
2 changes: 1 addition & 1 deletion config/src/iroha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ mod tests {
pub fn placeholder_keypair() -> KeyPair {
let private_key = PrivateKey::from_hex(
Algorithm::Ed25519,
"282ED9F3CF92811C3818DBC4AE594ED59DC1A2F78E4241E31924E101D6B1FB831C61FAF8FE94E253B93114240394F79A607B7FA55F9E5A41EBEC74B88055768B".as_ref()
"282ED9F3CF92811C3818DBC4AE594ED59DC1A2F78E4241E31924E101D6B1FB831C61FAF8FE94E253B93114240394F79A607B7FA55F9E5A41EBEC74B88055768B"
).expect("Private key not hex encoded");

KeyPair::new(
Expand Down
2 changes: 1 addition & 1 deletion core/test_network/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub fn get_key_pair() -> KeyPair {
.expect("Public key not in mulithash format"),
PrivateKey::from_hex(
Algorithm::Ed25519,
"9AC47ABF59B356E0BD7DCBBBB4DEC080E302156A48CA907E47CB6AEA1D32719E7233BFC89DCBD68C19FDE6CE6158225298EC1131B6A130D1AEB454C1AB5183C0".as_ref()
"9AC47ABF59B356E0BD7DCBBBB4DEC080E302156A48CA907E47CB6AEA1D32719E7233BFC89DCBD68C19FDE6CE6158225298EC1131B6A130D1AEB454C1AB5183C0"
).expect("Private key not hex encoded")
).expect("Key pair mismatch")
}
Expand Down
2 changes: 2 additions & 0 deletions crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ std = [
"dep:hkdf",
"dep:amcl",
"dep:amcl_wrapper",
"dep:signature",
"dep:ed25519-dalek",
"dep:curve25519-dalek",
"dep:x25519-dalek",
Expand Down Expand Up @@ -64,6 +65,7 @@ hkdf = { version = "0.12.3", optional = true }
amcl = { version = "0.2.0", optional = true, default-features = false, features = ["secp256k1"] }
amcl_wrapper = { version = "0.4.0", optional = true }

signature = { version = "2.1.0", optional = true }
ed25519-dalek = { version = "2.0.0", optional = true, features = ["rand_core"] }
curve25519-dalek = { version = "4.1.1", optional = true }
x25519-dalek = { version = "2.0.0", optional = true, features = ["static_secrets"] }
Expand Down
28 changes: 14 additions & 14 deletions crypto/src/encryption/chacha20poly1305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use chacha20poly1305::ChaCha20Poly1305 as SysChaCha20Poly1305;

use super::Encryptor;

/// ChaCha20Poly1305 is a symmetric encryption algorithm that uses the ChaCha20 stream cipher
/// `ChaCha20Poly1305` is a symmetric encryption algorithm that uses the `ChaCha20` stream cipher
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct ChaCha20Poly1305 {
key: GenericArray<u8, U32>,
Expand Down Expand Up @@ -67,68 +67,68 @@ mod tests {

#[test]
fn encrypt_easy_works() {
let aes = ChaCha20Poly1305::new(&ChaCha20Poly1305::key_gen().unwrap());
let cipher = ChaCha20Poly1305::new(&ChaCha20Poly1305::key_gen().unwrap());
let aad = Vec::new();
let message = b"Hello and Goodbye!".to_vec();
let res = aes.encrypt_easy(&aad, &message);
let res = cipher.encrypt_easy(&aad, &message);
assert!(res.is_ok());
let ciphertext = res.unwrap();
let res = aes.decrypt_easy(&aad, &ciphertext);
let res = cipher.decrypt_easy(&aad, &ciphertext);
assert!(res.is_ok());
assert_eq!(message, res.unwrap());
}

#[test]
fn encrypt_works() {
let aes = ChaCha20Poly1305::new(&ChaCha20Poly1305::key_gen().unwrap());
let cipher = ChaCha20Poly1305::new(&ChaCha20Poly1305::key_gen().unwrap());
let nonce = ChaCha20Poly1305::nonce_gen().unwrap();
let aad = b"encrypt test".to_vec();
let message = b"Hello and Goodbye!".to_vec();
let payload = Payload {
msg: message.as_slice(),
aad: aad.as_slice(),
};
let res = aes.encrypt(&nonce, payload);
let res = cipher.encrypt(&nonce, payload);
assert!(res.is_ok());
let ciphertext = res.unwrap();
let payload = Payload {
msg: ciphertext.as_slice(),
aad: aad.as_slice(),
};
let res = aes.decrypt(&nonce, payload);
let res = cipher.decrypt(&nonce, payload);
assert!(res.is_ok());
assert_eq!(message, res.unwrap());
}

#[test]
fn decrypt_should_fail() {
let aes = ChaCha20Poly1305::new(&ChaCha20Poly1305::key_gen().unwrap());
let cipher = ChaCha20Poly1305::new(&ChaCha20Poly1305::key_gen().unwrap());
let aad = b"decrypt should fail".to_vec();
let message = b"Hello and Goodbye!".to_vec();
let res = aes.encrypt_easy(&aad, &message);
let res = cipher.encrypt_easy(&aad, &message);
assert!(res.is_ok());
let mut ciphertext = res.unwrap();

let aad = b"decrypt should succeed".to_vec();
let res = aes.decrypt_easy(&aad, &ciphertext);
let res = cipher.decrypt_easy(&aad, &ciphertext);
assert!(res.is_err());

let aad = b"decrypt should fail".to_vec();
ciphertext[0] ^= ciphertext[1];
let res = aes.decrypt_easy(&aad, &ciphertext);
let res = cipher.decrypt_easy(&aad, &ciphertext);
assert!(res.is_err());
}

#[test]
fn buffer_works() {
let aes = ChaCha20Poly1305::new(&ChaCha20Poly1305::key_gen().unwrap());
let cipher = ChaCha20Poly1305::new(&ChaCha20Poly1305::key_gen().unwrap());
let aad = b"buffer works".to_vec();
let dummytext = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
let mut ciphertext = Vec::new();
let res = aes.encrypt_buffer(&aad, &mut Cursor::new(dummytext), &mut ciphertext);
let res = cipher.encrypt_buffer(&aad, &mut Cursor::new(dummytext), &mut ciphertext);
assert!(res.is_ok());
let mut plaintext = Vec::new();
let res = aes.decrypt_buffer(
let res = cipher.decrypt_buffer(
&aad,
&mut Cursor::new(ciphertext.as_slice()),
&mut plaintext,
Expand Down
71 changes: 61 additions & 10 deletions crypto/src/encryption/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ use crate::SessionKey;
// Helpful for generating bytes using the operating system random number generator
fn random_vec(bytes: usize) -> Result<Vec<u8>, Error> {
let mut value = vec![0u8; bytes];
OsRng.fill_bytes(value.as_mut_slice());
OsRng
.try_fill_bytes(value.as_mut_slice())
// RustCrypto errors don't have any details, can't propagate the error
.map_err(|_| Error)?;
Ok(value)
}

Expand All @@ -53,11 +56,11 @@ fn read_buffer<I: Read>(buffer: &mut I) -> Result<Vec<u8>, Error> {
/// # Usage
///
/// ```
/// extern crate ursa;
/// use ursa::encryption::symm::prelude::*;
/// use iroha_crypto::encryption::{SymmetricEncryptor, ChaCha20Poly1305};
///
/// let encryptor = SymmetricEncryptor::<Aes128Gcm>::default();
/// let aad = b"Using Aes128Gcm to encrypt data";
/// let key: Vec<u8> = (0..0x20).collect();
/// let encryptor = SymmetricEncryptor::<ChaCha20Poly1305>::new_with_key(&key);
/// let aad = b"Using ChaCha20Poly1305 to encrypt data";
/// let message = b"Hidden message";
/// let res = encryptor.encrypt_easy(aad.as_ref(), message.as_ref());
/// assert!(res.is_ok());
Expand All @@ -79,23 +82,31 @@ impl<E: Encryptor> SymmetricEncryptor<E> {
}

/// Create a new [`SymmetricEncryptor`] from a [`SessionKey`]
pub fn new_from_session_key(key: SessionKey) -> Self {
pub fn new_from_session_key(key: &SessionKey) -> Self {
Self::new(<E as KeyInit>::new(GenericArray::from_slice(&key.0)))
}
/// Create a new [`SymmetricEncryptor`] from key bytes
pub fn new_with_key<A: AsRef<[u8]>>(key: A) -> Result<Self, Error> {
Ok(Self {
pub fn new_with_key<A: AsRef<[u8]>>(key: A) -> Self {
Self {
encryptor: <E as KeyInit>::new(GenericArray::from_slice(key.as_ref())),
})
}
}

/// Encrypt `plaintext` and integrity protect `aad`. The result is the ciphertext.
/// This method handles safely generating a `nonce` and prepends it to the ciphertext
///
/// # Errors
///
/// This function will return an error if nonce generation or encryption fails
pub fn encrypt_easy<A: AsRef<[u8]>>(&self, aad: A, plaintext: A) -> Result<Vec<u8>, Error> {
self.encryptor.encrypt_easy(aad, plaintext)
}

/// Encrypt `plaintext` and integrity protect `aad`. The result is the ciphertext.
///
/// # Errors
///
/// This function will return an error if encryption fails
pub fn encrypt<A: AsRef<[u8]>>(
&self,
nonce: A,
Expand All @@ -115,6 +126,10 @@ impl<E: Encryptor> SymmetricEncryptor<E> {
/// or incorrect key.
/// `aad` must be the same value used in `encrypt_easy`. Expects the nonce to be prepended to
/// the `ciphertext`
///
/// # Errors
///
/// This function will return an error if decryption fails
pub fn decrypt_easy<A: AsRef<[u8]>>(&self, aad: A, ciphertext: A) -> Result<Vec<u8>, Error> {
self.encryptor.decrypt_easy(aad, ciphertext)
}
Expand All @@ -123,6 +138,10 @@ impl<E: Encryptor> SymmetricEncryptor<E> {
/// or an error if the `ciphetext` cannot be decrypted due to tampering, an incorrect `aad` value,
/// or incorrect key.
/// `aad` must be the same value used in `encrypt_easy`.
///
/// # Errors
///
/// This function will return an error if decryption fails
pub fn decrypt<A: AsRef<[u8]>>(
&self,
nonce: A,
Expand All @@ -138,6 +157,10 @@ impl<E: Encryptor> SymmetricEncryptor<E> {
}

/// Similar to `encrypt_easy` but reads from a stream instead of a slice
///
/// # Errors
///
/// This function will return an error if reading the buffer, nonce generation, encryption or writing the buffer fails
pub fn encrypt_buffer<A: AsRef<[u8]>, I: Read, O: Write>(
&self,
aad: A,
Expand All @@ -148,6 +171,10 @@ impl<E: Encryptor> SymmetricEncryptor<E> {
}

/// Similar to `decrypt_easy` but reads from a stream instead of a slice
///
/// # Errors
///
/// This function will return an error if reading the buffer, decryption or writing the buffer fails
pub fn decrypt_buffer<A: AsRef<[u8]>, I: Read, O: Write>(
&self,
aad: A,
Expand All @@ -174,6 +201,10 @@ pub trait Encryptor: Aead + KeyInit {
/// A simple API to encrypt a message with authenticated associated data.
///
/// This API handles nonce generation for you and prepends it in front of the ciphertext. Use [`Encryptor::decrypt_easy`] to decrypt the message encrypted this way.
///
/// # Errors
///
/// This function will return an error if nonce generation or encryption fails
fn encrypt_easy<M: AsRef<[u8]>>(&self, aad: M, plaintext: M) -> Result<Vec<u8>, Error> {
let nonce = Self::nonce_gen()?;
let payload = Payload {
Expand All @@ -189,6 +220,10 @@ pub trait Encryptor: Aead + KeyInit {
/// A simple API to decrypt a message with authenticated associated data.
///
/// This API expects the nonce to be prepended to the ciphertext. Use [`Encryptor::encrypt_easy`] to encrypt the message this way.
///
/// # Errors
///
/// This function will return an error if decryption fails
fn decrypt_easy<M: AsRef<[u8]>>(&self, aad: M, ciphertext: M) -> Result<Vec<u8>, Error> {
let ciphertext = ciphertext.as_ref();
if ciphertext.len() < Self::MinSize::to_usize() {
Expand All @@ -200,11 +235,15 @@ pub trait Encryptor: Aead + KeyInit {
msg: &ciphertext[Self::NonceSize::to_usize()..],
aad: aad.as_ref(),
};
let plaintext = self.decrypt(&nonce, payload)?;
let plaintext = self.decrypt(nonce, payload)?;
Ok(plaintext)
}

/// Same as [`Encryptor::encrypt_easy`] but works with [`std::io`] streams instead of slices
///
/// # Errors
///
/// This function will return an error if reading the buffer, nonce generation, encryption or writing the buffer fails
fn encrypt_buffer<M: AsRef<[u8]>, I: Read, O: Write>(
&self,
aad: M,
Expand All @@ -218,6 +257,10 @@ pub trait Encryptor: Aead + KeyInit {
}

/// Same as [`Encryptor::decrypt_easy`] but works with [`std::io`] streams instead of slices
///
/// # Errors
///
/// This function will return an error if reading the buffer, decryption or writing the buffer fails
fn decrypt_buffer<M: AsRef<[u8]>, I: Read, O: Write>(
&self,
aad: M,
Expand All @@ -231,11 +274,19 @@ pub trait Encryptor: Aead + KeyInit {
}

/// Generate a new key for this encryptor
///
/// # Errors
///
/// This function will return an error if the operating system random number generator fails
fn key_gen() -> Result<GenericArray<u8, Self::KeySize>, Error> {
random_bytes()
}

/// Generate a new nonce for this encryptor
///
/// # Errors
///
/// This function will return an error if the operating system random number generator fails
fn nonce_gen() -> Result<GenericArray<u8, Self::NonceSize>, Error> {
random_bytes()
}
Expand Down
12 changes: 8 additions & 4 deletions crypto/src/kex/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ pub trait KeyExchangeScheme {
fn new() -> Self;
/// Create new keypairs. If
/// `options` is None, the keys are generated ephemerally from the `OsRng`
/// `options` is UseSeed, the keys are generated ephemerally from the sha256 hash of the seed which is
/// then used to seed the ChaChaRng
/// `options` is FromPrivateKey, the corresponding public key is returned. This should be used for
/// `options` is `UseSeed`, the keys are generated ephemerally from the sha256 hash of the seed which is
/// then used to seed the `ChaChaRng`
/// `options` is `FromPrivateKey`, the corresponding public key is returned. This should be used for
/// static Diffie-Hellman and loading a long-term key.
///
/// # Errors
///
/// Returns an error if the key generation fails.
fn keypair(&self, options: Option<KeyGenOption>) -> Result<(PublicKey, PrivateKey), Error>;
/// Compute the diffie-hellman shared secret.
/// `local_private_key` is the key generated from calling `keypair` while
Expand All @@ -28,7 +32,7 @@ pub trait KeyExchangeScheme {
&self,
local_private_key: &PrivateKey,
remote_public_key: &PublicKey,
) -> Result<SessionKey, Error>;
) -> SessionKey;

/// Size of the shared secret in bytes.
const SHARED_SECRET_SIZE: usize;
Expand Down
Loading

0 comments on commit c6fcee5

Please sign in to comment.