From aa750a5e9dfd447818c104244a2c3a29c595875f Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 7 Jan 2022 05:49:14 +0100 Subject: [PATCH 01/11] Enforce maximum size of `ExpandMsgXmd` --- elliptic-curve/src/hash2curve/group_digest.rs | 26 ++++++++++++++----- elliptic-curve/src/hash2field.rs | 19 ++++++++++---- elliptic-curve/src/hash2field/expand_msg.rs | 4 +-- .../src/hash2field/expand_msg_xmd.rs | 16 ++++++++---- .../src/hash2field/expand_msg_xof.rs | 9 ++++--- 5 files changed, 52 insertions(+), 22 deletions(-) diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 736f7c935..84159d79e 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -1,5 +1,11 @@ +use core::ops::Mul; + use super::MapToCurve; use crate::hash2field::{hash_to_field, ExpandMsg, FromOkm}; +use generic_array::{ + typenum::{Prod, U1, U2}, + ArrayLength, +}; use group::cofactor::CofactorGroup; /// Adds hashing arbitrary byte sequences to a valid group element @@ -34,9 +40,13 @@ pub trait GroupDigest { /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XOF:SHAKE-256_SSWU_RO_"); /// ``` /// - fn hash_from_bytes(msg: &[u8], dst: &'static [u8]) -> Self::Output { - let mut u = [Self::FieldElement::default(), Self::FieldElement::default()]; - hash_to_field::(msg, dst, &mut u); + fn hash_from_bytes(msg: &[u8], dst: &'static [u8]) -> Self::Output + where + X: ExpandMsg::Length, U2>>, + ::Length: Mul, + Prod<::Length, U2>: ArrayLength, + { + let u = hash_to_field::(msg, dst); let q0 = Self::Output::map_to_curve(u[0]); let q1 = Self::Output::map_to_curve(u[1]); // Ideally we could add and then clear cofactor once @@ -60,9 +70,13 @@ pub trait GroupDigest { /// uniformly random in G: the set of possible outputs of /// encode_to_curve is only a fraction of the points in G, and some /// points in this set are more likely to be output than others. - fn encode_from_bytes(msg: &[u8], dst: &'static [u8]) -> Self::Output { - let mut u = [Self::FieldElement::default()]; - hash_to_field::(msg, dst, &mut u); + fn encode_from_bytes(msg: &[u8], dst: &'static [u8]) -> Self::Output + where + X: ExpandMsg::Length, U1>>, + ::Length: Mul, + Prod<::Length, U1>: ArrayLength, + { + let u = hash_to_field::(msg, dst); let q0 = Self::Output::map_to_curve(u[0]); q0.clear_cofactor() } diff --git a/elliptic-curve/src/hash2field.rs b/elliptic-curve/src/hash2field.rs index bdf30b9a5..7ffd49daf 100644 --- a/elliptic-curve/src/hash2field.rs +++ b/elliptic-curve/src/hash2field.rs @@ -2,10 +2,13 @@ mod expand_msg; mod expand_msg_xmd; mod expand_msg_xof; +use core::ops::Mul; + pub use expand_msg::*; pub use expand_msg_xmd::*; pub use expand_msg_xof::*; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +use generic_array::{ArrayLength, GenericArray}; +use generic_array::typenum::Prod; /// The trait for helping to convert to a scalar pub trait FromOkm { @@ -18,16 +21,22 @@ pub trait FromOkm { /// Convert an arbitrary byte sequence according to /// -pub fn hash_to_field(data: &[u8], domain: &'static [u8], out: &mut [T]) +pub fn hash_to_field>( + data: &[u8], + domain: &'static [u8], +) -> GenericArray where - E: ExpandMsg, + E: ExpandMsg>, T: FromOkm + Default, + T::Length: Mul, + Prod: ArrayLength, { - let len_in_bytes = T::Length::to_usize() * out.len(); let mut tmp = GenericArray::::Length>::default(); - let mut expander = E::expand_message(data, domain, len_in_bytes); + let mut expander = E::expand_message(data, domain); + let mut out = GenericArray::default(); for o in out.iter_mut() { expander.fill_bytes(&mut tmp); *o = T::from_okm(&tmp); } + out } diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs index 9adfab766..c41e61860 100644 --- a/elliptic-curve/src/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -7,11 +7,11 @@ const OVERSIZE_DST_SALT: &[u8] = b"H2C-OVERSIZE-DST-"; const MAX_DST_LEN: usize = 255; /// Trait for types implementing expand_message interface for hash_to_field -pub trait ExpandMsg { +pub trait ExpandMsg> { /// Expands `msg` to the required number of bytes /// Returns an expander that can be used to call `read` until enough /// bytes have been consumed - fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Self; + fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self; /// Fill the array with the expanded bytes fn fill_bytes(&mut self, okm: &mut [u8]); diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs index be599fcea..d37f76246 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -1,11 +1,12 @@ use super::{Domain, ExpandMsg}; use digest::{ generic_array::{ - typenum::{IsLess, IsLessOrEqual, Unsigned, U256}, + typenum::{IsLess, IsLessOrEqual, Unsigned, U256, U65536}, GenericArray, }, BlockInput, Digest, }; +use generic_array::ArrayLength; /// Placeholder type for implementing expand_message_xmd based on a hash function pub struct ExpandMsgXmd @@ -53,15 +54,16 @@ where } /// ExpandMsgXmd implements expand_message_xmd for the ExpandMsg trait -impl ExpandMsg for ExpandMsgXmd +impl ExpandMsg for ExpandMsgXmd where HashT: Digest + BlockInput, HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual, + L: ArrayLength + IsLess, { - fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Self { + fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self { let b_in_bytes = HashT::OutputSize::to_usize(); - let ell = (len_in_bytes + b_in_bytes - 1) / b_in_bytes; + let ell = (L::to_usize() + b_in_bytes - 1) / b_in_bytes; // if ell > 255 { // panic!("ell was too big in expand_message_xmd"); // } @@ -69,7 +71,11 @@ where let b_0 = HashT::new() .chain(GenericArray::::default()) .chain(msg) - .chain([(len_in_bytes >> 8) as u8, len_in_bytes as u8, 0u8]) + .chain([ + L::to_u16().to_be_bytes()[0], + L::to_u16().to_be_bytes()[1], + 0u8, + ]) .chain(domain.data()) .chain([domain.len() as u8]) .finalize(); diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs index 371482ae4..aef424c43 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -1,7 +1,7 @@ use super::ExpandMsg; use crate::hash2field::Domain; use digest::{ExtendableOutput, ExtendableOutputDirty, Update, XofReader}; -use generic_array::typenum::U32; +use generic_array::{typenum::U32, ArrayLength}; /// Placeholder type for implementing expand_message_xof based on an extendable output function pub struct ExpandMsgXof @@ -12,15 +12,16 @@ where } /// ExpandMsgXof implements expand_message_xof for the ExpandMsg trait -impl ExpandMsg for ExpandMsgXof +impl ExpandMsg for ExpandMsgXof where HashT: Default + ExtendableOutput + ExtendableOutputDirty + Update, + L: ArrayLength, { - fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Self { + fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self { let domain = Domain::::xof::(dst); let reader = HashT::default() .chain(msg) - .chain([(len_in_bytes >> 8) as u8, len_in_bytes as u8]) + .chain([(L::to_usize() >> 8) as u8, L::to_usize() as u8]) .chain(domain.data()) .chain([domain.len() as u8]) .finalize_xof(); From 46b24c643e4dded18f5dae11c266a51578eaef7a Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 7 Jan 2022 06:12:39 +0100 Subject: [PATCH 02/11] Enforce maximum `ell` of `ExpandMsgXmd` --- elliptic-curve/src/hash2field.rs | 2 +- .../src/hash2field/expand_msg_xmd.rs | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/elliptic-curve/src/hash2field.rs b/elliptic-curve/src/hash2field.rs index 7ffd49daf..54febaf3d 100644 --- a/elliptic-curve/src/hash2field.rs +++ b/elliptic-curve/src/hash2field.rs @@ -7,8 +7,8 @@ use core::ops::Mul; pub use expand_msg::*; pub use expand_msg_xmd::*; pub use expand_msg_xof::*; -use generic_array::{ArrayLength, GenericArray}; use generic_array::typenum::Prod; +use generic_array::{ArrayLength, GenericArray}; /// The trait for helping to convert to a scalar pub trait FromOkm { diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs index d37f76246..39963b592 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -1,12 +1,14 @@ +use core::ops::Mul; + use super::{Domain, ExpandMsg}; use digest::{ generic_array::{ - typenum::{IsLess, IsLessOrEqual, Unsigned, U256, U65536}, + typenum::{IsLess, IsLessOrEqual, Unsigned, U255, U256, U65536}, GenericArray, }, BlockInput, Digest, }; -use generic_array::ArrayLength; +use generic_array::{typenum::Prod, ArrayLength}; /// Placeholder type for implementing expand_message_xmd based on a hash function pub struct ExpandMsgXmd @@ -60,10 +62,13 @@ where HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual, L: ArrayLength + IsLess, + U255: Mul, + L: IsLess>, { fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self { let b_in_bytes = HashT::OutputSize::to_usize(); let ell = (L::to_usize() + b_in_bytes - 1) / b_in_bytes; + // Enforced on the type level // if ell > 255 { // panic!("ell was too big in expand_message_xmd"); // } @@ -71,11 +76,10 @@ where let b_0 = HashT::new() .chain(GenericArray::::default()) .chain(msg) - .chain([ - L::to_u16().to_be_bytes()[0], - L::to_u16().to_be_bytes()[1], - 0u8, - ]) + .chain({ + let l = L::to_u16().to_be_bytes(); + [l[0], l[1], 0u8] + }) .chain(domain.data()) .chain([domain.len() as u8]) .finalize(); From 221474ee6dc2b9d05f04ac168e7391108bb34bd8 Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 7 Jan 2022 06:25:58 +0100 Subject: [PATCH 03/11] Enforce maximum size of `ExpandMsgXof` --- elliptic-curve/src/hash2field/expand_msg_xof.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs index aef424c43..e27c04b70 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -1,7 +1,8 @@ use super::ExpandMsg; use crate::hash2field::Domain; use digest::{ExtendableOutput, ExtendableOutputDirty, Update, XofReader}; -use generic_array::{typenum::U32, ArrayLength}; +use generic_array::typenum::{IsLessOrEqual, U32, U65536}; +use generic_array::ArrayLength; /// Placeholder type for implementing expand_message_xof based on an extendable output function pub struct ExpandMsgXof @@ -15,13 +16,13 @@ where impl ExpandMsg for ExpandMsgXof where HashT: Default + ExtendableOutput + ExtendableOutputDirty + Update, - L: ArrayLength, + L: ArrayLength + IsLessOrEqual, { fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self { let domain = Domain::::xof::(dst); let reader = HashT::default() .chain(msg) - .chain([(L::to_usize() >> 8) as u8, L::to_usize() as u8]) + .chain(L::to_u16().to_be_bytes()) .chain(domain.data()) .chain([domain.len() as u8]) .finalize_xof(); From 81b3504990842b35ed02dcfb602fdac32d0fe8b6 Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 7 Jan 2022 06:26:46 +0100 Subject: [PATCH 04/11] Enforce maximum size of hash for both `ExpandMsg`s --- elliptic-curve/src/hash2field/expand_msg_xmd.rs | 6 +++--- elliptic-curve/src/hash2field/expand_msg_xof.rs | 10 ++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs index 39963b592..d29c42075 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -14,7 +14,7 @@ use generic_array::{typenum::Prod, ArrayLength}; pub struct ExpandMsgXmd where HashT: Digest + BlockInput, - HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, HashT::OutputSize: IsLessOrEqual, { b_0: GenericArray, @@ -28,7 +28,7 @@ where impl ExpandMsgXmd where HashT: Digest + BlockInput, - HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, HashT::OutputSize: IsLessOrEqual, { fn next(&mut self) -> bool { @@ -59,7 +59,7 @@ where impl ExpandMsg for ExpandMsgXmd where HashT: Digest + BlockInput, - HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, HashT::OutputSize: IsLessOrEqual, L: ArrayLength + IsLess, U255: Mul, diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs index e27c04b70..ed2c42711 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -1,13 +1,14 @@ use super::ExpandMsg; use crate::hash2field::Domain; -use digest::{ExtendableOutput, ExtendableOutputDirty, Update, XofReader}; -use generic_array::typenum::{IsLessOrEqual, U32, U65536}; +use digest::{ExtendableOutput, ExtendableOutputDirty, FixedOutput, Update, XofReader}; +use generic_array::typenum::{IsLessOrEqual, U256, U32, U65536}; use generic_array::ArrayLength; /// Placeholder type for implementing expand_message_xof based on an extendable output function pub struct ExpandMsgXof where - HashT: Default + ExtendableOutput + ExtendableOutputDirty + Update, + HashT: Default + ExtendableOutput + ExtendableOutputDirty + FixedOutput + Update, + HashT::OutputSize: IsLessOrEqual, { reader: ::Reader, } @@ -15,7 +16,8 @@ where /// ExpandMsgXof implements expand_message_xof for the ExpandMsg trait impl ExpandMsg for ExpandMsgXof where - HashT: Default + ExtendableOutput + ExtendableOutputDirty + Update, + HashT: Default + ExtendableOutput + ExtendableOutputDirty + FixedOutput + Update, + HashT::OutputSize: IsLessOrEqual, L: ArrayLength + IsLessOrEqual, { fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self { From c7e701fc194387aa810e1f923ebaba8ac2053373 Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 7 Jan 2022 06:41:42 +0100 Subject: [PATCH 05/11] Don't allow zero output --- elliptic-curve/src/hash2field/expand_msg_xmd.rs | 13 ++++--------- elliptic-curve/src/hash2field/expand_msg_xof.rs | 4 ++-- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs index d29c42075..e66fa5ee7 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -1,14 +1,9 @@ use core::ops::Mul; use super::{Domain, ExpandMsg}; -use digest::{ - generic_array::{ - typenum::{IsLess, IsLessOrEqual, Unsigned, U255, U256, U65536}, - GenericArray, - }, - BlockInput, Digest, -}; -use generic_array::{typenum::Prod, ArrayLength}; +use digest::{BlockInput, Digest}; +use generic_array::typenum::{IsLess, IsLessOrEqual, NonZero, Prod, Unsigned, U255, U256, U65536}; +use generic_array::{ArrayLength, GenericArray}; /// Placeholder type for implementing expand_message_xmd based on a hash function pub struct ExpandMsgXmd @@ -61,7 +56,7 @@ where HashT: Digest + BlockInput, HashT::OutputSize: IsLessOrEqual, HashT::OutputSize: IsLessOrEqual, - L: ArrayLength + IsLess, + L: ArrayLength + IsLess + NonZero, U255: Mul, L: IsLess>, { diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs index ed2c42711..187adc308 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -1,7 +1,7 @@ use super::ExpandMsg; use crate::hash2field::Domain; use digest::{ExtendableOutput, ExtendableOutputDirty, FixedOutput, Update, XofReader}; -use generic_array::typenum::{IsLessOrEqual, U256, U32, U65536}; +use generic_array::typenum::{IsLessOrEqual, NonZero, U256, U32, U65536}; use generic_array::ArrayLength; /// Placeholder type for implementing expand_message_xof based on an extendable output function @@ -18,7 +18,7 @@ impl ExpandMsg for ExpandMsgXof where HashT: Default + ExtendableOutput + ExtendableOutputDirty + FixedOutput + Update, HashT::OutputSize: IsLessOrEqual, - L: ArrayLength + IsLessOrEqual, + L: ArrayLength + IsLessOrEqual + NonZero, { fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self { let domain = Domain::::xof::(dst); From 178502637b4a683eb5b9ee4e18ece08630942489 Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 7 Jan 2022 06:55:58 +0100 Subject: [PATCH 06/11] Comment constraints --- elliptic-curve/src/hash2field/expand_msg_xmd.rs | 13 ++++++++++--- elliptic-curve/src/hash2field/expand_msg_xof.rs | 8 +++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs index e66fa5ee7..97ca71981 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -54,11 +54,18 @@ where impl ExpandMsg for ExpandMsgXmd where HashT: Digest + BlockInput, + L: ArrayLength, + U255: Mul, + // If `len_in_bytes` is bigger then 256, length of the `DST` will depend on + // the output size of the hash, which is still not allowed to be bigger then 256: + // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-6 HashT::OutputSize: IsLessOrEqual, + // Constraint set by `expand_message_xmd`: + // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-4 HashT::OutputSize: IsLessOrEqual, - L: ArrayLength + IsLess + NonZero, - U255: Mul, - L: IsLess>, + // Constraint set by `expand_message_xmd`: + // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-6 + L: NonZero + IsLess> + IsLess, { fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self { let b_in_bytes = HashT::OutputSize::to_usize(); diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs index 187adc308..e3868891c 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -17,8 +17,14 @@ where impl ExpandMsg for ExpandMsgXof where HashT: Default + ExtendableOutput + ExtendableOutputDirty + FixedOutput + Update, + L: ArrayLength, + // If `len_in_bytes` is bigger then 256, length of the `DST` will depend on + // the output size of the hash, which is still not allowed to be bigger then 256: + // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.2-5 HashT::OutputSize: IsLessOrEqual, - L: ArrayLength + IsLessOrEqual + NonZero, + // Constraint set by `expand_message_xof`: + // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.2-5 + L: NonZero + IsLessOrEqual, { fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self { let domain = Domain::::xof::(dst); From 2d45918943a4a135b351162b0a4dd8c14e4b2e86 Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 7 Jan 2022 07:11:25 +0100 Subject: [PATCH 07/11] Reduce unchecked conversions to a minimum --- elliptic-curve/src/hash2field/expand_msg.rs | 18 +++++++++++++----- .../src/hash2field/expand_msg_xmd.rs | 17 +++++++++-------- .../src/hash2field/expand_msg_xof.rs | 2 +- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs index c41e61860..144aa8787 100644 --- a/elliptic-curve/src/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -1,4 +1,5 @@ use digest::{Digest, ExtendableOutputDirty, Update, XofReader}; +use generic_array::typenum::{IsLessOrEqual, U256}; use generic_array::{ArrayLength, GenericArray}; /// Salt when the DST is too long @@ -22,14 +23,20 @@ pub trait ExpandMsg> { /// Implements [section 5.4.3 of `draft-irtf-cfrg-hash-to-curve-13`][dst]. /// /// [dst]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-13#section-5.4.3 -pub(crate) enum Domain> { +pub(crate) enum Domain +where + L: ArrayLength + IsLessOrEqual, +{ /// > 255 Hashed(GenericArray), /// <= 255 Array(&'static [u8]), } -impl> Domain { +impl Domain +where + L: ArrayLength + IsLessOrEqual, +{ pub fn xof(dst: &'static [u8]) -> Self where X: Default + ExtendableOutputDirty + Update, @@ -65,10 +72,11 @@ impl> Domain { } } - pub fn len(&self) -> usize { + pub fn len(&self) -> u8 { match self { - Self::Hashed(_) => L::to_usize(), - Self::Array(d) => d.len(), + Self::Hashed(_) => L::to_u8(), + // Can't overflow because enforced on a type level. + Self::Array(d) => d.len() as u8, } } } diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs index 97ca71981..c3377f676 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -15,9 +15,9 @@ where b_0: GenericArray, b_vals: GenericArray, domain: Domain, - index: usize, + index: u8, offset: usize, - ell: usize, + ell: u8, } impl ExpandMsgXmd @@ -39,9 +39,9 @@ where .for_each(|(j, (b0val, bi1val))| tmp[j] = b0val ^ bi1val); self.b_vals = HashT::new() .chain(tmp) - .chain([self.index as u8]) + .chain([self.index]) .chain(self.domain.data()) - .chain([self.domain.len() as u8]) + .chain([self.domain.len()]) .finalize(); true } else { @@ -68,8 +68,9 @@ where L: NonZero + IsLess> + IsLess, { fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self { - let b_in_bytes = HashT::OutputSize::to_usize(); - let ell = (L::to_usize() + b_in_bytes - 1) / b_in_bytes; + let b_in_bytes = HashT::OutputSize::to_u16(); + // Can't overflow because enforced on a type level. + let ell = ((L::to_u16() + b_in_bytes - 1) / b_in_bytes) as u8; // Enforced on the type level // if ell > 255 { // panic!("ell was too big in expand_message_xmd"); @@ -83,14 +84,14 @@ where [l[0], l[1], 0u8] }) .chain(domain.data()) - .chain([domain.len() as u8]) + .chain([domain.len()]) .finalize(); let b_vals = HashT::new() .chain(&b_0[..]) .chain([1u8]) .chain(domain.data()) - .chain([domain.len() as u8]) + .chain([domain.len()]) .finalize(); Self { diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs index e3868891c..88c384e4f 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -32,7 +32,7 @@ where .chain(msg) .chain(L::to_u16().to_be_bytes()) .chain(domain.data()) - .chain([domain.len() as u8]) + .chain([domain.len()]) .finalize_xof(); Self { reader } } From 246e39ccf08f2b694f912e85b5f978b4b00f67b7 Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 7 Jan 2022 07:14:59 +0100 Subject: [PATCH 08/11] Separate unnecessary array chaining --- elliptic-curve/src/hash2field/expand_msg_xmd.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs index c3377f676..cd21c06fd 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -79,10 +79,8 @@ where let b_0 = HashT::new() .chain(GenericArray::::default()) .chain(msg) - .chain({ - let l = L::to_u16().to_be_bytes(); - [l[0], l[1], 0u8] - }) + .chain(L::to_u16().to_be_bytes()) + .chain([0]) .chain(domain.data()) .chain([domain.len()]) .finalize(); From b13fc15664844418f74fc5f05173bd0d41e51eac Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 7 Jan 2022 08:33:24 +0100 Subject: [PATCH 09/11] Remove unnecessary constrain --- elliptic-curve/src/hash2field/expand_msg_xof.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs index 88c384e4f..25127f053 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -1,14 +1,13 @@ use super::ExpandMsg; use crate::hash2field::Domain; use digest::{ExtendableOutput, ExtendableOutputDirty, FixedOutput, Update, XofReader}; -use generic_array::typenum::{IsLessOrEqual, NonZero, U256, U32, U65536}; +use generic_array::typenum::{IsLessOrEqual, NonZero, U32, U65536}; use generic_array::ArrayLength; /// Placeholder type for implementing expand_message_xof based on an extendable output function pub struct ExpandMsgXof where HashT: Default + ExtendableOutput + ExtendableOutputDirty + FixedOutput + Update, - HashT::OutputSize: IsLessOrEqual, { reader: ::Reader, } @@ -18,10 +17,6 @@ impl ExpandMsg for ExpandMsgXof where HashT: Default + ExtendableOutput + ExtendableOutputDirty + FixedOutput + Update, L: ArrayLength, - // If `len_in_bytes` is bigger then 256, length of the `DST` will depend on - // the output size of the hash, which is still not allowed to be bigger then 256: - // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.2-5 - HashT::OutputSize: IsLessOrEqual, // Constraint set by `expand_message_xof`: // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.2-5 L: NonZero + IsLessOrEqual, From 2cfdc51191f777e7fdb3d7788b915fdb9d94546a Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 7 Jan 2022 07:55:22 +0100 Subject: [PATCH 10/11] Remove `'static` requirements for DST --- elliptic-curve/src/hash2curve/group_digest.rs | 4 +- elliptic-curve/src/hash2field.rs | 22 ++--- elliptic-curve/src/hash2field/expand_msg.rs | 19 ++-- .../src/hash2field/expand_msg_xmd.rs | 90 +++++++------------ .../src/hash2field/expand_msg_xof.rs | 23 +++-- 5 files changed, 61 insertions(+), 97 deletions(-) diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 84159d79e..4024bbf1c 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -40,7 +40,7 @@ pub trait GroupDigest { /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XOF:SHAKE-256_SSWU_RO_"); /// ``` /// - fn hash_from_bytes(msg: &[u8], dst: &'static [u8]) -> Self::Output + fn hash_from_bytes(msg: &[u8], dst: &[u8]) -> Self::Output where X: ExpandMsg::Length, U2>>, ::Length: Mul, @@ -70,7 +70,7 @@ pub trait GroupDigest { /// uniformly random in G: the set of possible outputs of /// encode_to_curve is only a fraction of the points in G, and some /// points in this set are more likely to be output than others. - fn encode_from_bytes(msg: &[u8], dst: &'static [u8]) -> Self::Output + fn encode_from_bytes(msg: &[u8], dst: &[u8]) -> Self::Output where X: ExpandMsg::Length, U1>>, ::Length: Mul, diff --git a/elliptic-curve/src/hash2field.rs b/elliptic-curve/src/hash2field.rs index 54febaf3d..343f4c9c8 100644 --- a/elliptic-curve/src/hash2field.rs +++ b/elliptic-curve/src/hash2field.rs @@ -7,7 +7,7 @@ use core::ops::Mul; pub use expand_msg::*; pub use expand_msg_xmd::*; pub use expand_msg_xof::*; -use generic_array::typenum::Prod; +use generic_array::typenum::{Prod, Unsigned}; use generic_array::{ArrayLength, GenericArray}; /// The trait for helping to convert to a scalar @@ -21,22 +21,18 @@ pub trait FromOkm { /// Convert an arbitrary byte sequence according to /// -pub fn hash_to_field>( - data: &[u8], - domain: &'static [u8], -) -> GenericArray +pub fn hash_to_field>(data: &[u8], domain: &[u8]) -> GenericArray where E: ExpandMsg>, T: FromOkm + Default, T::Length: Mul, Prod: ArrayLength, { - let mut tmp = GenericArray::::Length>::default(); - let mut expander = E::expand_message(data, domain); - let mut out = GenericArray::default(); - for o in out.iter_mut() { - expander.fill_bytes(&mut tmp); - *o = T::from_okm(&tmp); - } - out + let uniform_bytes = E::expand_message(data, domain); + + uniform_bytes + .chunks_exact(T::Length::to_usize()) + .map(GenericArray::from_slice) + .map(T::from_okm) + .collect() } diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs index 144aa8787..34d20eae6 100644 --- a/elliptic-curve/src/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -9,13 +9,8 @@ const MAX_DST_LEN: usize = 255; /// Trait for types implementing expand_message interface for hash_to_field pub trait ExpandMsg> { - /// Expands `msg` to the required number of bytes - /// Returns an expander that can be used to call `read` until enough - /// bytes have been consumed - fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self; - - /// Fill the array with the expanded bytes - fn fill_bytes(&mut self, okm: &mut [u8]); + /// Expands `msg` to the required number of bytes in `L` + fn expand_message(msg: &[u8], dst: &[u8]) -> GenericArray; } /// The domain separation tag @@ -23,21 +18,21 @@ pub trait ExpandMsg> { /// Implements [section 5.4.3 of `draft-irtf-cfrg-hash-to-curve-13`][dst]. /// /// [dst]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-13#section-5.4.3 -pub(crate) enum Domain +pub(crate) enum Domain<'a, L> where L: ArrayLength + IsLessOrEqual, { /// > 255 Hashed(GenericArray), /// <= 255 - Array(&'static [u8]), + Array(&'a [u8]), } -impl Domain +impl<'a, L> Domain<'a, L> where L: ArrayLength + IsLessOrEqual, { - pub fn xof(dst: &'static [u8]) -> Self + pub fn xof(dst: &'a [u8]) -> Self where X: Default + ExtendableOutputDirty + Update, { @@ -54,7 +49,7 @@ where } } - pub fn xmd(dst: &'static [u8]) -> Self + pub fn xmd(dst: &'a [u8]) -> Self where X: Digest, { diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs index cd21c06fd..eb0d2681b 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -1,54 +1,18 @@ +use core::marker::PhantomData; use core::ops::Mul; use super::{Domain, ExpandMsg}; use digest::{BlockInput, Digest}; use generic_array::typenum::{IsLess, IsLessOrEqual, NonZero, Prod, Unsigned, U255, U256, U65536}; use generic_array::{ArrayLength, GenericArray}; +use subtle::{Choice, ConditionallySelectable}; /// Placeholder type for implementing expand_message_xmd based on a hash function -pub struct ExpandMsgXmd +pub struct ExpandMsgXmd(PhantomData) where HashT: Digest + BlockInput, HashT::OutputSize: IsLessOrEqual, - HashT::OutputSize: IsLessOrEqual, -{ - b_0: GenericArray, - b_vals: GenericArray, - domain: Domain, - index: u8, - offset: usize, - ell: u8, -} - -impl ExpandMsgXmd -where - HashT: Digest + BlockInput, - HashT::OutputSize: IsLessOrEqual, - HashT::OutputSize: IsLessOrEqual, -{ - fn next(&mut self) -> bool { - if self.index < self.ell { - self.index += 1; - self.offset = 0; - // b_0 XOR b_(idx - 1) - let mut tmp = GenericArray::::default(); - self.b_0 - .iter() - .zip(&self.b_vals[..]) - .enumerate() - .for_each(|(j, (b0val, bi1val))| tmp[j] = b0val ^ bi1val); - self.b_vals = HashT::new() - .chain(tmp) - .chain([self.index]) - .chain(self.domain.data()) - .chain([self.domain.len()]) - .finalize(); - true - } else { - false - } - } -} + HashT::OutputSize: IsLessOrEqual; /// ExpandMsgXmd implements expand_message_xmd for the ExpandMsg trait impl ExpandMsg for ExpandMsgXmd @@ -67,7 +31,7 @@ where // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-6 L: NonZero + IsLess> + IsLess, { - fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self { + fn expand_message(msg: &[u8], dst: &[u8]) -> GenericArray { let b_in_bytes = HashT::OutputSize::to_u16(); // Can't overflow because enforced on a type level. let ell = ((L::to_u16() + b_in_bytes - 1) / b_in_bytes) as u8; @@ -85,30 +49,42 @@ where .chain([domain.len()]) .finalize(); - let b_vals = HashT::new() + let mut b_vals = HashT::new() .chain(&b_0[..]) .chain([1u8]) .chain(domain.data()) .chain([domain.len()]) .finalize(); - Self { - b_0, - b_vals, - domain, - index: 1, - offset: 0, - ell, - } - } + let mut buf = GenericArray::<_, L>::default(); + let mut offset = 0; - fn fill_bytes(&mut self, okm: &mut [u8]) { - for b in okm { - if self.offset == self.b_vals.len() && !self.next() { - return; + for i in 1..ell { + // b_0 XOR b_(idx - 1) + let tmp: GenericArray<_, HashT::OutputSize> = b_0 + .iter() + .zip(b_vals.as_slice()) + .map(|(b0val, bi1val)| b0val ^ bi1val) + .collect(); + for b in b_vals { + buf[offset % L::to_usize()].conditional_assign( + &b, + Choice::from(if offset < L::to_usize() { 1 } else { 0 }), + ); + offset += 1; } - *b = self.b_vals[self.offset]; - self.offset += 1; + b_vals = HashT::new() + .chain(tmp) + .chain([i + 1]) + .chain(domain.data()) + .chain([domain.len()]) + .finalize(); + } + for b in b_vals { + buf[offset % L::to_usize()] + .conditional_assign(&b, Choice::from(if offset < L::to_usize() { 1 } else { 0 })); + offset += 1; } + buf } } diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs index 25127f053..fe3cc76c1 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -1,16 +1,15 @@ +use core::marker::PhantomData; + use super::ExpandMsg; use crate::hash2field::Domain; use digest::{ExtendableOutput, ExtendableOutputDirty, FixedOutput, Update, XofReader}; use generic_array::typenum::{IsLessOrEqual, NonZero, U32, U65536}; -use generic_array::ArrayLength; +use generic_array::{ArrayLength, GenericArray}; /// Placeholder type for implementing expand_message_xof based on an extendable output function -pub struct ExpandMsgXof +pub struct ExpandMsgXof(PhantomData) where - HashT: Default + ExtendableOutput + ExtendableOutputDirty + FixedOutput + Update, -{ - reader: ::Reader, -} + HashT: Default + ExtendableOutput + ExtendableOutputDirty + FixedOutput + Update; /// ExpandMsgXof implements expand_message_xof for the ExpandMsg trait impl ExpandMsg for ExpandMsgXof @@ -21,18 +20,16 @@ where // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.2-5 L: NonZero + IsLessOrEqual, { - fn expand_message(msg: &[u8], dst: &'static [u8]) -> Self { + fn expand_message(msg: &[u8], dst: &[u8]) -> GenericArray { let domain = Domain::::xof::(dst); - let reader = HashT::default() + let mut reader = HashT::default() .chain(msg) .chain(L::to_u16().to_be_bytes()) .chain(domain.data()) .chain([domain.len()]) .finalize_xof(); - Self { reader } - } - - fn fill_bytes(&mut self, okm: &mut [u8]) { - self.reader.read(okm); + let mut buf = GenericArray::default(); + reader.read(&mut buf); + buf } } From 14d8ff69df8123f823c0b62e084247665c72ff03 Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 7 Jan 2022 08:31:55 +0100 Subject: [PATCH 11/11] Update digest to 0.10 --- elliptic-curve/Cargo.lock | 45 ++++++++++++++++++- elliptic-curve/Cargo.toml | 3 +- elliptic-curve/src/hash2curve/group_digest.rs | 6 +-- elliptic-curve/src/hash2field/expand_msg.rs | 8 ++-- .../src/hash2field/expand_msg_xmd.rs | 7 +-- .../src/hash2field/expand_msg_xof.rs | 6 +-- elliptic-curve/src/ops.rs | 6 +-- 7 files changed, 61 insertions(+), 20 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 812bece07..cffaa4681 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -20,6 +20,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "block-buffer" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" +dependencies = [ + "generic-array", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -32,6 +41,15 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + [[package]] name = "crypto-bigint" version = "0.3.2" @@ -44,6 +62,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +dependencies = [ + "generic-array", +] + [[package]] name = "der" version = "0.5.1" @@ -56,10 +83,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" dependencies = [ + "block-buffer", + "crypto-common", "generic-array", ] @@ -80,6 +109,7 @@ dependencies = [ "sec1", "serde", "serde_json", + "sha2", "subtle", "zeroize", ] @@ -222,6 +252,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "spki" version = "0.5.3" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 0f48d46ab..80ad9a029 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -29,7 +29,7 @@ zeroize = { version = "1", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false } -digest = { version = "0.9", optional = true, default-features = false } +digest = { version = "0.10", optional = true } ff = { version = "0.11", optional = true, default-features = false } group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } @@ -40,6 +40,7 @@ serde_json = { version = "1", optional = true, default-features = false, feature [dev-dependencies] hex-literal = "0.3" +sha2 = "0.10" [features] default = ["arithmetic"] diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 4024bbf1c..fce3993a8 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -2,10 +2,8 @@ use core::ops::Mul; use super::MapToCurve; use crate::hash2field::{hash_to_field, ExpandMsg, FromOkm}; -use generic_array::{ - typenum::{Prod, U1, U2}, - ArrayLength, -}; +use generic_array::typenum::{Prod, U1, U2}; +use generic_array::ArrayLength; use group::cofactor::CofactorGroup; /// Adds hashing arbitrary byte sequences to a valid group element diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs index 34d20eae6..1cf9e5e62 100644 --- a/elliptic-curve/src/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -1,4 +1,4 @@ -use digest::{Digest, ExtendableOutputDirty, Update, XofReader}; +use digest::{Digest, ExtendableOutput, Update, XofReader}; use generic_array::typenum::{IsLessOrEqual, U256}; use generic_array::{ArrayLength, GenericArray}; @@ -34,14 +34,14 @@ where { pub fn xof(dst: &'a [u8]) -> Self where - X: Default + ExtendableOutputDirty + Update, + X: Default + ExtendableOutput + Update, { if dst.len() > MAX_DST_LEN { let mut data = GenericArray::::default(); X::default() .chain(OVERSIZE_DST_SALT) .chain(dst) - .finalize_xof_dirty() + .finalize_xof() .read(&mut data); Self::Hashed(data) } else { @@ -51,7 +51,7 @@ where pub fn xmd(dst: &'a [u8]) -> Self where - X: Digest, + X: Digest + Update, { if dst.len() > MAX_DST_LEN { Self::Hashed(X::new().chain(OVERSIZE_DST_SALT).chain(dst).finalize()) diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs index eb0d2681b..57deecff3 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -2,7 +2,8 @@ use core::marker::PhantomData; use core::ops::Mul; use super::{Domain, ExpandMsg}; -use digest::{BlockInput, Digest}; +use digest::core_api::BlockSizeUser; +use digest::{Digest, Update}; use generic_array::typenum::{IsLess, IsLessOrEqual, NonZero, Prod, Unsigned, U255, U256, U65536}; use generic_array::{ArrayLength, GenericArray}; use subtle::{Choice, ConditionallySelectable}; @@ -10,14 +11,14 @@ use subtle::{Choice, ConditionallySelectable}; /// Placeholder type for implementing expand_message_xmd based on a hash function pub struct ExpandMsgXmd(PhantomData) where - HashT: Digest + BlockInput, + HashT: Digest + BlockSizeUser + Update, HashT::OutputSize: IsLessOrEqual, HashT::OutputSize: IsLessOrEqual; /// ExpandMsgXmd implements expand_message_xmd for the ExpandMsg trait impl ExpandMsg for ExpandMsgXmd where - HashT: Digest + BlockInput, + HashT: Digest + BlockSizeUser + Update, L: ArrayLength, U255: Mul, // If `len_in_bytes` is bigger then 256, length of the `DST` will depend on diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs index fe3cc76c1..62f14b7a3 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -2,19 +2,19 @@ use core::marker::PhantomData; use super::ExpandMsg; use crate::hash2field::Domain; -use digest::{ExtendableOutput, ExtendableOutputDirty, FixedOutput, Update, XofReader}; +use digest::{ExtendableOutput, Update, XofReader}; use generic_array::typenum::{IsLessOrEqual, NonZero, U32, U65536}; use generic_array::{ArrayLength, GenericArray}; /// Placeholder type for implementing expand_message_xof based on an extendable output function pub struct ExpandMsgXof(PhantomData) where - HashT: Default + ExtendableOutput + ExtendableOutputDirty + FixedOutput + Update; + HashT: Default + ExtendableOutput + Update; /// ExpandMsgXof implements expand_message_xof for the ExpandMsg trait impl ExpandMsg for ExpandMsgXof where - HashT: Default + ExtendableOutput + ExtendableOutputDirty + FixedOutput + Update, + HashT: Default + ExtendableOutput + Update, L: ArrayLength, // Constraint set by `expand_message_xof`: // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.2-5 diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index d8038d931..8bbd622d2 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -9,7 +9,7 @@ use subtle::CtOption; use group::Group; #[cfg(feature = "digest")] -use digest::{BlockInput, Digest, FixedOutput, Reset, Update}; +use digest::{Digest, FixedOutput, Reset, Update}; /// Perform an inversion on a field element (i.e. base field element or scalar) pub trait Invert { @@ -67,7 +67,7 @@ pub trait Reduce: Sized { #[cfg_attr(docsrs, doc(cfg(feature = "digest")))] fn from_be_digest_reduced(digest: D) -> Self where - D: FixedOutput + BlockInput + Clone + Default + Reset + Update, + D: FixedOutput + Digest + Clone + Default + Reset + Update, { Self::from_be_bytes_reduced(digest.finalize()) } @@ -78,7 +78,7 @@ pub trait Reduce: Sized { #[cfg_attr(docsrs, doc(cfg(feature = "digest")))] fn from_le_digest_reduced(digest: D) -> Self where - D: FixedOutput + BlockInput + Clone + Default + Reset + Update, + D: FixedOutput + Digest + Clone + Default + Reset + Update, { Self::from_le_bytes_reduced(digest.finalize()) }