@@ -253,6 +253,60 @@ impl TryFrom<usize> for ShaLength {
253253 }
254254}
255255
256+ #[ derive( Debug , Clone , Copy ) ]
257+ pub struct XOFLength ( usize ) ;
258+ impl XOFLength {
259+ #[ inline]
260+ pub ( crate ) fn from_bytes ( n : usize ) -> Self {
261+ Self ( n * 8 )
262+ }
263+
264+ #[ inline]
265+ pub ( crate ) fn from_bits ( n : usize ) -> Self {
266+ Self ( n)
267+ }
268+
269+ #[ inline]
270+ pub ( crate ) fn as_bits ( self ) -> usize {
271+ self . 0
272+ }
273+
274+ #[ inline]
275+ pub ( crate ) fn as_bytes ( self ) -> usize {
276+ self . 0 . div_ceil ( 8 )
277+ }
278+ }
279+
280+ #[ derive( Debug , Clone , Copy ) ]
281+ pub enum HashLength {
282+ Byte ( usize ) ,
283+ Bit ( usize ) ,
284+ }
285+
286+ impl HashLength {
287+ pub fn from_bytes ( n : usize ) -> Self {
288+ Self :: Byte ( n)
289+ }
290+
291+ pub fn from_bits ( n : usize ) -> Self {
292+ Self :: Bit ( n)
293+ }
294+
295+ pub fn as_bits ( self ) -> usize {
296+ match self {
297+ HashLength :: Byte ( n) => n * 8 ,
298+ HashLength :: Bit ( n) => n,
299+ }
300+ }
301+
302+ pub ( crate ) fn as_bytes ( self ) -> usize {
303+ match self {
304+ HashLength :: Byte ( n) => n,
305+ HashLength :: Bit ( n) => n. div_ceil ( 8 ) ,
306+ }
307+ }
308+ }
309+
256310/// Represents an actual determined algorithm.
257311#[ derive( Debug , Clone , Copy ) ]
258312pub enum SizedAlgoKind {
@@ -266,15 +320,15 @@ pub enum SizedAlgoKind {
266320 Sha2 ( ShaLength ) ,
267321 Sha3 ( ShaLength ) ,
268322 // Note: we store Blake*'s length as BYTES.
269- Blake2b ( usize ) ,
270- Blake3 ( usize ) ,
323+ Blake2b ( XOFLength ) ,
324+ Blake3 ( XOFLength ) ,
271325 // Shake* length are stored in bits.
272- Shake128 ( Option < usize > ) ,
273- Shake256 ( Option < usize > ) ,
326+ Shake128 ( Option < XOFLength > ) ,
327+ Shake256 ( Option < XOFLength > ) ,
274328}
275329
276330impl SizedAlgoKind {
277- pub fn from_unsized ( kind : AlgoKind , output_length : Option < usize > ) -> UResult < Self > {
331+ pub fn from_unsized ( kind : AlgoKind , output_length : Option < HashLength > ) -> UResult < Self > {
278332 use AlgoKind as ak;
279333 match ( kind, output_length) {
280334 (
@@ -300,12 +354,20 @@ impl SizedAlgoKind {
300354 ( ak:: Sm3 , _) => Ok ( Self :: Sm3 ) ,
301355 ( ak:: Sha1 , _) => Ok ( Self :: Sha1 ) ,
302356
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 ) ) ) ,
305- ( ak:: Shake128 , l) => Ok ( Self :: Shake128 ( l) ) ,
306- ( 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) ?) ) ,
357+ ( ak:: Blake2b , l) => Ok ( Self :: Blake2b ( XOFLength :: from_bits (
358+ l. map_or ( Blake2b :: DEFAULT_BIT_SIZE , HashLength :: as_bits) ,
359+ ) ) ) ,
360+ ( ak:: Blake3 , l) => Ok ( Self :: Blake3 ( XOFLength :: from_bits (
361+ l. map_or ( Blake3 :: DEFAULT_BIT_SIZE , HashLength :: as_bits) ,
362+ ) ) ) ,
363+ ( ak:: Shake128 , l) => Ok ( Self :: Shake128 (
364+ l. map ( HashLength :: as_bits) . map ( XOFLength :: from_bits) ,
365+ ) ) ,
366+ ( ak:: Shake256 , l) => Ok ( Self :: Shake256 (
367+ l. map ( HashLength :: as_bits) . map ( XOFLength :: from_bits) ,
368+ ) ) ,
369+ ( ak:: Sha2 , Some ( l) ) => Ok ( Self :: Sha2 ( ShaLength :: try_from ( l. as_bits ( ) ) ?) ) ,
370+ ( ak:: Sha3 , Some ( l) ) => Ok ( Self :: Sha3 ( ShaLength :: try_from ( l. as_bits ( ) ) ?) ) ,
309371 ( algo @ ( ak:: Sha2 | ak:: Sha3 ) , None ) => {
310372 Err ( ChecksumError :: LengthRequiredForSha ( algo. to_lowercase ( ) . into ( ) ) . into ( ) )
311373 }
@@ -323,16 +385,16 @@ impl SizedAlgoKind {
323385 Self :: Sha1 => "SHA1" . into ( ) ,
324386 Self :: Sha2 ( len) => format ! ( "SHA{}" , len. as_usize( ) ) ,
325387 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 ! (
388+ Self :: Blake2b ( len ) if len . as_bits ( ) == Blake2b :: DEFAULT_BIT_SIZE => "BLAKE2b" . into ( ) ,
389+ Self :: Blake2b ( len ) => format ! ( "BLAKE2b-{}" , len . as_bits ( ) ) ,
390+ Self :: Blake3 ( len ) => format ! ( "BLAKE3-{}" , len . as_bits ( ) ) ,
391+ Self :: Shake128 ( opt_len ) => format ! (
330392 "SHAKE128-{}" ,
331- opt_bit_len . unwrap_or ( Shake128 :: DEFAULT_BIT_SIZE )
393+ opt_len . map_or ( Shake128 :: DEFAULT_BIT_SIZE , XOFLength :: as_bits )
332394 ) ,
333- Self :: Shake256 ( opt_bit_len ) => format ! (
395+ Self :: Shake256 ( opt_len ) => format ! (
334396 "SHAKE256-{}" ,
335- opt_bit_len . unwrap_or ( Shake256 :: DEFAULT_BIT_SIZE )
397+ opt_len . map_or ( Shake256 :: DEFAULT_BIT_SIZE , XOFLength :: as_bits )
336398 ) ,
337399 Self :: Sysv | Self :: Bsd | Self :: Crc | Self :: Crc32b => {
338400 panic ! ( "Should not be used for tagging" )
@@ -358,14 +420,20 @@ impl SizedAlgoKind {
358420 Self :: Sha3 ( Len256 ) => Box :: new ( Sha3_256 :: default ( ) ) ,
359421 Self :: Sha3 ( Len384 ) => Box :: new ( Sha3_384 :: default ( ) ) ,
360422 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- }
423+ Self :: Blake2b ( len) => Box :: new ( Blake2b :: with_output_bytes ( len. as_bytes ( ) ) ) ,
424+ Self :: Blake3 ( len) => Box :: new ( Blake3 :: with_output_bytes ( len. as_bytes ( ) ) ) ,
425+ Self :: Shake128 ( len_opt) => Box :: new (
426+ len_opt
427+ . map ( XOFLength :: as_bits)
428+ . map ( Shake128 :: with_output_bits)
429+ . unwrap_or_default ( ) ,
430+ ) ,
431+ Self :: Shake256 ( len_opt) => Box :: new (
432+ len_opt
433+ . map ( XOFLength :: as_bits)
434+ . map ( Shake256 :: with_output_bits)
435+ . unwrap_or_default ( ) ,
436+ ) ,
369437 }
370438 }
371439
@@ -380,10 +448,10 @@ impl SizedAlgoKind {
380448 Self :: Sha1 => 160 ,
381449 Self :: Sha2 ( len) => len. as_usize ( ) ,
382450 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 ) ,
451+ Self :: Blake2b ( len) => len. as_bits ( ) ,
452+ Self :: Blake3 ( len) => len. as_bits ( ) ,
453+ Self :: Shake128 ( len) => len. map_or ( Shake128 :: DEFAULT_BIT_SIZE , XOFLength :: as_bits ) ,
454+ Self :: Shake256 ( len) => len. map_or ( Shake256 :: DEFAULT_BIT_SIZE , XOFLength :: as_bits ) ,
387455 }
388456 }
389457 pub fn is_legacy ( & self ) -> bool {
@@ -506,7 +574,7 @@ pub enum BlakeLength<'s> {
506574/// Note: when the input is a string, validation may print error messages.
507575/// Note: when the algo is Blake2b, values that are above 512
508576/// (Blake2b::DEFAULT_BIT_SIZE) are errors.
509- pub fn parse_blake_length ( algo : AlgoKind , bit_length : BlakeLength < ' _ > ) -> UResult < usize > {
577+ pub fn parse_blake_length ( algo : AlgoKind , bit_length : BlakeLength < ' _ > ) -> UResult < HashLength > {
510578 debug_assert ! ( matches!( algo, AlgoKind :: Blake2b | AlgoKind :: Blake3 ) ) ;
511579
512580 let print_error = || {
@@ -529,8 +597,8 @@ pub fn parse_blake_length(algo: AlgoKind, bit_length: BlakeLength<'_>) -> UResul
529597
530598 if n == 0 {
531599 return Ok ( match algo {
532- AlgoKind :: Blake2b => Blake2b :: DEFAULT_BYTE_SIZE ,
533- AlgoKind :: Blake3 => Blake3 :: DEFAULT_BYTE_SIZE ,
600+ AlgoKind :: Blake2b => HashLength :: Bit ( Blake2b :: DEFAULT_BIT_SIZE ) ,
601+ AlgoKind :: Blake3 => HashLength :: Bit ( Blake3 :: DEFAULT_BIT_SIZE ) ,
534602 _ => unreachable ! ( ) ,
535603 } ) ;
536604 }
@@ -545,7 +613,7 @@ pub fn parse_blake_length(algo: AlgoKind, bit_length: BlakeLength<'_>) -> UResul
545613 return Err ( ChecksumError :: LengthNotMultipleOf8 . into ( ) ) ;
546614 }
547615
548- Ok ( n / 8 )
616+ Ok ( HashLength :: Bit ( n ) )
549617}
550618
551619pub fn validate_sha2_sha3_length ( algo_name : AlgoKind , length : Option < usize > ) -> UResult < ShaLength > {
@@ -562,7 +630,7 @@ pub fn validate_sha2_sha3_length(algo_name: AlgoKind, length: Option<usize>) ->
562630 }
563631}
564632
565- pub fn sanitize_sha2_sha3_length_str ( algo_kind : AlgoKind , length : & str ) -> UResult < usize > {
633+ pub fn sanitize_sha2_sha3_length_str ( algo_kind : AlgoKind , length : & str ) -> UResult < HashLength > {
566634 // There is a difference in the errors sent when the length is not a number
567635 // vs. its an invalid number.
568636 //
@@ -580,7 +648,7 @@ pub fn sanitize_sha2_sha3_length_str(algo_kind: AlgoKind, length: &str) -> UResu
580648 } ;
581649
582650 if [ 224 , 256 , 384 , 512 ] . contains ( & len) {
583- Ok ( len)
651+ Ok ( HashLength :: Bit ( len) )
584652 } else {
585653 show_error ! ( "{}" , ChecksumError :: InvalidLength ( length. into( ) ) ) ;
586654 Err ( ChecksumError :: InvalidLengthForSha ( algo_kind. to_uppercase ( ) . into ( ) ) . into ( ) )
@@ -664,17 +732,23 @@ mod tests {
664732 #[ test]
665733 fn test_calculate_blake2b_length ( ) {
666734 assert_eq ! (
667- parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "0" ) ) . unwrap( ) ,
735+ parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "0" ) )
736+ . unwrap( )
737+ . as_bytes( ) ,
668738 Blake2b :: DEFAULT_BYTE_SIZE
669739 ) ;
670740 assert ! ( parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "10" ) ) . is_err( ) ) ;
671741 assert ! ( parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "520" ) ) . is_err( ) ) ;
672742 assert_eq ! (
673- parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "512" ) ) . unwrap( ) ,
743+ parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "512" ) )
744+ . unwrap( )
745+ . as_bytes( ) ,
674746 Blake2b :: DEFAULT_BYTE_SIZE
675747 ) ;
676748 assert_eq ! (
677- parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "256" ) ) . unwrap( ) ,
749+ parse_blake_length( AlgoKind :: Blake2b , BlakeLength :: String ( "256" ) )
750+ . unwrap( )
751+ . as_bytes( ) ,
678752 32
679753 ) ;
680754 }
0 commit comments