shithub: blake2

ref: 73dd9e9038e5d8ca8efad8c19efce70335292f17
dir: /ref/blake2xb-ref.c/

View raw version
#include <stdint.h>
#include <string.h>
#include <stdio.h>

#include "blake2.h"
#include "blake2-impl.h"


int blake2xb_init( blake2b_state *S, const uint16_t outlen, const void *key, const uint8_t keylen)
{
  blake2b_param P[1];

  if ( !outlen ) return -1;

  P->digest_length = BLAKE2B_OUTBYTES;
  P->key_length    = keylen;
  P->fanout        = 1;
  P->depth         = 1;
  store32( &P->leaf_length, 0 );
  store32( &P->node_offset, 0 );
  store32( &P->xof_length, outlen );
  P->node_depth    = 0;
  P->inner_length  = 0;
  memset( P->reserved, 0, sizeof( P->reserved ) );
  memset( P->salt,     0, sizeof( P->salt ) );
  memset( P->personal, 0, sizeof( P->personal ) );

  if( blake2b_init_param( S, P ) < 0 ) return -1;

    if (keylen) 
    {
        if ( !key || keylen > BLAKE2B_KEYBYTES ) return -1;
        uint8_t block[BLAKE2B_BLOCKBYTES];
        memset( block, 0, BLAKE2B_BLOCKBYTES );
        memcpy( block, key, keylen );
        blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
        secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); 
    }
  return 0;
}


int blake2xb_update( blake2b_state *S, const uint8_t *in, uint64_t inlen )
{
    if ( !in ) return -1;

    return blake2b_update( S, in, inlen );
}

int blake2xb_final( blake2b_state *S, uint8_t *out, const uint16_t outlen) {

    blake2b_state C[1];
    blake2b_param P[1];
    int i;
    uint16_t last_index = outlen/BLAKE2B_OUTBYTES;
    uint8_t root[BLAKE2B_BLOCKBYTES];

    if ( !out ) return 1;

    /* Finalize the root hash */
    if (blake2b_final( S, root, BLAKE2B_OUTBYTES ) < 0 )
        return -1;

    /* Set common block structure values */
    P->digest_length = BLAKE2B_OUTBYTES;
    P->key_length    = 0;
    P->fanout        = 0; 
    P->depth         = 0;
    store32( &P->leaf_length, BLAKE2B_OUTBYTES );
    store32( &P->xof_length, outlen );
    P->inner_length  = 0;
    P->node_depth    = 0;
    memset( P->reserved, 0, sizeof( P->reserved ) );
    memset( P->salt,     0, sizeof( P->salt ) );
    memset( P->personal, 0, sizeof( P->personal ) );

    for( i = 0; i < last_index; ++ i ) {
        /* Initialize state */
        store32( &P->node_offset, i );
        if( blake2b_init_param( C, P ) < 0 ) return -1;
        /* Process key if needed */
        blake2b_update( C, root, BLAKE2B_OUTBYTES);
        blake2b_final( C, out + i*BLAKE2B_OUTBYTES, BLAKE2B_OUTBYTES );
    }
    /* Last instance */
    store32( &P->node_offset, last_index);
    P->digest_length = outlen % BLAKE2B_OUTBYTES;
    if( blake2b_init_param( C, P ) < 0 ) return -1;
    blake2b_update( C, root, BLAKE2B_OUTBYTES);
    blake2b_final( C, out + last_index*BLAKE2B_OUTBYTES, outlen % BLAKE2B_OUTBYTES );
     
     return 0;
}

int blake2xb( uint8_t *out, const void *in, const void *key, const
uint16_t outlen, const uint64_t inlen, const uint8_t keylen ) 
{
    blake2b_state S[1];

    /* Verify parameters */
    if ( NULL == in && inlen > 0 ) return -1;

    if ( NULL == out ) return -1;

    if ( NULL == key && keylen > 0) return -1;

    if( keylen > BLAKE2B_KEYBYTES ) return -1;

    if( !outlen ) return -1;

    /* Initialize the root block structure */
    if ( blake2xb_init( S, outlen, key, keylen ) < 0 ) {
        return -1;
    }

    /* Compute the root of the tree */
    if ( blake2xb_update( S, ( const uint8_t * )in, inlen ) < 0 )
        return -1;

    /* Compute the final hash using the counter construction */
    blake2xb_final( S, out, outlen );

    return 0;
}

#if defined(BLAKE2XB_SELFTEST)
#include <string.h>
#include "blake2-kat.h"
int main( int argc, char **argv )
{
  uint8_t key[BLAKE2B_KEYBYTES];
  uint8_t buf[BLAKE2_KAT_LENGTH];

  for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i )
    key[i] = ( uint8_t )i;

  for( size_t i = 0; i < BLAKE2_KAT_LENGTH; ++i )
    buf[i] = ( uint8_t )i;

  for( size_t i = 0; i < BLAKE2_KAT_LENGTH; ++i )
  {
      uint8_t hash[BLAKE2_KAT_LENGTH];
      blake2xb( hash, buf, key, i, BLAKE2_KAT_LENGTH, BLAKE2B_KEYBYTES );

      for( size_t j = 0; j < i; ++j ) {
          printf("%02x", hash[j]);
      }
      printf("\n");
  }

  //puts( "ok" );
  return 0;
}
#endif