@@ -115,6 +115,8 @@ impl AlgoKind {
115115 ALGORITHM_OPTIONS_SHA384 => Sha384 ,
116116 ALGORITHM_OPTIONS_SHA512 => Sha512 ,
117117
118+ // Extensions not in GNU as of version 9.10
119+ ALGORITHM_OPTIONS_BLAKE3 => Blake3 ,
118120 ALGORITHM_OPTIONS_SHAKE128 => Shake128 ,
119121 ALGORITHM_OPTIONS_SHAKE256 => Shake256 ,
120122 _ => return Err ( ChecksumError :: UnknownAlgorithm ( algo. as_ref ( ) . to_string ( ) ) . into ( ) ) ,
@@ -245,11 +247,11 @@ pub enum SizedAlgoKind {
245247 Md5 ,
246248 Sm3 ,
247249 Sha1 ,
248- Blake3 ,
249250 Sha2 ( ShaLength ) ,
250251 Sha3 ( ShaLength ) ,
251- // Note: we store Blake2b 's length as BYTES.
252+ // Note: we store Blake* 's length as BYTES.
252253 Blake2b ( Option < usize > ) ,
254+ Blake3 ( Option < usize > ) ,
253255 // Shake* length are stored in bits.
254256 Shake128 ( Option < usize > ) ,
255257 Shake256 ( Option < usize > ) ,
@@ -267,7 +269,6 @@ impl SizedAlgoKind {
267269 | ak:: Md5
268270 | ak:: Sm3
269271 | ak:: Sha1
270- | ak:: Blake3
271272 | ak:: Sha224
272273 | ak:: Sha256
273274 | ak:: Sha384
@@ -282,8 +283,8 @@ impl SizedAlgoKind {
282283 ( ak:: Md5 , _) => Ok ( Self :: Md5 ) ,
283284 ( ak:: Sm3 , _) => Ok ( Self :: Sm3 ) ,
284285 ( ak:: Sha1 , _) => Ok ( Self :: Sha1 ) ,
285- ( ak:: Blake3 , _) => Ok ( Self :: Blake3 ) ,
286286
287+ ( ak:: Blake3 , l) => Ok ( Self :: Blake3 ( l) ) ,
287288 ( ak:: Shake128 , l) => Ok ( Self :: Shake128 ( l) ) ,
288289 ( ak:: Shake256 , l) => Ok ( Self :: Shake256 ( l) ) ,
289290 ( ak:: Sha2 , Some ( l) ) => Ok ( Self :: Sha2 ( ShaLength :: try_from ( l) ?) ) ,
@@ -293,7 +294,8 @@ impl SizedAlgoKind {
293294 }
294295 // [`calculate_blake2b_length`] expects a length in bits but we
295296 // have a length in bytes.
296- ( ak:: Blake2b , Some ( l) ) => Ok ( Self :: Blake2b ( calculate_blake2b_length_str (
297+ ( algo @ ak:: Blake2b , Some ( l) ) => Ok ( Self :: Blake2b ( calculate_blake_length_str (
298+ algo,
297299 & ( 8 * l) . to_string ( ) ,
298300 ) ?) ) ,
299301 ( ak:: Blake2b , None ) => Ok ( Self :: Blake2b ( None ) ) ,
@@ -310,11 +312,16 @@ impl SizedAlgoKind {
310312 Self :: Md5 => "MD5" . into ( ) ,
311313 Self :: Sm3 => "SM3" . into ( ) ,
312314 Self :: Sha1 => "SHA1" . into ( ) ,
313- Self :: Blake3 => "BLAKE3" . into ( ) ,
314315 Self :: Sha2 ( len) => format ! ( "SHA{}" , len. as_usize( ) ) ,
315316 Self :: Sha3 ( len) => format ! ( "SHA3-{}" , len. as_usize( ) ) ,
316317 Self :: Blake2b ( Some ( byte_len) ) => format ! ( "BLAKE2b-{}" , byte_len * 8 ) ,
317318 Self :: Blake2b ( None ) => "BLAKE2b" . into ( ) ,
319+ Self :: Blake3 ( byte_len) => {
320+ format ! (
321+ "BLAKE3-{}" ,
322+ byte_len. unwrap_or( Blake3 :: DEFAULT_BYTE_SIZE ) * 8
323+ )
324+ }
318325 Self :: Shake128 ( opt_bit_len) => format ! (
319326 "SHAKE128-{}" ,
320327 opt_bit_len. unwrap_or( Shake128 :: DEFAULT_BIT_SIZE )
@@ -339,7 +346,6 @@ impl SizedAlgoKind {
339346 Self :: Md5 => Box :: new ( Md5 :: default ( ) ) ,
340347 Self :: Sm3 => Box :: new ( Sm3 :: default ( ) ) ,
341348 Self :: Sha1 => Box :: new ( Sha1 :: default ( ) ) ,
342- Self :: Blake3 => Box :: new ( Blake3 :: default ( ) ) ,
343349 Self :: Sha2 ( Len224 ) => Box :: new ( Sha224 :: default ( ) ) ,
344350 Self :: Sha2 ( Len256 ) => Box :: new ( Sha256 :: default ( ) ) ,
345351 Self :: Sha2 ( Len384 ) => Box :: new ( Sha384 :: default ( ) ) ,
@@ -351,6 +357,9 @@ impl SizedAlgoKind {
351357 Self :: Blake2b ( len_opt) => {
352358 Box :: new ( len_opt. map ( Blake2b :: with_output_bytes) . unwrap_or_default ( ) )
353359 }
360+ Self :: Blake3 ( len_opt) => {
361+ Box :: new ( len_opt. map ( Blake3 :: with_output_bytes) . unwrap_or_default ( ) )
362+ }
354363 Self :: Shake128 ( len_opt) => {
355364 Box :: new ( len_opt. map ( Shake128 :: with_output_bits) . unwrap_or_default ( ) )
356365 }
@@ -369,7 +378,7 @@ impl SizedAlgoKind {
369378 Self :: Md5 => 128 ,
370379 Self :: Sm3 => 512 ,
371380 Self :: Sha1 => 160 ,
372- Self :: Blake3 => 256 ,
381+ Self :: Blake3 ( len ) => len . unwrap_or ( Blake3 :: DEFAULT_BYTE_SIZE ) * 8 ,
373382 Self :: Sha2 ( len) => len. as_usize ( ) ,
374383 Self :: Sha3 ( len) => len. as_usize ( ) ,
375384 Self :: Blake2b ( len) => len. unwrap_or ( Blake2b :: DEFAULT_BYTE_SIZE * 8 ) ,
@@ -486,20 +495,22 @@ pub fn digest_reader<T: Read>(
486495 Ok ( ( digest. result ( ) , output_size) )
487496}
488497
489- /// Calculates the length of the digest.
490- pub fn calculate_blake2b_length_str ( bit_length : & str ) -> UResult < Option < usize > > {
498+ /// Calculates the BYTE length of the digest.
499+ pub fn calculate_blake_length_str ( algo : AlgoKind , bit_length : & str ) -> UResult < Option < usize > > {
500+ debug_assert ! ( matches!( algo, AlgoKind :: Blake2b | AlgoKind :: Blake3 ) ) ;
501+
491502 // Blake2b's length is parsed in an u64.
492503 match bit_length. parse :: < usize > ( ) {
493504 Ok ( 0 ) => Ok ( None ) ,
494505
495506 // Error cases
496- Ok ( n) if n > 512 => {
507+ Ok ( n) if n > 512 && algo == AlgoKind :: Blake2b => {
497508 show_error ! ( "{}" , ChecksumError :: InvalidLength ( bit_length. into( ) ) ) ;
498- Err ( ChecksumError :: LengthTooBigForBlake ( "BLAKE2b" . into ( ) ) . into ( ) )
509+ Err ( ChecksumError :: LengthTooBigForBlake ( algo . to_uppercase ( ) . into ( ) ) . into ( ) )
499510 }
500511 Err ( e) if * e. kind ( ) == IntErrorKind :: PosOverflow => {
501512 show_error ! ( "{}" , ChecksumError :: InvalidLength ( bit_length. into( ) ) ) ;
502- Err ( ChecksumError :: LengthTooBigForBlake ( "BLAKE2b" . into ( ) ) . into ( ) )
513+ Err ( ChecksumError :: LengthTooBigForBlake ( algo . to_uppercase ( ) . into ( ) ) . into ( ) )
503514 }
504515 Err ( _) => Err ( ChecksumError :: InvalidLength ( bit_length. into ( ) ) . into ( ) ) ,
505516
@@ -632,10 +643,19 @@ mod tests {
632643
633644 #[ test]
634645 fn test_calculate_blake2b_length ( ) {
635- assert_eq ! ( calculate_blake2b_length_str( "0" ) . unwrap( ) , None ) ;
636- assert ! ( calculate_blake2b_length_str( "10" ) . is_err( ) ) ;
637- assert ! ( calculate_blake2b_length_str( "520" ) . is_err( ) ) ;
638- assert_eq ! ( calculate_blake2b_length_str( "512" ) . unwrap( ) , None ) ;
639- assert_eq ! ( calculate_blake2b_length_str( "256" ) . unwrap( ) , Some ( 32 ) ) ;
646+ assert_eq ! (
647+ calculate_blake_length_str( AlgoKind :: Blake2b , "0" ) . unwrap( ) ,
648+ None
649+ ) ;
650+ assert ! ( calculate_blake_length_str( AlgoKind :: Blake2b , "10" ) . is_err( ) ) ;
651+ assert ! ( calculate_blake_length_str( AlgoKind :: Blake2b , "520" ) . is_err( ) ) ;
652+ assert_eq ! (
653+ calculate_blake_length_str( AlgoKind :: Blake2b , "512" ) . unwrap( ) ,
654+ None
655+ ) ;
656+ assert_eq ! (
657+ calculate_blake_length_str( AlgoKind :: Blake2b , "256" ) . unwrap( ) ,
658+ Some ( 32 )
659+ ) ;
640660 }
641661}
0 commit comments