Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions parity-crypto/src/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,11 @@ pub fn ripemd160(data: &[u8]) -> Digest<Ripemd160> {
hasher.finish()
}

#[derive(Debug)]
pub enum Sha256 {}
#[derive(Debug)]
pub enum Sha512 {}
#[derive(Debug)]
pub enum Ripemd160 {}

/// Stateful digest computation.
Expand Down
61 changes: 40 additions & 21 deletions parity-crypto/src/hmac/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

use digest::{Sha256, Sha512};
use rdigest::generic_array::{GenericArray, typenum::U32, typenum::U64, typenum::U128};
use rdigest::generic_array::{GenericArray, typenum::U32, typenum::U64};
use rhmac::{Hmac, Mac as _};
use rsha2;
use std::marker::PhantomData;
use std::ops::Deref;

/// HMAC signature.
#[derive(Debug)]
pub struct Signature<T>(HashInner, PhantomData<T>);

#[derive(Debug)]
enum HashInner {
Sha256(GenericArray<u8, U32>),
Sha512(GenericArray<u8, U64>),
Expand All @@ -44,19 +46,19 @@ impl<T> Deref for Signature<T> {
pub struct SigKey<T>(KeyInner, PhantomData<T>);

enum KeyInner {
Sha256(GenericArray<u8, U64>),
Sha512(GenericArray<u8, U128>),
Sha256(Vec<u8>),
Comment thread
niklasad1 marked this conversation as resolved.
Sha512(Vec<u8>),
}

impl SigKey<Sha256> {
pub fn sha256(key: &[u8]) -> SigKey<Sha256> {
SigKey(KeyInner::Sha256(*GenericArray::from_slice(key)), PhantomData)
SigKey(KeyInner::Sha256(key.to_vec()), PhantomData)
}
}

impl SigKey<Sha512> {
pub fn sha512(key: &[u8]) -> SigKey<Sha512> {
SigKey(KeyInner::Sha512(*GenericArray::from_slice(key)), PhantomData)
SigKey(KeyInner::Sha512(key.to_vec()), PhantomData)
}
}

Expand All @@ -78,8 +80,23 @@ enum SignerInner {
impl<T> Signer<T> {
pub fn with(key: &SigKey<T>) -> Signer<T> {
match &key.0 {
KeyInner::Sha256(k) => Signer(SignerInner::Sha256(Hmac::new(k)), PhantomData),
KeyInner::Sha512(k) => Signer(SignerInner::Sha512(Hmac::new(k)), PhantomData),
KeyInner::Sha256(key_bytes) => {
Signer(
SignerInner::Sha256(
Hmac::<rsha2::Sha256>::new_varkey(key_bytes)
.expect("always returns Ok; qed")
),
PhantomData
)
},
KeyInner::Sha512(key_bytes) => {
Signer(
SignerInner::Sha512(
Hmac::<rsha2::Sha512>::new_varkey(key_bytes)
.expect("always returns Ok; qed")
), PhantomData
)
},
}
}

Expand All @@ -103,29 +120,31 @@ pub struct VerifyKey<T>(KeyInner, PhantomData<T>);

impl VerifyKey<Sha256> {
pub fn sha256(key: &[u8]) -> VerifyKey<Sha256> {
VerifyKey(KeyInner::Sha256(*GenericArray::from_slice(key)), PhantomData)
VerifyKey(KeyInner::Sha256(key.to_vec()), PhantomData)
}
}

impl VerifyKey<Sha512> {
pub fn sha512(key: &[u8]) -> VerifyKey<Sha512> {
VerifyKey(KeyInner::Sha512(*GenericArray::from_slice(key)), PhantomData)
VerifyKey(KeyInner::Sha512(key.to_vec()), PhantomData)
}
}

/// Verify HMAC signature of `data`.
pub fn verify<T>(k: &VerifyKey<T>, data: &[u8], sig: &[u8]) -> bool {
match &k.0 {
KeyInner::Sha256(k) => {
let mut ctxt = Hmac::<rsha2::Sha256>::new(k);
ctxt.input(data);
ctxt.verify(sig).is_ok()
}
KeyInner::Sha512(k) => {
let mut ctxt = Hmac::<rsha2::Sha512>::new(k);
ctxt.input(data);
ctxt.verify(sig).is_ok()
}
pub fn verify<T>(key: &VerifyKey<T>, data: &[u8], sig: &[u8]) -> bool {
match &key.0 {
KeyInner::Sha256(key_bytes) => {
let mut ctx = Hmac::<rsha2::Sha256>::new_varkey(key_bytes)
.expect("always returns Ok; qed");
ctx.input(data);
ctx.verify(sig).is_ok()
},
KeyInner::Sha512(key_bytes) => {
let mut ctx = Hmac::<rsha2::Sha512>::new_varkey(key_bytes)
.expect("always returns Ok; qed");
ctx.input(data);
ctx.verify(sig).is_ok()
},
}
}

Expand Down
1 change: 0 additions & 1 deletion parity-crypto/src/hmac/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,4 @@ fn simple_mac_and_verify() {
let verif_key2 = VerifyKey::sha512(&key2[..]);
assert!(verify(&verif_key1, &input[..], &sig1[..]));
assert!(verify(&verif_key2, &big_input[..], &sig2[..]));

}