Skip to content

Commit f7c6964

Browse files
committed
Merge branch 'master' into ao-are-you-ready-for-a-good-mul
* master: Bump fixed-hash to 0.3.2 (#134) Use EntropyRng instead of OsRng (#130) Bump parity-crypto to 0.3.1 (#132) rust-crypto dependency removal (#85) Use newly stablized TryFrom trait for primitive-types (#127)
2 parents e0c50c8 + ecdc90c commit f7c6964

File tree

15 files changed

+464
-121
lines changed

15 files changed

+464
-121
lines changed

fixed-hash/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "fixed-hash"
3-
version = "0.3.1"
3+
version = "0.3.2"
44
authors = ["Parity Technologies <[email protected]>"]
55
license = "MIT"
66
homepage = "https://github.com/paritytech/parity-common"

fixed-hash/src/hash.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ macro_rules! impl_rand_for_fixed_hash {
513513

514514
/// Assign `self` to a cryptographically random value.
515515
pub fn randomize(&mut self) {
516-
let mut rng = $crate::rand::OsRng::new().unwrap();
516+
let mut rng = $crate::rand::rngs::EntropyRng::new();
517517
self.randomize_using(&mut rng);
518518
}
519519

parity-crypto/Cargo.toml

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,28 @@
11
[package]
22
name = "parity-crypto"
3-
version = "0.3.0"
3+
version = "0.3.1"
44
authors = ["Parity Technologies <[email protected]>"]
55
repository = "https://github.com/paritytech/parity-common"
66
description = "Crypto utils used by ethstore and network."
77
license = "GPL-3.0"
8+
autobenches = false
9+
10+
[[bench]]
11+
name = "bench"
12+
harness = false
13+
814

915
[dependencies]
1016
quick-error = "1.2.2"
11-
ring = "0.14.3"
12-
rust-crypto = "0.2.36"
1317
tiny-keccak = "1.4"
18+
scrypt = { version = "0.1.1", default-features = false }
19+
ripemd160 = "0.8.0"
20+
sha2 = "0.8.0"
21+
digest = "0.8"
22+
aes = "0.3.2"
23+
aes-ctr = "0.3.0"
24+
block-modes = "0.3.3"
25+
ring = "0.14.6"
26+
27+
[dev-dependencies]
28+
criterion = "0.2"

parity-crypto/benches/bench.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
2+
// This file is part of Parity.
3+
4+
// Parity is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// Parity is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
16+
17+
18+
extern crate parity_crypto;
19+
20+
#[macro_use]
21+
extern crate criterion;
22+
23+
use criterion::{Criterion, Bencher};
24+
25+
criterion_group!(benches, input_len);
26+
27+
criterion_main!(benches);
28+
29+
/// general benches for multiple input size
30+
fn input_len(c: &mut Criterion) {
31+
32+
c.bench_function_over_inputs("ripemd",
33+
|b: &mut Bencher, size: &usize| {
34+
let data = vec![0u8; *size];
35+
b.iter(|| parity_crypto::digest::ripemd160(&data[..]));
36+
},
37+
vec![100, 500, 1_000, 10_000, 100_000]
38+
);
39+
40+
c.bench_function_over_inputs("aes_ctr",
41+
|b: &mut Bencher, size: &usize| {
42+
let data = vec![0u8; *size];
43+
let mut dest = vec![0; *size];
44+
let k = [0; 16];
45+
let iv = [0; 16];
46+
47+
b.iter(||{
48+
parity_crypto::aes::encrypt_128_ctr(&k[..], &iv[..], &data[..], &mut dest[..]).unwrap();
49+
// same as encrypt but add it just in case
50+
parity_crypto::aes::decrypt_128_ctr(&k[..], &iv[..], &data[..], &mut dest[..]).unwrap();
51+
});
52+
},
53+
vec![100, 500, 1_000, 10_000, 100_000]
54+
);
55+
56+
}

parity-crypto/src/aes.rs

Lines changed: 168 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,195 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
1616

17+
use block_modes::{BlockMode};
18+
use block_modes::block_padding::Pkcs7;
19+
use block_modes::block_padding::ZeroPadding;
20+
use block_modes::{ Cbc, Ecb };
21+
use raes::{ Aes128, Aes256 };
22+
use aes_ctr::{ Aes128Ctr, Aes256Ctr };
23+
use aes_ctr::stream_cipher::{ NewStreamCipher, SyncStreamCipher };
1724
use error::SymmError;
18-
use rcrypto::blockmodes::{CtrMode, CbcDecryptor, PkcsPadding};
19-
use rcrypto::aessafe::{AesSafe128Encryptor, AesSafe128Decryptor};
20-
use rcrypto::symmetriccipher::{Encryptor, Decryptor};
21-
use rcrypto::buffer::{RefReadBuffer, RefWriteBuffer, WriteBuffer};
25+
use raes::block_cipher_trait::generic_array::GenericArray;
26+
27+
28+
/// One time encoder/decoder for Ecb mode Aes256 with zero padding
29+
pub struct AesEcb256(Ecb<Aes256, ZeroPadding>);
30+
31+
impl AesEcb256 {
32+
33+
/// New encoder/decoder, no iv for ecb
34+
pub fn new(key: &[u8]) -> Result<Self, SymmError> {
35+
Ok(AesEcb256(Ecb::new_var(key, &[])?))
36+
}
37+
38+
/// Encrypt data in place without padding. The data length must be a multiple
39+
/// of the block size.
40+
pub fn encrypt(self, content: &mut [u8]) -> Result<(), SymmError> {
41+
let len = content.len();
42+
self.0.encrypt(content, len)?;
43+
Ok(())
44+
}
45+
46+
/// Decrypt data in place without padding. The data length must be a multiple
47+
/// of the block size.
48+
pub fn decrypt(self, content: &mut [u8]) -> Result<(), SymmError> {
49+
self.0.decrypt(content)?;
50+
Ok(())
51+
}
52+
}
53+
54+
55+
/// Reusable encoder/decoder for Aes256 in Ctr mode and no padding
56+
pub struct AesCtr256(Aes256Ctr);
57+
58+
impl AesCtr256 {
59+
60+
/// New encoder/decoder
61+
pub fn new(key: &[u8], iv: &[u8]) -> Result<Self, SymmError> {
62+
Ok(AesCtr256(
63+
Aes256Ctr::new(GenericArray::from_slice(key), GenericArray::from_slice(iv))
64+
))
65+
}
66+
67+
/// In place encrypt a content without padding, the content length must be a multiple
68+
/// of the block size.
69+
pub fn encrypt(&mut self, content: &mut[u8]) -> Result<(), SymmError> {
70+
self.0.try_apply_keystream(content)?;
71+
Ok(())
72+
}
73+
74+
/// In place decrypt a content without padding, the content length must be a multiple
75+
/// of the block size.
76+
pub fn decrypt(&mut self, content: &mut[u8]) -> Result<(), SymmError> {
77+
self.0.try_apply_keystream(content)?;
78+
Ok(())
79+
}
80+
}
2281

2382
/// Encrypt a message (CTR mode).
2483
///
2584
/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each.
2685
/// An error is returned if the input lengths are invalid.
86+
/// If possible prefer `inplace_encrypt_128_ctr` to avoid a slice copy.
2787
pub fn encrypt_128_ctr(k: &[u8], iv: &[u8], plain: &[u8], dest: &mut [u8]) -> Result<(), SymmError> {
28-
let mut encryptor = CtrMode::new(AesSafe128Encryptor::new(k), iv.to_vec());
29-
encryptor.encrypt(&mut RefReadBuffer::new(plain), &mut RefWriteBuffer::new(dest), true)?;
88+
let mut encryptor = Aes128Ctr::new(
89+
GenericArray::from_slice(k),
90+
GenericArray::from_slice(iv),
91+
);
92+
&mut dest[..plain.len()].copy_from_slice(plain);
93+
encryptor.try_apply_keystream(dest)?;
3094
Ok(())
95+
96+
}
97+
98+
/// Encrypt a message (CTR mode).
99+
///
100+
/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each.
101+
/// An error is returned if the input lengths are invalid.
102+
pub fn inplace_encrypt_128_ctr(k: &[u8], iv: &[u8], data: &mut [u8]) -> Result<(), SymmError> {
103+
let mut encryptor = Aes128Ctr::new(
104+
GenericArray::from_slice(k),
105+
GenericArray::from_slice(iv),
106+
);
107+
encryptor.try_apply_keystream(data)?;
108+
Ok(())
109+
31110
}
32111

33112
/// Decrypt a message (CTR mode).
34113
///
35114
/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each.
36115
/// An error is returned if the input lengths are invalid.
116+
/// If possible prefer `inplace_decrypt_128_ctr` instead.
37117
pub fn decrypt_128_ctr(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) -> Result<(), SymmError> {
38-
let mut encryptor = CtrMode::new(AesSafe128Encryptor::new(k), iv.to_vec());
39-
encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut RefWriteBuffer::new(dest), true)?;
118+
let mut encryptor = Aes128Ctr::new(
119+
GenericArray::from_slice(k),
120+
GenericArray::from_slice(iv),
121+
);
122+
123+
&mut dest[..encrypted.len()].copy_from_slice(encrypted);
124+
encryptor.try_apply_keystream(dest)?;
40125
Ok(())
41126
}
42127

128+
/// Decrypt a message (CTR mode).
129+
///
130+
/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each.
131+
/// An error is returned if the input lengths are invalid.
132+
pub fn inplace_decrypt_128_ctr(k: &[u8], iv: &[u8], data: &mut [u8]) -> Result<(), SymmError> {
133+
let mut encryptor = Aes128Ctr::new(
134+
GenericArray::from_slice(k),
135+
GenericArray::from_slice(iv),
136+
);
137+
138+
encryptor.try_apply_keystream(data)?;
139+
Ok(())
140+
}
141+
142+
43143
/// Decrypt a message (CBC mode).
44144
///
45145
/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each.
46146
/// An error is returned if the input lengths are invalid.
47147
pub fn decrypt_128_cbc(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) -> Result<usize, SymmError> {
48-
let mut encryptor = CbcDecryptor::new(AesSafe128Decryptor::new(k), PkcsPadding, iv.to_vec());
49-
let len = dest.len();
50-
let mut buffer = RefWriteBuffer::new(dest);
51-
encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut buffer, true)?;
52-
Ok(len - buffer.remaining())
148+
let encryptor = Cbc::<Aes128, Pkcs7>::new_var(k, iv)?;
149+
&mut dest[..encrypted.len()].copy_from_slice(encrypted);
150+
let unpad_length = {
151+
encryptor.decrypt(&mut dest[..encrypted.len()])?.len()
152+
};
153+
Ok(unpad_length)
154+
}
155+
156+
157+
#[cfg(test)]
158+
mod tests {
159+
160+
use super::*;
161+
162+
// only use for test could be expose in the future
163+
fn encrypt_128_cbc(k: &[u8], iv: &[u8], plain: &[u8], dest: &mut [u8]) -> Result<(), SymmError> {
164+
let encryptor = Cbc::<Aes128, Pkcs7>::new_var(k, iv)?;
165+
&mut dest[..plain.len()].copy_from_slice(plain);
166+
encryptor.encrypt(dest, plain.len())?;
167+
Ok(())
168+
}
169+
170+
#[test]
171+
pub fn test_aes_short() -> Result<(),SymmError> {
172+
let key = [97, 110, 121, 99, 111, 110, 116, 101, 110, 116, 116, 111, 114, 101, 97, 99, 104, 49, 50, 56, 98, 105, 116, 115, 105, 122, 101, 10];
173+
let salt = [109, 121, 115, 97, 108, 116, 115, 104, 111, 117, 108, 100, 102, 105, 108, 108, 115, 111, 109, 109, 101, 98, 121, 116, 101, 108, 101, 110, 103, 116, 104, 10];
174+
let content = [83, 111, 109, 101, 32, 99, 111, 110, 116, 101, 110, 116, 32, 116, 111, 32, 116, 101, 115, 116,
175+
32, 97, 101, 115, 44, 10, 110, 111, 116, 32, 116, 111, 32, 109, 117, 99, 104, 32, 44, 32, 111, 110, 108, 121,
176+
32, 118, 101, 114, 121, 32, 98, 97, 115, 105, 99, 32, 116, 101, 115, 116, 32, 116, 111, 32, 97, 118, 111, 105,
177+
100, 32, 111, 98, 118, 105, 111, 117, 115, 32, 114, 101, 103, 114, 101, 115, 115, 105, 111, 110, 32, 119, 104,
178+
101, 110, 32, 115, 119, 105, 116, 99, 104, 105, 110, 103, 32, 108, 105, 98, 115, 46, 10];
179+
let ctr_enc = [65, 55, 246, 75, 24, 117, 30, 233, 218, 139, 91, 251, 251, 179, 171, 69, 60, 244, 249, 44, 238, 60,
180+
10, 66, 71, 10, 199, 111, 54, 24, 124, 223, 153, 250, 159, 154, 164, 109, 232, 82, 20, 199, 182, 40, 174, 104, 64,
181+
203, 236, 94, 222, 184, 117, 54, 234, 189, 253, 122, 135, 121, 100, 44, 227, 241, 123, 120, 110, 188, 109, 148, 112,
182+
160, 131, 205, 116, 104, 232, 8, 22, 170, 80, 231, 155, 246, 255, 115, 101, 5, 234, 104, 220, 199, 192, 166, 181, 156,
183+
113, 255, 187, 51, 38, 128, 75, 29, 237, 178, 205, 98, 101, 110];
184+
let cbc_enc = [167, 248, 5, 90, 11, 140, 215, 138, 165, 125, 137, 76, 47, 243, 191, 48, 183, 247, 109, 86, 24, 45,
185+
81, 215, 0, 51, 221, 185, 131, 97, 234, 189, 244, 255, 107, 210, 70, 60, 41, 221, 43, 137, 185, 166, 42, 65, 18, 200,
186+
151, 233, 255, 192, 109, 25, 105, 115, 161, 209, 126, 235, 99, 192, 241, 241, 19, 249, 87, 244, 28, 146, 186, 189, 108,
187+
9, 243, 132, 4, 105, 53, 162, 8, 235, 84, 107, 213, 59, 158, 113, 227, 120, 162, 50, 237, 123, 70, 187, 83, 73, 146, 13,
188+
44, 191, 53, 4, 125, 207, 176, 45, 8, 153, 175, 198];
189+
let mut dest = vec![0;110];
190+
let mut dest_padded = vec![0;112];
191+
let mut dest_padded2 = vec![0;128]; // TODO RustLib need an extra 16bytes in dest : looks extra buggy but function is not currently use (keep it private for now)
192+
encrypt_128_cbc(&key[..16], &salt[..16], &content, &mut dest_padded2)?;
193+
assert!(&dest_padded2[..112] == &cbc_enc[..]);
194+
encrypt_128_ctr(&key[..16], &salt[..16], &content, &mut dest)?;
195+
assert!(&dest[..] == &ctr_enc[..]);
196+
let mut content_data = content.to_vec();
197+
inplace_encrypt_128_ctr(&key[..16], &salt[..16], &mut content_data[..])?;
198+
assert!(&content_data[..] == &ctr_enc[..]);
199+
decrypt_128_ctr(&key[..16], &salt[..16], &ctr_enc[..], &mut dest)?;
200+
assert!(&dest[..] == &content[..]);
201+
let mut content_data = ctr_enc.to_vec();
202+
inplace_decrypt_128_ctr(&key[..16], &salt[..16], &mut content_data[..])?;
203+
assert!(&content_data[..] == &content[..]);
204+
let l = decrypt_128_cbc(&key[..16], &salt[..16], &cbc_enc[..], &mut dest_padded)?;
205+
assert!(&dest_padded[..l] == &content[..]);
206+
Ok(())
207+
}
53208
}

0 commit comments

Comments
 (0)