1121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes/*
2121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes   BLAKE2 reference source code package - optimized C implementations
3121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
4121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes   Copyright 2012, Samuel Neves <sneves@dei.uc.pt>.  You may use this under the
5121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes   terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
6121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes   your option.  The terms of these licenses can be found at:
7121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
8121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes   - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
9121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes   - OpenSSL license   : https://www.openssl.org/source/license.html
10121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes   - Apache 2.0        : http://www.apache.org/licenses/LICENSE-2.0
11121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
12121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes   More information about the BLAKE2 hash function can be found at
13121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes   https://blake2.net.
14121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes*/
15121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
16121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include <stdint.h>
17121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include <string.h>
18121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include <stdio.h>
19121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
20121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include "blake2.h"
21121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include "blake2-impl.h"
22121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
23121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include "blake2-config.h"
24121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
25121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
26121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include <emmintrin.h>
27121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#if defined(HAVE_SSSE3)
28121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include <tmmintrin.h>
29121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#endif
30121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#if defined(HAVE_SSE41)
31121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include <smmintrin.h>
32121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#endif
33121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#if defined(HAVE_AVX)
34121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include <immintrin.h>
35121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#endif
36121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#if defined(HAVE_XOP)
37121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include <x86intrin.h>
38121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#endif
39121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
40121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include "blake2s-round.h"
41121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
42121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimesstatic const uint32_t blake2s_IV[8] =
43121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
44121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
45121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
46121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes};
47121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
48121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimesstatic const uint8_t blake2s_sigma[10][16] =
49121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
50121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
51121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
52121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
53121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
54121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
55121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
56121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
57121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
58121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
59121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
60121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes};
61121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
62121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
63121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes/* Some helper functions, not necessarily useful */
64121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_set_lastnode( blake2s_state *S )
65121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
66121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  S->f[1] = -1;
67121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
68121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
69121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
70121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_clear_lastnode( blake2s_state *S )
71121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
72121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  S->f[1] = 0;
73121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
74121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
75121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
76121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_is_lastblock( const blake2s_state *S )
77121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
78121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return S->f[0] != 0;
79121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
80121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
81121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_set_lastblock( blake2s_state *S )
82121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
83121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if( S->last_node ) blake2s_set_lastnode( S );
84121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
85121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  S->f[0] = -1;
86121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
87121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
88121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
89121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_clear_lastblock( blake2s_state *S )
90121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
91121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if( S->last_node ) blake2s_clear_lastnode( S );
92121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
93121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  S->f[0] = 0;
94121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
95121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
96121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
97121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
98121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
99121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0];
100121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  t += inc;
101121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  S->t[0] = ( uint32_t )( t >>  0 );
102121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  S->t[1] = ( uint32_t )( t >> 32 );
103121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
104121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
105121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
106121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
107121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes/* Parameter-related functions */
108121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
109121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
110121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  P->digest_length = digest_length;
111121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
112121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
113121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
114121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
115121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
116121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  P->fanout = fanout;
117121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
118121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
119121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
120121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
121121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
122121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  P->depth = depth;
123121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
124121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
125121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
126121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
127121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
128121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  P->leaf_length = leaf_length;
129121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
130121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
131121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
132121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
133121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
134121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  store48( P->node_offset, node_offset );
135121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
136121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
137121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
138121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
139121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
140121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  P->node_depth = node_depth;
141121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
142121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
143121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
144121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
145121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
146121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  P->inner_length = inner_length;
147121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
148121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
149121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
150121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
151121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
152121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  memcpy( P->salt, salt, BLAKE2S_SALTBYTES );
153121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
154121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
155121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
156121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
157121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
158121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );
159121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
160121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
161121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
162121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_init0( blake2s_state *S )
163121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
16487bf0febcb59a389eb62bcb467b7ec9c4974be49Christian Heimes  int i;
165121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  memset( S, 0, sizeof( blake2s_state ) );
166121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
16787bf0febcb59a389eb62bcb467b7ec9c4974be49Christian Heimes  for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
168121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
169121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
170121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
171121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
172121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes/* init2 xors IV with input parameter block */
173121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimesint blake2s_init_param( blake2s_state *S, const blake2s_param *P )
174121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
175121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  /*blake2s_init0( S ); */
176121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint8_t * v = ( const uint8_t * )( blake2s_IV );
177121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint8_t * p = ( const uint8_t * )( P );
178121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  uint8_t * h = ( uint8_t * )( S->h );
17987bf0febcb59a389eb62bcb467b7ec9c4974be49Christian Heimes  int i;
180121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  /* IV XOR ParamBlock */
181121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  memset( S, 0, sizeof( blake2s_state ) );
182121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
18387bf0febcb59a389eb62bcb467b7ec9c4974be49Christian Heimes  for( i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
184121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
185121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
186121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
187121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
188121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
189121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes/* Some sort of default parameter block initialization, for sequential blake2s */
190121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimesint blake2s_init( blake2s_state *S, const uint8_t outlen )
191121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
192121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const blake2s_param P =
193121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {
194121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    outlen,
195121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    0,
196121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    1,
197121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    1,
198121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    0,
199121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    {0},
200121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    0,
201121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    0,
202121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    {0},
203121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    {0}
204121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  };
205121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  /* Move interval verification here? */
206121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
207121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return blake2s_init_param( S, &P );
208121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
209121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
210121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
211121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimesint blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
212121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
213121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const blake2s_param P =
214121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {
215121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    outlen,
216121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    keylen,
217121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    1,
218121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    1,
219121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    0,
220121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    {0},
221121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    0,
222121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    0,
223121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    {0},
224121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    {0}
225121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  };
226121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
227121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  /* Move interval verification here? */
228121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
229121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
230121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1;
231121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
232121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if( blake2s_init_param( S, &P ) < 0 )
233121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    return -1;
234121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
235121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {
236121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    uint8_t block[BLAKE2S_BLOCKBYTES];
237121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    memset( block, 0, BLAKE2S_BLOCKBYTES );
238121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    memcpy( block, key, keylen );
239121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
240121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
241121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  }
242121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
243121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
244121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
245121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
246121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian HeimesBLAKE2_LOCAL_INLINE(int) blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )
247121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
248121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  __m128i row1, row2, row3, row4;
249121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  __m128i buf1, buf2, buf3, buf4;
250121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#if defined(HAVE_SSE41)
251121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  __m128i t0, t1;
252121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#if !defined(HAVE_XOP)
253121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  __m128i t2;
254121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#endif
255121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#endif
256121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  __m128i ff0, ff1;
257121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#if defined(HAVE_SSSE3) && !defined(HAVE_XOP)
258121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 );
259121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 );
260121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#endif
261121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#if defined(HAVE_SSE41)
262121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const __m128i m0 = LOADU( block +  00 );
263121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const __m128i m1 = LOADU( block +  16 );
264121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const __m128i m2 = LOADU( block +  32 );
265121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const __m128i m3 = LOADU( block +  48 );
266121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#else
267121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t  m0 = ( ( uint32_t * )block )[ 0];
268121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t  m1 = ( ( uint32_t * )block )[ 1];
269121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t  m2 = ( ( uint32_t * )block )[ 2];
270121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t  m3 = ( ( uint32_t * )block )[ 3];
271121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t  m4 = ( ( uint32_t * )block )[ 4];
272121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t  m5 = ( ( uint32_t * )block )[ 5];
273121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t  m6 = ( ( uint32_t * )block )[ 6];
274121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t  m7 = ( ( uint32_t * )block )[ 7];
275121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t  m8 = ( ( uint32_t * )block )[ 8];
276121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t  m9 = ( ( uint32_t * )block )[ 9];
277121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t m10 = ( ( uint32_t * )block )[10];
278121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t m11 = ( ( uint32_t * )block )[11];
279121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t m12 = ( ( uint32_t * )block )[12];
280121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t m13 = ( ( uint32_t * )block )[13];
281121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t m14 = ( ( uint32_t * )block )[14];
282121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  const uint32_t m15 = ( ( uint32_t * )block )[15];
283121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#endif
284121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  row1 = ff0 = LOADU( &S->h[0] );
285121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  row2 = ff1 = LOADU( &S->h[4] );
286121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  row3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A );
287121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  row4 = _mm_xor_si128( _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ), LOADU( &S->t[0] ) );
288121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  ROUND( 0 );
289121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  ROUND( 1 );
290121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  ROUND( 2 );
291121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  ROUND( 3 );
292121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  ROUND( 4 );
293121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  ROUND( 5 );
294121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  ROUND( 6 );
295121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  ROUND( 7 );
296121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  ROUND( 8 );
297121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  ROUND( 9 );
298121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  STOREU( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row1, row3 ) ) );
299121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  STOREU( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row2, row4 ) ) );
300121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
301121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
302121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
303121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes/* inlen now in bytes */
304121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimesint blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen )
305121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
306121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  while( inlen > 0 )
307121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {
308121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    size_t left = S->buflen;
309121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    size_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
310121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
311121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    if( inlen > fill )
312121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    {
313121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      memcpy( S->buf + left, in, fill ); /* Fill buffer */
314121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      S->buflen += fill;
315121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
316121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      blake2s_compress( S, S->buf ); /* Compress */
317121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); /* Shift buffer left */
318121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      S->buflen -= BLAKE2S_BLOCKBYTES;
319121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      in += fill;
320121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      inlen -= fill;
321121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    }
322121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    else /* inlen <= fill */
323121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    {
324121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      memcpy( S->buf + left, in, inlen );
325121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      S->buflen += inlen; /* Be lazy, do not compress */
326121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      in += inlen;
327121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      inlen -= inlen;
328121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    }
329121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  }
330121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
331121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
332121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
333121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
334121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes/* Is this correct? */
335121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimesint blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen )
336121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
337121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
33887bf0febcb59a389eb62bcb467b7ec9c4974be49Christian Heimes  int i;
339121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
340121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if( outlen > BLAKE2S_OUTBYTES )
341121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    return -1;
342121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
343121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if( blake2s_is_lastblock( S ) )
344121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    return -1;
345121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
346121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if( S->buflen > BLAKE2S_BLOCKBYTES )
347121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {
348121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
349121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    blake2s_compress( S, S->buf );
350121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    S->buflen -= BLAKE2S_BLOCKBYTES;
3515940c535b06805960d008bcafec7260dae74d9b9Christian Heimes    memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
352121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  }
353121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
354121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  blake2s_increment_counter( S, ( uint32_t )S->buflen );
355121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  blake2s_set_lastblock( S );
356121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
357121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  blake2s_compress( S, S->buf );
358121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
35987bf0febcb59a389eb62bcb467b7ec9c4974be49Christian Heimes  for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
360121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
361121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
362121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  memcpy( out, buffer, outlen );
363121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
364121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
365121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
366121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes/* inlen, at least, should be uint64_t. Others can be size_t. */
367121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimesint blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
368121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
369121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  blake2s_state S[1];
370121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
371121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  /* Verify parameters */
372121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if ( NULL == in && inlen > 0 ) return -1;
373121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
374121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if ( NULL == out ) return -1;
375121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
376121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if ( NULL == key && keylen > 0) return -1;
377121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
378121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
379121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
380121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if( keylen > BLAKE2S_KEYBYTES ) return -1;
381121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
382121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  if( keylen > 0 )
383121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {
384121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
385121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  }
386121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  else
387121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {
388121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    if( blake2s_init( S, outlen ) < 0 ) return -1;
389121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  }
390121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
391121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  blake2s_update( S, ( const uint8_t * )in, inlen );
392121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  blake2s_final( S, out, outlen );
393121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
394121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
395121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
396121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#if defined(SUPERCOP)
397121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimesint crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
398121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
399121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, inlen, 0 );
400121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
401121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#endif
402121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
403121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#if defined(BLAKE2S_SELFTEST)
404121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include <string.h>
405121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#include "blake2-kat.h"
406121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimesint main( int argc, char **argv )
407121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes{
408121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  uint8_t key[BLAKE2S_KEYBYTES];
409121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  uint8_t buf[KAT_LENGTH];
4109c2f3041039b21ec08ed3179333460110ff6a355Christian Heimes  size_t i;
411121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
4129c2f3041039b21ec08ed3179333460110ff6a355Christian Heimes  for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
413121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    key[i] = ( uint8_t )i;
414121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
4159c2f3041039b21ec08ed3179333460110ff6a355Christian Heimes  for( i = 0; i < KAT_LENGTH; ++i )
416121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    buf[i] = ( uint8_t )i;
417121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
4189c2f3041039b21ec08ed3179333460110ff6a355Christian Heimes  for( i = 0; i < KAT_LENGTH; ++i )
419121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  {
420121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    uint8_t hash[BLAKE2S_OUTBYTES];
421121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
422121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    if( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 ||
423121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes        0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
424121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    {
425121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      puts( "error" );
426121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes      return -1;
427121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes    }
428121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  }
429121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
430121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  puts( "ok" );
431121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes  return 0;
432121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes}
433121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes#endif
434121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
435121b9487d13b7dcd5a864a6067c4a5c88ba15b5dChristian Heimes
436