Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[parity-crypto] bump version to 0.4.0 #149

Merged
merged 12 commits into from
May 23, 2019
7 changes: 3 additions & 4 deletions parity-crypto/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "parity-crypto"
version = "0.3.1"
version = "0.4.0"
authors = ["Parity Technologies <admin@parity.io>"]
repository = "https://github.com/paritytech/parity-common"
description = "Crypto utils used by ethstore and network."
Expand All @@ -13,9 +13,8 @@ harness = false


[dependencies]
quick-error = "1.2.2"
tiny-keccak = "1.4"
scrypt = { version = "0.1.1", default-features = false }
scrypt = { version = "0.2", default-features = false }
ripemd160 = "0.8.0"
sha2 = "0.8.0"
digest = "0.8"
Expand All @@ -24,7 +23,7 @@ aes = "0.3.2"
aes-ctr = "0.3.0"
block-modes = "0.3.3"
pbkdf2 = "0.3.0"
constant_time_eq = "0.1.3"
subtle = "2.1"
memzero = "0.1"

[dev-dependencies]
Expand Down
5 changes: 4 additions & 1 deletion parity-crypto/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@

General cryptographic utilities for Ethereum.

By default, this library is compiled with the `secp256k1` feature, which provides ECDH and ECIES capability on that curve. It can be compiled without to avoid a dependency on the `libsecp256k1` library.

## Changelog

The 0.4 release removes the dependency on `ring` and replaces it with prue-rust alternatives. As a consequence of this, AES GCM support has been removed. `subtle` is used for constant time equality testing and error handling is pared down to the bare minimum required.
156 changes: 100 additions & 56 deletions parity-crypto/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,80 +18,99 @@ use rscrypt;
use block_modes;
use aes_ctr;
use std::error::Error as StdError;
use std::{fmt, result};

