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-beta.4"
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.
170 changes: 114 additions & 56 deletions parity-crypto/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,80 +18,113 @@ 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),
// TODO: used anywhere?
AsymShort(&'static str),
// TODO: used anywhere?
AsymFull(Box<dyn StdError + Send>)
dvdplm marked this conversation as resolved.
Show resolved Hide resolved
}

#[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 {
Offset(usize), // TODO: never constructed – can remove?
dvdplm marked this conversation as resolved.
Show resolved Hide resolved
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),
Error::AsymShort(_)=> None,
Error::AsymFull(err)=> Some(&**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),
// TODO: the trait `std::error::Error` is not implemented for
dvdplm marked this conversation as resolved.
Show resolved Hide resolved
// `aes_ctr::stream_cipher::LoopError` – but afaict it **is**:
// https://github.com/RustCrypto/traits/blob/master/stream-cipher/src/errors.rs#L16
// PrivSymmErr::KeyStream(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),
Error::AsymShort(err_str) => write!(f, "asymm error: {}", err_str),
Error::AsymFull(err) => write!(f, "asymm 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::Offset(x)) => write!(f, "offset {} greater than slice length", x),
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 +142,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