(root)/
Python-3.11.7/
Modules/
_blake2/
impl/
blake2s-ref.c
       1  /*
       2     BLAKE2 reference source code package - reference C implementations
       3  
       4     Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
       5  
       6     To the extent possible under law, the author(s) have dedicated all copyright
       7     and related and neighboring rights to this software to the public domain
       8     worldwide. This software is distributed without any warranty.
       9  
      10     You should have received a copy of the CC0 Public Domain Dedication along with
      11     this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
      12  */
      13  
      14  #include <stdint.h>
      15  #include <string.h>
      16  #include <stdio.h>
      17  
      18  #include "blake2.h"
      19  #include "blake2-impl.h"
      20  
      21  static const uint32_t blake2s_IV[8] =
      22  {
      23    0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
      24    0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
      25  };
      26  
      27  static const uint8_t blake2s_sigma[10][16] =
      28  {
      29    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
      30    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
      31    { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
      32    {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
      33    {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
      34    {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
      35    { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
      36    { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
      37    {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
      38    { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
      39  };
      40  
      41  static inline int blake2s_set_lastnode( blake2s_state *S )
      42  {
      43    S->f[1] = ~0U;
      44    return 0;
      45  }
      46  
      47  static inline int blake2s_clear_lastnode( blake2s_state *S )
      48  {
      49    S->f[1] = 0U;
      50    return 0;
      51  }
      52  
      53  /* Some helper functions, not necessarily useful */
      54  static inline int blake2s_set_lastblock( blake2s_state *S )
      55  {
      56    if( S->last_node ) blake2s_set_lastnode( S );
      57  
      58    S->f[0] = ~0U;
      59    return 0;
      60  }
      61  
      62  static inline int blake2s_clear_lastblock( blake2s_state *S )
      63  {
      64    if( S->last_node ) blake2s_clear_lastnode( S );
      65  
      66    S->f[0] = 0U;
      67    return 0;
      68  }
      69  
      70  static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
      71  {
      72    S->t[0] += inc;
      73    S->t[1] += ( S->t[0] < inc );
      74    return 0;
      75  }
      76  
      77  // Parameter-related functions
      78  static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
      79  {
      80    P->digest_length = digest_length;
      81    return 0;
      82  }
      83  
      84  static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
      85  {
      86    P->fanout = fanout;
      87    return 0;
      88  }
      89  
      90  static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
      91  {
      92    P->depth = depth;
      93    return 0;
      94  }
      95  
      96  static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
      97  {
      98    store32( &P->leaf_length, leaf_length );
      99    return 0;
     100  }
     101  
     102  static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
     103  {
     104    store48( P->node_offset, node_offset );
     105    return 0;
     106  }
     107  
     108  static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
     109  {
     110    P->node_depth = node_depth;
     111    return 0;
     112  }
     113  
     114  static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
     115  {
     116    P->inner_length = inner_length;
     117    return 0;
     118  }
     119  
     120  static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
     121  {
     122    memcpy( P->salt, salt, BLAKE2S_SALTBYTES );
     123    return 0;
     124  }
     125  
     126  static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
     127  {
     128    memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );
     129    return 0;
     130  }
     131  
     132  static inline int blake2s_init0( blake2s_state *S )
     133  {
     134    memset( S, 0, sizeof( blake2s_state ) );
     135  
     136    for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
     137  
     138    return 0;
     139  }
     140  
     141  #if defined(__cplusplus)
     142  extern "C" {
     143  #endif
     144    int blake2s_init( blake2s_state *S, size_t outlen );
     145    int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
     146    int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
     147    int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen );
     148    int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen );
     149    int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
     150  #if defined(__cplusplus)
     151  }
     152  #endif
     153  
     154  /* init2 xors IV with input parameter block */
     155  int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
     156  {
     157    blake2s_init0( S );
     158    uint32_t *p = ( uint32_t * )( P );
     159  
     160    /* IV XOR ParamBlock */
     161    for( size_t i = 0; i < 8; ++i )
     162      S->h[i] ^= load32( &p[i] );
     163  
     164    S->outlen = P->digest_length;
     165    return 0;
     166  }
     167  
     168  
     169  // Sequential blake2s initialization
     170  int blake2s_init( blake2s_state *S, size_t outlen )
     171  {
     172    blake2s_param P[1];
     173  
     174    /* Move interval verification here? */
     175    if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
     176  
     177    P->digest_length = ( uint8_t) outlen;
     178    P->key_length    = 0;
     179    P->fanout        = 1;
     180    P->depth         = 1;
     181    store32( &P->leaf_length, 0 );
     182    store48( &P->node_offset, 0 );
     183    P->node_depth    = 0;
     184    P->inner_length  = 0;
     185    // memset(P->reserved, 0, sizeof(P->reserved) );
     186    memset( P->salt,     0, sizeof( P->salt ) );
     187    memset( P->personal, 0, sizeof( P->personal ) );
     188    return blake2s_init_param( S, P );
     189  }
     190  
     191  int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
     192  {
     193    blake2s_param P[1];
     194  
     195    if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
     196  
     197    if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
     198  
     199    P->digest_length = ( uint8_t ) outlen;
     200    P->key_length    = ( uint8_t ) keylen;
     201    P->fanout        = 1;
     202    P->depth         = 1;
     203    store32( &P->leaf_length, 0 );
     204    store48( &P->node_offset, 0 );
     205    P->node_depth    = 0;
     206    P->inner_length  = 0;
     207    // memset(P->reserved, 0, sizeof(P->reserved) );
     208    memset( P->salt,     0, sizeof( P->salt ) );
     209    memset( P->personal, 0, sizeof( P->personal ) );
     210  
     211    if( blake2s_init_param( S, P ) < 0 ) return -1;
     212  
     213    {
     214      uint8_t block[BLAKE2S_BLOCKBYTES];
     215      memset( block, 0, BLAKE2S_BLOCKBYTES );
     216      memcpy( block, key, keylen );
     217      blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
     218      secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
     219    }
     220    return 0;
     221  }
     222  
     223  static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )
     224  {
     225    uint32_t m[16];
     226    uint32_t v[16];
     227  
     228    for( size_t i = 0; i < 16; ++i )
     229      m[i] = load32( block + i * sizeof( m[i] ) );
     230  
     231    for( size_t i = 0; i < 8; ++i )
     232      v[i] = S->h[i];
     233  
     234    v[ 8] = blake2s_IV[0];
     235    v[ 9] = blake2s_IV[1];
     236    v[10] = blake2s_IV[2];
     237    v[11] = blake2s_IV[3];
     238    v[12] = S->t[0] ^ blake2s_IV[4];
     239    v[13] = S->t[1] ^ blake2s_IV[5];
     240    v[14] = S->f[0] ^ blake2s_IV[6];
     241    v[15] = S->f[1] ^ blake2s_IV[7];
     242  #define G(r,i,a,b,c,d) \
     243    do { \
     244      a = a + b + m[blake2s_sigma[r][2*i+0]]; \
     245      d = rotr32(d ^ a, 16); \
     246      c = c + d; \
     247      b = rotr32(b ^ c, 12); \
     248      a = a + b + m[blake2s_sigma[r][2*i+1]]; \
     249      d = rotr32(d ^ a, 8); \
     250      c = c + d; \
     251      b = rotr32(b ^ c, 7); \
     252    } while(0)
     253  #define ROUND(r)  \
     254    do { \
     255      G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
     256      G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
     257      G(r,2,v[ 2],v[ 6],v[10],v[14]); \
     258      G(r,3,v[ 3],v[ 7],v[11],v[15]); \
     259      G(r,4,v[ 0],v[ 5],v[10],v[15]); \
     260      G(r,5,v[ 1],v[ 6],v[11],v[12]); \
     261      G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
     262      G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
     263    } while(0)
     264    ROUND( 0 );
     265    ROUND( 1 );
     266    ROUND( 2 );
     267    ROUND( 3 );
     268    ROUND( 4 );
     269    ROUND( 5 );
     270    ROUND( 6 );
     271    ROUND( 7 );
     272    ROUND( 8 );
     273    ROUND( 9 );
     274  
     275    for( size_t i = 0; i < 8; ++i )
     276      S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
     277  
     278  #undef G
     279  #undef ROUND
     280    return 0;
     281  }
     282  
     283  
     284  int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen )
     285  {
     286    while( inlen > 0 )
     287    {
     288      uint32_t left = S->buflen;
     289      uint32_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
     290  
     291      if( inlen > fill )
     292      {
     293        memcpy( S->buf + left, in, fill ); // Fill buffer
     294        S->buflen += fill;
     295        blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
     296        blake2s_compress( S, S->buf ); // Compress
     297        memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left
     298        S->buflen -= BLAKE2S_BLOCKBYTES;
     299        in += fill;
     300        inlen -= fill;
     301      }
     302      else // inlen <= fill
     303      {
     304        memcpy( S->buf + left, in, inlen );
     305        S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress
     306        in += inlen;
     307        inlen -= inlen;
     308      }
     309    }
     310  
     311    return 0;
     312  }
     313  
     314  int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen )
     315  {
     316    uint8_t buffer[BLAKE2S_OUTBYTES];
     317    size_t i;
     318  
     319    if(S->outlen != outlen) return -1;
     320  
     321    if( S->buflen > BLAKE2S_BLOCKBYTES )
     322    {
     323      blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
     324      blake2s_compress( S, S->buf );
     325      S->buflen -= BLAKE2S_BLOCKBYTES;
     326      memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
     327    }
     328  
     329    blake2s_increment_counter( S, ( uint32_t )S->buflen );
     330    blake2s_set_lastblock( S );
     331    memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
     332    blake2s_compress( S, S->buf );
     333  
     334    for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
     335      store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
     336  
     337    memcpy( out, buffer, outlen );
     338    return 0;
     339  }
     340  
     341  int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
     342  {
     343    blake2s_state S[1];
     344  
     345    /* Verify parameters */
     346    if ( NULL == in && inlen > 0 ) return -1;
     347  
     348    if ( NULL == out ) return -1;
     349  
     350    if ( NULL == key && keylen > 0 ) return -1;
     351  
     352    if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
     353  
     354    if( keylen > BLAKE2S_KEYBYTES ) return -1;
     355  
     356    if( keylen > 0 )
     357    {
     358      if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
     359    }
     360    else
     361    {
     362      if( blake2s_init( S, outlen ) < 0 ) return -1;
     363    }
     364  
     365    if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1;
     366    return blake2s_final( S, out, outlen );
     367  }
     368