quick_error! {
#[derive(Debug)]
pub enum Error {
Scrypt(e: ScryptError) {
cause(e)
from()
}
Symm(e: SymmError) {
cause(e)
from()
}
AsymShort(det: &'static str) {
description(det)
}
AsymFull(e: Box<dyn StdError + Send>) {
cause(&**e)
description(e.description())
#[derive(Debug)]
pub enum Error {
Scrypt(ScryptError),
Symm(SymmError),
}

#[derive(Debug)]
pub enum ScryptError {
// log(N) < r / 16
InvalidN,
// p <= (2^31-1 * 32)/(128 * r)
InvalidP,
ScryptParam(rscrypt::errors::InvalidParams),
ScryptLength(rscrypt::errors::InvalidOutputLen),
}

#[derive(Debug)]
pub struct SymmError(PrivSymmErr);

#[derive(Debug)]
enum PrivSymmErr {
BlockMode(block_modes::BlockModeError),
KeyStream(aes_ctr::stream_cipher::LoopError),
InvalidKeyLength(block_modes::InvalidKeyIvLength),
}

impl StdError for Error {
fn source(&self) -> Option<&(StdError + 'static)> {
match self {
Error::Scrypt(scrypt_err) => Some(scrypt_err),
Error::Symm(symm_err) => Some(symm_err),
}
}
}

impl Into<std::io::Error> for Error {
fn into(self) -> std::io::Error {
std::io::Error::new(std::io::ErrorKind::Other, format!("Crypto error: {}",self))
impl StdError for ScryptError {
fn source(&self) -> Option<&(StdError + 'static)> {
match self {
ScryptError::ScryptParam(err) => Some(err),
ScryptError::ScryptLength(err) => Some(err),
_ => None,
}
}
}

quick_error! {
#[derive(Debug)]
pub enum ScryptError {
// log(N) < r / 16
InvalidN {
display("Invalid N argument of the scrypt encryption")
}
// p <= (2^31-1 * 32)/(128 * r)
InvalidP {
display("Invalid p argument of the scrypt encryption")
}
ScryptParam(e: rscrypt::errors::InvalidParams) {
display("invalid params for scrypt: {}", e)
cause(e)
from()
}
ScryptLength(e: rscrypt::errors::InvalidOutputLen) {
display("invalid scrypt output length: {}", e)
cause(e)
from()
impl StdError for SymmError {
fn source(&self) -> Option<&(StdError + 'static)> {
match &self.0 {
PrivSymmErr::BlockMode(err) => Some(err),
PrivSymmErr::InvalidKeyLength(err) => Some(err),
_ => None,
}
}
}


quick_error! {
#[derive(Debug)]
pub enum SymmError wraps PrivSymmErr {
Offset(x: usize) {
display("offset {} greater than slice length", x)
}
BlockMode(e: block_modes::BlockModeError) {
display("symmetric crypto error")
from()
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
match self {
Error::Scrypt(err)=> write!(f, "scrypt error: {}", err),
Error::Symm(err) => write!(f, "symm error: {}", err),
}
KeyStream(e: aes_ctr::stream_cipher::LoopError) {
display("ctr key stream ended")
from()
}
}

impl fmt::Display for ScryptError {
fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
match self {
ScryptError::InvalidN => write!(f, "invalid n argument"),
ScryptError::InvalidP => write!(f, "invalid p argument"),
ScryptError::ScryptParam(err) => write!(f, "invalid params: {}", err),
ScryptError::ScryptLength(err) => write!(f, "invalid output length: {}", err),
}
InvalidKeyLength(e: block_modes::InvalidKeyIvLength) {
display("Error with RustCrypto key length : {}", e)
from()
}
}

impl fmt::Display for SymmError {
fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
match self {
SymmError(PrivSymmErr::BlockMode(err)) => write!(f, "block cipher error: {}", err),
SymmError(PrivSymmErr::KeyStream(err)) => write!(f, "ctr key stream ended: {}", err),
SymmError(PrivSymmErr::InvalidKeyLength(err)) => write!(f, "block cipher key length: {}", err),
}
}
}

impl Into<std::io::Error> for Error {
fn into(self) -> std::io::Error {
std::io::Error::new(std::io::ErrorKind::Other, format!("Crypto error: {}",self))
}
}

impl From<block_modes::BlockModeError> for SymmError {
fn from(e: block_modes::BlockModeError) -> SymmError {
SymmError(PrivSymmErr::BlockMode(e))
Expand All @@ -109,3 +128,28 @@ impl From<aes_ctr::stream_cipher::LoopError> for SymmError {
SymmError(PrivSymmErr::KeyStream(e))
}
}

impl From<rscrypt::errors::InvalidParams> for ScryptError {
fn from(e: rscrypt::errors::InvalidParams) -> ScryptError {
ScryptError::ScryptParam(e)
}
}

impl From<rscrypt::errors::InvalidOutputLen> for ScryptError {
fn from(e: rscrypt::errors::InvalidOutputLen) -> ScryptError {
ScryptError::ScryptLength(e)
}
}

impl From<ScryptError> for Error {
fn from(e: ScryptError) -> Error {
Error::Scrypt(e)
}
}

impl From<SymmError> for Error {
fn from(e: SymmError) -> Error {
Error::Symm(e)
}
}

21 changes: 17 additions & 4 deletions parity-crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

//! Crypto utils used by ethstore and network.

#[macro_use]
extern crate quick_error;
extern crate tiny_keccak;
extern crate scrypt as rscrypt;
extern crate ripemd160 as rripemd160;
Expand All @@ -28,7 +26,7 @@ extern crate aes as raes;
extern crate aes_ctr;
extern crate block_modes;
extern crate pbkdf2 as rpbkdf2;
extern crate constant_time_eq;
extern crate subtle;
extern crate memzero;

#[cfg(test)]
Expand All @@ -45,6 +43,7 @@ pub mod pbkdf2;
pub use error::Error;

use tiny_keccak::Keccak;
use subtle::ConstantTimeEq;

pub const KEY_LENGTH: usize = 32;
pub const KEY_ITERATIONS: usize = 10240;
Expand Down Expand Up @@ -83,5 +82,19 @@ pub fn derive_mac(derived_left_bits: &[u8], cipher_text: &[u8]) -> Vec<u8> {
}

pub fn is_equal(a: &[u8], b: &[u8]) -> bool {
constant_time_eq::constant_time_eq(a, b)
a.ct_eq(b).into()
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn can_test_for_equality() {
let a = b"abc";
let b = b"abc";
let c = b"efg";
assert!(is_equal(a, b));
assert!(!is_equal(a, c));
}
}
1 change: 0 additions & 1 deletion parity-crypto/src/pbkdf2/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

use super::*;
use std::num::NonZeroU32;

#[test]
fn basic_test() {
Expand Down