parity_crypto/
lib.rs

1// Copyright 2020 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Crypto utils used by ethstore and network.
10
11pub mod aes;
12pub mod digest;
13pub mod error;
14pub mod hmac;
15pub mod pbkdf2;
16#[cfg(feature = "publickey")]
17pub mod publickey;
18pub mod scrypt;
19
20pub use crate::error::Error;
21
22use subtle::ConstantTimeEq;
23use tiny_keccak::{Hasher, Keccak};
24
25pub const KEY_LENGTH: usize = 32;
26pub const KEY_ITERATIONS: usize = 10240;
27pub const KEY_LENGTH_AES: usize = KEY_LENGTH / 2;
28
29/// Default authenticated data to use (in RPC).
30pub const DEFAULT_MAC: [u8; 2] = [0, 0];
31
32pub trait Keccak256<T> {
33	fn keccak256(&self) -> T
34	where
35		T: Sized;
36}
37
38impl<T> Keccak256<[u8; 32]> for T
39where
40	T: AsRef<[u8]>,
41{
42	fn keccak256(&self) -> [u8; 32] {
43		let mut keccak = Keccak::v256();
44		let mut result = [0u8; 32];
45		keccak.update(self.as_ref());
46		keccak.finalize(&mut result);
47		result
48	}
49}
50
51pub fn derive_key_iterations(password: &[u8], salt: &[u8], c: u32) -> (Vec<u8>, Vec<u8>) {
52	let mut derived_key = [0u8; KEY_LENGTH];
53	pbkdf2::sha256(c, pbkdf2::Salt(salt), pbkdf2::Secret(password), &mut derived_key);
54	let derived_right_bits = &derived_key[0..KEY_LENGTH_AES];
55	let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH];
56	(derived_right_bits.to_vec(), derived_left_bits.to_vec())
57}
58
59pub fn derive_mac(derived_left_bits: &[u8], cipher_text: &[u8]) -> Vec<u8> {
60	let mut mac = vec![0u8; KEY_LENGTH_AES + cipher_text.len()];
61	mac[0..KEY_LENGTH_AES].copy_from_slice(derived_left_bits);
62	mac[KEY_LENGTH_AES..cipher_text.len() + KEY_LENGTH_AES].copy_from_slice(cipher_text);
63	mac
64}
65
66pub fn is_equal(a: &[u8], b: &[u8]) -> bool {
67	a.ct_eq(b).into()
68}
69
70#[cfg(test)]
71mod test {
72	use super::*;
73
74	#[test]
75	fn can_test_for_equality() {
76		let a = b"abc";
77		let b = b"abc";
78		let c = b"efg";
79		assert!(is_equal(a, b));
80		assert!(!is_equal(a, c));
81	}
82}