shithub: blake2

Download patch

ref: 051109d9b09257b61736e03a071985651cfc098c
parent: d0bf1ed303f05b74ee7033111869f7393965f333
parent: 3b2fb9f2cdfa4ef250a817ae3d2c8bfbbf87e66e
author: Samuel Neves <sneves@users.noreply.github.com>
date: Sun Jan 31 12:10:11 EST 2016

Merge pull request #15 from betafive/pbarker/b2sum

Add digest length argument to b2sum (plus minor improvements)

--- /dev/null
+++ b/.gitignore
@@ -1,0 +1,16 @@
+b2sum/b2sum
+bench/blake2b
+bench/blake2b.data
+bench/blake2s
+bench/blake2s.data
+bench/md5
+bench/md5.data
+bench/plotcycles.pdf
+ref/blake2b
+ref/blake2bp
+ref/blake2s
+ref/blake2sp
+sse/blake2b
+sse/blake2bp
+sse/blake2s
+sse/blake2sp
--- a/b2sum/b2sum.c
+++ b/b2sum/b2sum.c
@@ -25,7 +25,7 @@
 #include "blake2.h"
 
 /* This will help compatibility with coreutils */
-int blake2s_stream( FILE *stream, void *resstream )
+int blake2s_stream( FILE *stream, void *resstream, size_t outbytes )
 {
   int ret = -1;
   size_t sum, n;
@@ -35,7 +35,7 @@
 
   if( !buffer ) return -1;
 
-  blake2s_init( S, BLAKE2S_OUTBYTES );
+  blake2s_init( S, outbytes );
 
   while( 1 )
   {
@@ -68,7 +68,7 @@
 
   if( sum > 0 ) blake2s_update( S, buffer, sum );
 
-  blake2s_final( S, resstream, BLAKE2S_OUTBYTES );
+  blake2s_final( S, resstream, outbytes );
   ret = 0;
 cleanup_buffer:
   free( buffer );
@@ -75,7 +75,7 @@
   return ret;
 }
 
-int blake2b_stream( FILE *stream, void *resstream )
+int blake2b_stream( FILE *stream, void *resstream, size_t outbytes )
 {
   int ret = -1;
   size_t sum, n;
@@ -85,7 +85,7 @@
 
   if( !buffer ) return -1;
 
-  blake2b_init( S, BLAKE2B_OUTBYTES );
+  blake2b_init( S, outbytes );
 
   while( 1 )
   {
@@ -118,7 +118,7 @@
 
   if( sum > 0 ) blake2b_update( S, buffer, sum );
 
-  blake2b_final( S, resstream, BLAKE2B_OUTBYTES );
+  blake2b_final( S, resstream, outbytes );
   ret = 0;
 cleanup_buffer:
   free( buffer );
@@ -125,7 +125,7 @@
   return ret;
 }
 
-int blake2sp_stream( FILE *stream, void *resstream )
+int blake2sp_stream( FILE *stream, void *resstream, size_t outbytes )
 {
   int ret = -1;
   size_t sum, n;
@@ -135,7 +135,7 @@
 
   if( !buffer ) return -1;
 
-  blake2sp_init( S, BLAKE2S_OUTBYTES );
+  blake2sp_init( S, outbytes );
 
   while( 1 )
   {
@@ -168,7 +168,7 @@
 
   if( sum > 0 ) blake2sp_update( S, buffer, sum );
 
-  blake2sp_final( S, resstream, BLAKE2S_OUTBYTES );
+  blake2sp_final( S, resstream, outbytes );
   ret = 0;
 cleanup_buffer:
   free( buffer );
@@ -176,7 +176,7 @@
 }
 
 
-int blake2bp_stream( FILE *stream, void *resstream )
+int blake2bp_stream( FILE *stream, void *resstream, size_t outbytes )
 {
   int ret = -1;
   size_t sum, n;
@@ -186,7 +186,7 @@
 
   if( !buffer ) return -1;
 
-  blake2bp_init( S, BLAKE2B_OUTBYTES );
+  blake2bp_init( S, outbytes );
 
   while( 1 )
   {
@@ -219,7 +219,7 @@
 
   if( sum > 0 ) blake2bp_update( S, buffer, sum );
 
-  blake2bp_final( S, resstream, BLAKE2B_OUTBYTES );
+  blake2bp_final( S, resstream, outbytes );
   ret = 0;
 cleanup_buffer:
   free( buffer );
@@ -226,7 +226,7 @@
   return ret;
 }
 
-typedef int ( *blake2fn )( FILE *, void * );
+typedef int ( *blake2fn )( FILE *, void *, size_t );
 
 
 static void usage( char **argv, int errcode )
@@ -238,6 +238,8 @@
   fprintf( out, "\n" );
   fprintf( out, "  -a <algo>    hash algorithm (blake2b is default): \n"
                 "               [blake2b|blake2s|blake2bp|blake2sp]\n" );
+  fprintf( out, "  -l <length>  digest length in bits, must not exceed the maximum for\n"
+                "               the selected algorithm and must be a multiple of 8\n" );
   fprintf( out, "  --tag        create a BSD-style checksum\n" );
   fprintf( out, "  --help       display this help and exit\n" );
   exit( errcode );
@@ -247,7 +249,9 @@
 int main( int argc, char **argv )
 {
   blake2fn blake2_stream = blake2b_stream;
-  size_t outlen   = BLAKE2B_OUTBYTES;
+  size_t maxbytes = BLAKE2B_OUTBYTES;
+  const char *algorithm = "BLAKE2b";
+  size_t outbytes = 0;
   unsigned char hash[BLAKE2B_OUTBYTES] = {0};
   bool bsdstyle = false;
   int c;
@@ -257,6 +261,8 @@
   {
     int this_option_optind = optind ? optind : 1;
     int option_index = 0;
+    char *end = NULL;
+    size_t outbits;
     static struct option long_options[] = {
       { "help",  no_argument, 0,  0  },
       { "tag",   no_argument, 0,  0  },
@@ -263,7 +269,7 @@
       { NULL, 0, NULL, 0 }
     };
 
-    c = getopt_long( argc, argv, "a:", long_options, &option_index );
+    c = getopt_long( argc, argv, "a:l:", long_options, &option_index );
     if( c == -1 ) break;
     switch( c )
     {
@@ -271,22 +277,26 @@
       if( 0 == strcmp( optarg, "blake2b" ) )
       {
         blake2_stream = blake2b_stream;
-        outlen = BLAKE2B_OUTBYTES;
+        maxbytes = BLAKE2B_OUTBYTES;
+        algorithm = "BLAKE2b";
       }
       else if ( 0 == strcmp( optarg, "blake2s" ) )
       {
         blake2_stream = blake2s_stream;
-        outlen = BLAKE2S_OUTBYTES;
+        maxbytes = BLAKE2S_OUTBYTES;
+        algorithm = "BLAKE2s";
       }
       else if ( 0 == strcmp( optarg, "blake2bp" ) )
       {
         blake2_stream = blake2bp_stream;
-        outlen = BLAKE2B_OUTBYTES;
+        maxbytes = BLAKE2B_OUTBYTES;
+        algorithm = "BLAKE2bp";
       }
       else if ( 0 == strcmp( optarg, "blake2sp" ) )
       {
         blake2_stream = blake2sp_stream;
-        outlen = BLAKE2S_OUTBYTES;
+        maxbytes = BLAKE2S_OUTBYTES;
+        algorithm = "BLAKE2sp";
       }
       else
       {
@@ -296,6 +306,16 @@
 
       break;
 
+    case 'l':
+      outbits = strtoul(optarg, &end, 10);
+      if( !end || *end != '\0' || outbits % 8 )
+      {
+        printf( "Invalid length argument: `%s'\n", optarg);
+        usage( argv, 111 );
+      }
+      outbytes = outbits / 8;
+      break;
+
     case 0:
       if( 0 == strcmp( "help", long_options[option_index].name ) )
         usage( argv, 0 );
@@ -309,6 +329,15 @@
     }
   }
 
+  if(outbytes > maxbytes)
+  {
+    printf( "Invalid length argument: %zu\n", outbytes * 8 );
+    printf( "Maximum digest length for %s is %zu\n", algorithm, maxbytes * 8 );
+    usage( argv, 111 );
+  }
+  else if( outbytes == 0 )
+    outbytes = maxbytes;
+
   if( optind == argc )
     argv[argc++] = (char *) "-";
 
@@ -326,7 +355,7 @@
       continue;
     }
 
-    if( blake2_stream( f, hash ) < 0 )
+    if( blake2_stream( f, hash, outbytes ) < 0 )
     {
       fprintf( stderr, "Failed to hash `%s'\n", argv[i] );
     }
@@ -334,14 +363,13 @@
     {
       if( bsdstyle )
       {
-        if( blake2_stream == blake2b_stream ) printf( "BLAKE2b" );
-        else if( blake2_stream == blake2bp_stream ) printf( "BLAKE2bp" );
-        else if( blake2_stream == blake2s_stream ) printf( "BLAKE2s" );
-        else if( blake2_stream == blake2sp_stream ) printf( "BLAKE2sp" );
-        printf( " (%s) = ", argv[i] );
+        if( outbytes < maxbytes )
+          printf( "%s-%zu (%s) = ", algorithm, outbytes * 8, argv[i] );
+        else
+          printf( "%s (%s) = ", algorithm, argv[i] );
       }
 
-      for( size_t j = 0; j < outlen; ++j )
+      for( size_t j = 0; j < outbytes; ++j )
         printf( "%02x", hash[j] );
 
       if( bsdstyle )
--