@@ -204,15 +204,15 @@ impl AlgoKind {
204204 /// When checking untagged format lines, non-XOF non-legacy algorithms
205205 /// should report "improperly formatted lines" if the digest length isn't
206206 /// equivalent to this.
207- pub fn expected_digest_bit_len ( self ) -> Option < usize > {
207+ pub fn expected_digest_bit_len ( self ) -> Option < HashLength > {
208208 match self {
209- Self :: Md5 => Some ( Md5 :: BIT_SIZE ) ,
210- Self :: Sm3 => Some ( Sm3 :: BIT_SIZE ) ,
211- Self :: Sha1 => Some ( Sha1 :: BIT_SIZE ) ,
212- Self :: Sha224 => Some ( Sha224 :: BIT_SIZE ) ,
213- Self :: Sha256 => Some ( Sha256 :: BIT_SIZE ) ,
214- Self :: Sha384 => Some ( Sha384 :: BIT_SIZE ) ,
215- Self :: Sha512 => Some ( Sha512 :: BIT_SIZE ) ,
209+ Self :: Md5 => Some ( HashLength ( Md5 :: BIT_SIZE ) ) ,
210+ Self :: Sm3 => Some ( HashLength ( Sm3 :: BIT_SIZE ) ) ,
211+ Self :: Sha1 => Some ( HashLength ( Sha1 :: BIT_SIZE ) ) ,
212+ Self :: Sha224 => Some ( HashLength ( Sha224 :: BIT_SIZE ) ) ,
213+ Self :: Sha256 => Some ( HashLength ( Sha256 :: BIT_SIZE ) ) ,
214+ Self :: Sha384 => Some ( HashLength ( Sha384 :: BIT_SIZE ) ) ,
215+ Self :: Sha512 => Some ( HashLength ( Sha512 :: BIT_SIZE ) ) ,
216216 _ => None ,
217217 }
218218 }
@@ -253,6 +253,42 @@ impl TryFrom<usize> for ShaLength {
253253 }
254254}
255255
256+ /// Stores a hash length in bits.
257+ #[ derive( Debug , Clone , Copy ) ]
258+ pub struct HashLength ( usize ) ;
259+
260+ impl HashLength {
261+ #[ must_use]
262+ #[ inline]
263+ pub ( crate ) fn from_bytes ( n : usize ) -> Self {
264+ Self ( n * 8 )
265+ }
266+
267+ #[ must_use]
268+ #[ inline]
269+ pub fn from_bits ( n : usize ) -> Self {
270+ Self ( n)
271+ }
272+
273+ #[ must_use]
274+ #[ inline]
275+ pub ( crate ) fn as_bits ( self ) -> usize {
276+ self . 0
277+ }
278+
279+ #[ must_use]
280+ #[ inline]
281+ pub ( crate ) fn as_bytes ( self ) -> usize {
282+ self . 0 . div_ceil ( 8 )
283+ }
284+ }
285+
286+ impl From < ShaLength > for HashLength {
287+ fn from ( value : ShaLength ) -> Self {
288+ Self ( value. as_usize ( ) )
289+ }
290+ }
291+
256292/// Represents an actual determined algorithm.
257293#[ derive( Debug , Clone , Copy ) ]
258294pub enum SizedAlgoKind {
@@ -266,15 +302,15 @@ pub enum SizedAlgoKind {
266302 Sha2 ( ShaLength ) ,
267303 Sha3 ( ShaLength ) ,
268304 // Note: we store Blake*'s length as BYTES.
269- Blake2b ( usize ) ,
270- Blake3 ( usize ) ,
305+ Blake2b ( HashLength ) ,
306+ Blake3 ( HashLength ) ,
271307 // Shake* length are stored in bits.
272- Shake128 ( Option < usize > ) ,
273- Shake256 ( Option < usize > ) ,
308+ Shake128 ( Option < HashLength > ) ,
309+ Shake256 ( Option < HashLength > ) ,
274310}
275311
276312impl SizedAlgoKind {
277- pub fn from_unsized ( kind : AlgoKind , output_length : Option < usize > ) -> UResult < Self > {
313+ pub fn from_unsized ( kind : AlgoKind , output_length : Option < HashLength > ) -> UResult < Self > {
278314 use AlgoKind as ak;
279315 match ( kind, output_length) {
280316 (
@@ -300,12 +336,16 @@ impl SizedAlgoKind {
300336 ( ak:: Sm3 , _) => Ok ( Self :: Sm3 ) ,
301337 ( ak:: Sha1 , _) => Ok ( Self :: Sha1 ) ,
302338
303- ( ak:: Blake2b , l) => Ok ( Self :: Blake2b ( l. unwrap_or ( Blake2b :: DEFAULT_BYTE_SIZE ) ) ) ,
304- ( ak:: Blake3 , l) => Ok ( Self :: Blake3 ( l. unwrap_or ( Blake3 :: DEFAULT_BYTE_SIZE ) ) ) ,
339+ ( ak:: Blake2b , l) => Ok ( Self :: Blake2b (
340+ l. unwrap_or ( HashLength :: from_bits ( Blake2b :: DEFAULT_BIT_SIZE ) ) ,
341+ ) ) ,
342+ ( ak:: Blake3 , l) => Ok ( Self :: Blake3 (
343+ l. unwrap_or ( HashLength :: from_bits ( Blake3 :: DEFAULT_BIT_SIZE ) ) ,
344+ ) ) ,
305345 ( ak:: Shake128 , l) => Ok ( Self :: Shake128 ( l) ) ,
306346 ( ak:: Shake256 , l) => Ok ( Self :: Shake256 ( l) ) ,
307- ( ak:: Sha2 , Some ( l) ) => Ok ( Self :: Sha2 ( ShaLength :: try_from ( l) ?) ) ,
308- ( ak:: Sha3 , Some ( l) ) => Ok ( Self :: Sha3 ( ShaLength :: try_from ( l) ?) ) ,
347+ ( ak:: Sha2 , Some ( l) ) => Ok ( Self :: Sha2 ( ShaLength :: try_from ( l. as_bits ( ) ) ?) ) ,
348+ ( ak:: Sha3 , Some ( l) ) => Ok ( Self :: Sha3 ( ShaLength :: try_from ( l. as_bits ( ) ) ?) ) ,
309349 ( algo @ ( ak:: Sha2 | ak:: Sha3 ) , None ) => {
310350 Err ( ChecksumError :: LengthRequiredForSha ( algo. to_lowercase ( ) . into ( ) ) . into ( ) )
311351 }
@@ -323,16 +363,16 @@ impl SizedAlgoKind {
323363 Self :: Sha1 => "SHA1" . into ( ) ,
324364 Self :: Sha2 ( len) => format ! ( "SHA{}" , len. as_usize( ) ) ,
325365 Self :: Sha3 ( len) => format ! ( "SHA3-{}" , len. as_usize( ) ) ,
326- Self :: Blake2b ( Blake2b :: DEFAULT_BYTE_SIZE ) => "BLAKE2b" . into ( ) ,
327- Self :: Blake2b ( byte_len ) => format ! ( "BLAKE2b-{}" , byte_len * 8 ) ,
328- Self :: Blake3 ( byte_len ) => format ! ( "BLAKE3-{}" , byte_len * 8 ) ,
329- Self :: Shake128 ( opt_bit_len ) => format ! (
366+ Self :: Blake2b ( len ) if len . as_bits ( ) == Blake2b :: DEFAULT_BIT_SIZE => "BLAKE2b" . into ( ) ,
367+ Self :: Blake2b ( len ) => format ! ( "BLAKE2b-{}" , len . as_bits ( ) ) ,
368+ Self :: Blake3 ( len ) => format ! ( "BLAKE3-{}" , len . as_bits ( ) ) ,
369+ Self :: Shake128 ( opt_len ) => format ! (
330370 "SHAKE128-{}" ,
331- opt_bit_len . unwrap_or ( Shake128 :: DEFAULT_BIT_SIZE )
371+ opt_len . map_or ( Shake128 :: DEFAULT_BIT_SIZE , HashLength :: as_bits )
332372 ) ,
333- Self :: Shake256 ( opt_bit_len ) => format ! (
373+ Self :: Shake256 ( opt_len ) => format ! (
334374 "SHAKE256-{}" ,
335- opt_bit_len . unwrap_or ( Shake256 :: DEFAULT_BIT_SIZE )
375+ opt_len . map_or ( Shake256 :: DEFAULT_BIT_SIZE , HashLength :: as_bits )
336376 ) ,
337377 Self :: Sysv | Self :: Bsd | Self :: Crc | Self :: Crc32b => {
338378 panic ! ( "Should not be used for tagging" )
@@ -358,14 +398,20 @@ impl SizedAlgoKind {
358398 Self :: Sha3 ( Len256 ) => Box :: new ( Sha3_256 :: default ( ) ) ,
359399 Self :: Sha3 ( Len384 ) => Box :: new ( Sha3_384 :: default ( ) ) ,
360400 Self :: Sha3 ( Len512 ) => Box :: new ( Sha3_512 :: default ( ) ) ,
361- Self :: Blake2b ( len) => Box :: new ( Blake2b :: with_output_bytes ( * len) ) ,
362- Self :: Blake3 ( len) => Box :: new ( Blake3 :: with_output_bytes ( * len) ) ,
363- Self :: Shake128 ( len_opt) => {
364- Box :: new ( len_opt. map ( Shake128 :: with_output_bits) . unwrap_or_default ( ) )
365- }
366- Self :: Shake256 ( len_opt) => {
367- Box :: new ( len_opt. map ( Shake256 :: with_output_bits) . unwrap_or_default ( ) )
368- }
401+ Self :: Blake2b ( len) => Box :: new ( Blake2b :: with_output_bytes ( len. as_bytes ( ) ) ) ,
402+ Self :: Blake3 ( len) => Box :: new ( Blake3 :: with_output_bytes ( len. as_bytes ( ) ) ) ,
403+ Self :: Shake128 ( len_opt) => Box :: new (
404+ len_opt
405+ . map ( HashLength :: as_bits)
406+ . map ( Shake128 :: with_output_bits)
407+ . unwrap_or_default ( ) ,
408+ ) ,
409+ Self :: Shake256 ( len_opt) => Box :: new (
410+ len_opt
411+ . map ( HashLength :: as_bits)
412+ . map ( Shake256 :: with_output_bits)
413+ . unwrap_or_default ( ) ,
414+ ) ,
369415 }
370416 }
371417
@@ -380,10 +426,10 @@ impl SizedAlgoKind {
380426 Self :: Sha1 => 160 ,
381427 Self :: Sha2 ( len) => len. as_usize ( ) ,
382428 Self :: Sha3 ( len) => len. as_usize ( ) ,
383- Self :: Blake2b ( len) => len * 8 ,
384- Self :: Blake3 ( len) => len * 8 ,
385- Self :: Shake128 ( len) => len. unwrap_or ( Shake128 :: DEFAULT_BIT_SIZE ) ,
386- Self :: Shake256 ( len) => len. unwrap_or ( Shake256 :: DEFAULT_BIT_SIZE ) ,
429+ Self :: Blake2b ( len) => len. as_bits ( ) ,
430+ Self :: Blake3 ( len) => len. as_bits ( ) ,
431+ Self :: Shake128 ( len) => len. map_or ( Shake128 :: DEFAULT_BIT_SIZE , HashLength :: as_bits ) ,
432+ Self :: Shake256 ( len) => len. map_or ( Shake256 :: DEFAULT_BIT_SIZE , HashLength :: as_bits ) ,
387433 }
388434 }
389435 pub fn is_legacy ( & self ) -> bool {
@@ -506,7 +552,7 @@ pub enum BlakeLength<'s> {
506552/// Note: when the input is a string, validation may print error messages.
507553/// Note: when the algo is Blake2b, values that are above 512
508554/// (Blake2b::DEFAULT_BIT_SIZE) are errors.
509- pub fn parse_blake_length ( algo : AlgoKind , bit_length : BlakeLength < ' _ > ) -> UResult < usize > {
555+ pub fn parse_blake_length ( algo : AlgoKind , bit_length : BlakeLength < ' _ > ) -> UResult < HashLength > {
510556 debug_assert ! ( matches!( algo, AlgoKind :: Blake2b | AlgoKind :: Blake3 ) ) ;
511557
512558 let print_error = || {
@@ -529,8 +575,8 @@ pub fn parse_blake_length(algo: AlgoKind, bit_length: BlakeLength<'_>) -> UResul
529575
530576 if n == 0 {
531577 return Ok ( match algo {
532- AlgoKind :: Blake2b => Blake2b :: DEFAULT_BYTE_SIZE ,
533- AlgoKind :: Blake3 => Blake3 :: DEFAULT_BYTE_SIZE ,
578+ AlgoKind :: Blake2b => HashLength :: from_bits ( Blake2b :: DEFAULT_BIT_SIZE ) ,
579+ AlgoKind :: Blake3 => HashLength :: from_bits ( Blake3 :: DEFAULT_BIT_SIZE ) ,
534580 _ => unreachable ! ( ) ,
535581 } ) ;
536582 }
@@ -545,7 +591,7 @@ pub fn parse_blake_length(algo: AlgoKind, bit_length: BlakeLength<'_>) -> UResul
545591 return Err ( ChecksumError :: LengthNotMultipleOf8 . into ( ) ) ;
546592 }
547593
548- Ok ( n / 8 )
594+ Ok ( HashLength :: from_bits ( n ) )
549595}
550596
551597pub fn validate_sha2_sha3_length ( algo_name : AlgoKind , length : Option < usize > ) -> UResult < ShaLength > {
@@ -562,7 +608,7 @@ pub fn validate_sha2_sha3_length(algo_name: AlgoKind, length: Option<usize>) ->
562608 }
563609}
564610
565- pub fn sanitize_sha2_sha3_length_str ( algo_kind : AlgoKind , length : & str ) -> UResult < usize > {
611+ pub fn sanitize_sha2_sha3_length_str ( algo_kind : AlgoKind , length : & str ) -> UResult < HashLength > {
566612 // There is a difference in the errors sent when the length is not a number
567613 // vs. its an invalid number.
568614 //
@@ -580,7 +626,7 @@ pub fn sanitize_sha2_sha3_length_str(algo_kind: AlgoKind, length: &str) -> UResu
580626 } ;
581627
582628 if [ 224 , 256 , 384 , 512 ] . contains ( & len) {
583- Ok ( len)
629+ Ok ( HashLength :: from_bits ( len) )
584630 } else {
585631 show_error ! ( "{}" , ChecksumError :: InvalidLength ( length. into( ) ) ) ;
586632 Err ( ChecksumError :: InvalidLengthForSha ( algo_kind. to_uppercase ( ) . into ( ) ) . into ( ) )
@@ -664,17 +710,23 @@ mod tests {
664710 #[ test]
665711 fn test_calculate_blake2b_length ( ) {
666712 assert_eq ! (
667- parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "0" ) ) . unwrap( ) ,
713+ parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "0" ) )
714+ . unwrap( )
715+ . as_bytes( ) ,
668716 Blake2b :: DEFAULT_BYTE_SIZE
669717 ) ;
670718 assert ! ( parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "10" ) ) . is_err( ) ) ;
671719 assert ! ( parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "520" ) ) . is_err( ) ) ;
672720 assert_eq ! (
673- parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "512" ) ) . unwrap( ) ,
721+ parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "512" ) )
722+ . unwrap( )
723+ . as_bytes( ) ,
674724 Blake2b :: DEFAULT_BYTE_SIZE
675725 ) ;
676726 assert_eq ! (
677- parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "256" ) ) . unwrap( ) ,
727+ parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "256" ) )
728+ . unwrap( )
729+ . as_bytes( ) ,
678730 32
679731 ) ;
680732 }
0 commit comments