blake2 0.2.0 → 0.3.0
raw patch · 32 files changed
+2422/−2337 lines, 32 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Crypto.Hash.BLAKE2.Internal: type FinalFunc a = Ptr a -> Ptr Word8 -> Word8 -> IO CInt
+ Crypto.Hash.BLAKE2.Internal: type FinalFunc a = Ptr a -> Ptr () -> CSize -> IO CInt
- Crypto.Hash.BLAKE2.Internal: type HashFunc = Ptr Word8 -> Ptr CChar -> Ptr CChar -> Word8 -> Word64 -> Word8 -> IO CInt
+ Crypto.Hash.BLAKE2.Internal: type HashFunc = Ptr () -> CSize -> Ptr () -> CSize -> Ptr () -> CSize -> IO CInt
- Crypto.Hash.BLAKE2.Internal: type InitFunc a = Ptr a -> Int -> IO CInt
+ Crypto.Hash.BLAKE2.Internal: type InitFunc a = Ptr a -> CSize -> IO CInt
- Crypto.Hash.BLAKE2.Internal: type InitKeyFunc a = Ptr a -> Word8 -> Ptr CChar -> Word8 -> IO CInt
+ Crypto.Hash.BLAKE2.Internal: type InitKeyFunc a = Ptr a -> CSize -> Ptr () -> CSize -> IO CInt
- Crypto.Hash.BLAKE2.Internal: type UpdateFunc a = Ptr a -> Ptr Word8 -> Word64 -> IO CInt
+ Crypto.Hash.BLAKE2.Internal: type UpdateFunc a = Ptr a -> Ptr () -> CSize -> IO CInt
Files
- .travis.yml +22/−64
- blake2.cabal +6/−8
- cbits/ref/blake2b-ref.c +379/−0
- cbits/ref/blake2b.c +0/−416
- cbits/ref/blake2bp-ref.c +359/−0
- cbits/ref/blake2bp.c +0/−293
- cbits/ref/blake2s-ref.c +367/−0
- cbits/ref/blake2s.c +0/−406
- cbits/ref/blake2sp-ref.c +359/−0
- cbits/ref/blake2sp.c +0/−299
- cbits/sse/blake2b.c +135/−212
- cbits/sse/blake2bp.c +115/−54
- cbits/sse/blake2s.c +136/−204
- cbits/sse/blake2sp.c +118/−55
- changelog.md +5/−0
- include/ref/blake2-impl.h +81/−60
- include/ref/blake2.h +89/−55
- include/sse/blake2-config.h +2/−4
- include/sse/blake2-impl.h +82/−61
- include/sse/blake2.h +89/−55
- include/sse/blake2b-load-sse2.h +5/−7
- include/sse/blake2b-load-sse41.h +5/−7
- include/sse/blake2b-round.h +7/−9
- include/sse/blake2s-load-sse2.h +5/−6
- include/sse/blake2s-load-sse41.h +5/−7
- include/sse/blake2s-load-xop.h +10/−10
- include/sse/blake2s-round.h +6/−8
- src/Crypto/Hash/BLAKE2/BLAKE2b.hsc +1/−1
- src/Crypto/Hash/BLAKE2/BLAKE2bp.hsc +1/−1
- src/Crypto/Hash/BLAKE2/BLAKE2s.hsc +1/−1
- src/Crypto/Hash/BLAKE2/BLAKE2sp.hsc +1/−1
- src/Crypto/Hash/BLAKE2/Internal.hs +31/−33
.travis.yml view
@@ -1,81 +1,39 @@-# This file has been generated -- see https://github.com/hvr/multi-ghc-travis language: c-sudo: false+dist: trusty cache: directories:- - $HOME/.cabsnap- - $HOME/.cabal/packages+ - $HOME/.stack -before_cache:- - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log- - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar+addons:+ apt:+ packages:+ - libgmp-dev matrix: include:- - env: CABALVER=1.22 GHCVER=7.10.3- compiler: ": #GHC 7.10.3"- addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,alex-3.1.7,happy-1.19.5], sources: [hvr-ghc]}}- - env: CABALVER=1.24 GHCVER=8.0.2- compiler: ": #GHC 8.0.2"- addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.2,alex-3.1.7,happy-1.19.5], sources: [hvr-ghc]}}- - env: CABALVER=head GHCVER=head- compiler: ": #GHC head"- addons: {apt: {packages: [cabal-install-head,ghc-head,alex-3.1.7,happy-1.19.5], sources: [hvr-ghc]}}+ - env: ARGS="--resolver lts-12.25"+ compiler: "stack-8.4.4" + - env: ARGS=""+ compiler: "stack-8.6.3"++ - env: ARGS="--resolver nightly"+ compiler: "stack-nightly"+ allow_failures:- - env: CABALVER=head GHCVER=head+ - env: ARGS="--resolver nightly"+ compiler: "stack-nightly" before_install: - unset CC- - export HAPPYVER=1.19.5- - export ALEXVER=3.1.7- - export PATH=~/.cabal/bin:/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:/opt/happy/$HAPPYVER/bin:/opt/alex/$ALEXVER/bin:$PATH+ - mkdir -p ~/.local/bin+ - export PATH=$HOME/.local/bin:$PATH+ - travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack' install:- - cabal --version- - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"- - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];- then- zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >- $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;- fi- - travis_retry cabal update- - "sed -i 's/^jobs:.*$/jobs: 2/' $HOME/.cabal/config"- - cabal install --only-dependencies --enable-tests --enable-benchmarks --dry -v blake2.cabal > installplan.txt- - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt-- # check whether current requested install-plan matches cached package-db snapshot- - if diff -u installplan.txt $HOME/.cabsnap/installplan.txt;- then- echo "cabal build-cache HIT";- rm -rfv .ghc;- cp -a $HOME/.cabsnap/ghc $HOME/.ghc;- cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/;- else- echo "cabal build-cache MISS";- rm -rf $HOME/.cabsnap;- mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;- cabal install --only-dependencies --enable-tests --enable-benchmarks blake2.cabal;- fi-- # snapshot package-db on cache miss- - if [ ! -d $HOME/.cabsnap ];- then- echo "snapshotting package-db to build-cache";- mkdir $HOME/.cabsnap;- cp -a $HOME/.ghc $HOME/.cabsnap/ghc;- cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;- fi+ - stack $ARGS setup script:- - cabal configure --enable-tests --enable-benchmarks -v2 # -v2 provides useful information for debugging- - cabal build # this builds all libraries and executables (including tests)- - cabal test- - cabal sdist # tests that a source-distribution can be generated-- # Check that the resulting source distribution can be built & installed.- # If there are no other `.tar.gz` files in `dist`, this can be even simpler:- # `cabal install --force-reinstalls dist/*-*.tar.gz`- - SRC_TGZ=$(cabal info . | awk '{print $2;exit}').tar.gz &&- (cd dist && cabal install --enable-tests --run-tests --force-reinstalls "$SRC_TGZ")+ - stack $ARGS --no-terminal test --bench --no-run-benchmarks --haddock --no-haddock-deps+ - stack $ARGS sdist
blake2.cabal view
@@ -1,5 +1,5 @@ name: blake2-version: 0.2.0+version: 0.3.0 synopsis: A library providing BLAKE2 license: PublicDomain license-file: LICENSE@@ -10,7 +10,7 @@ category: Cryptography build-type: Simple cabal-version: >=1.10-tested-with: GHC == 7.10.3, GHC == 8.0.2+tested-with: GHC == 8.4.4, GHC == 8.6.3 description: This library provides the <https://blake2.net/ BLAKE2> hash algorithms. @@ -31,8 +31,6 @@ flag hlint -flag doctest- flag llvm default: False manual: True@@ -69,10 +67,10 @@ include-dirs: include/sse else c-sources:- cbits/ref/blake2b.c- cbits/ref/blake2bp.c- cbits/ref/blake2s.c- cbits/ref/blake2sp.c+ cbits/ref/blake2b-ref.c+ cbits/ref/blake2bp-ref.c+ cbits/ref/blake2s-ref.c+ cbits/ref/blake2sp-ref.c include-dirs: include/ref if flag(llvm)
+ cbits/ref/blake2b-ref.c view
@@ -0,0 +1,379 @@+/*+ BLAKE2 reference source code package - reference C implementations++ Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the+ terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at+ your option. The terms of these licenses can be found at:++ - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0+ - OpenSSL license : https://www.openssl.org/source/license.html+ - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0++ More information about the BLAKE2 hash function can be found at+ https://blake2.net.+*/++#include <stdint.h>+#include <string.h>+#include <stdio.h>++#include "blake2.h"+#include "blake2-impl.h"++static const uint64_t blake2b_IV[8] =+{+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,+ 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,+ 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL+};++static const uint8_t blake2b_sigma[12][16] =+{+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,+ { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,+ { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,+ { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,+ { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,+ { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,+ { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,+ { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,+ { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }+};+++static void blake2b_set_lastnode( blake2b_state *S )+{+ S->f[1] = (uint64_t)-1;+}++/* Some helper functions, not necessarily useful */+static int blake2b_is_lastblock( const blake2b_state *S )+{+ return S->f[0] != 0;+}++static void blake2b_set_lastblock( blake2b_state *S )+{+ if( S->last_node ) blake2b_set_lastnode( S );++ S->f[0] = (uint64_t)-1;+}++static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc )+{+ S->t[0] += inc;+ S->t[1] += ( S->t[0] < inc );+}++static void blake2b_init0( blake2b_state *S )+{+ size_t i;+ memset( S, 0, sizeof( blake2b_state ) );++ for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];+}++/* init xors IV with input parameter block */+int blake2b_init_param( blake2b_state *S, const blake2b_param *P )+{+ const uint8_t *p = ( const uint8_t * )( P );+ size_t i;++ blake2b_init0( S );++ /* IV XOR ParamBlock */+ for( i = 0; i < 8; ++i )+ S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );++ S->outlen = P->digest_length;+ return 0;+}++++int blake2b_init( blake2b_state *S, size_t outlen )+{+ blake2b_param P[1];++ if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;++ P->digest_length = (uint8_t)outlen;+ P->key_length = 0;+ P->fanout = 1;+ P->depth = 1;+ store32( &P->leaf_length, 0 );+ store32( &P->node_offset, 0 );+ store32( &P->xof_length, 0 );+ 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 ) );+ return blake2b_init_param( S, P );+}+++int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )+{+ blake2b_param P[1];++ if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;++ if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;++ P->digest_length = (uint8_t)outlen;+ P->key_length = (uint8_t)keylen;+ P->fanout = 1;+ P->depth = 1;+ store32( &P->leaf_length, 0 );+ store32( &P->node_offset, 0 );+ store32( &P->xof_length, 0 );+ 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;++ {+ 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 ); /* Burn the key from stack */+ }+ return 0;+}++#define G(r,i,a,b,c,d) \+ do { \+ a = a + b + m[blake2b_sigma[r][2*i+0]]; \+ d = rotr64(d ^ a, 32); \+ c = c + d; \+ b = rotr64(b ^ c, 24); \+ a = a + b + m[blake2b_sigma[r][2*i+1]]; \+ d = rotr64(d ^ a, 16); \+ c = c + d; \+ b = rotr64(b ^ c, 63); \+ } while(0)++#define ROUND(r) \+ do { \+ G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \+ G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \+ G(r,2,v[ 2],v[ 6],v[10],v[14]); \+ G(r,3,v[ 3],v[ 7],v[11],v[15]); \+ G(r,4,v[ 0],v[ 5],v[10],v[15]); \+ G(r,5,v[ 1],v[ 6],v[11],v[12]); \+ G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \+ G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \+ } while(0)++static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )+{+ uint64_t m[16];+ uint64_t v[16];+ size_t i;++ for( i = 0; i < 16; ++i ) {+ m[i] = load64( block + i * sizeof( m[i] ) );+ }++ for( i = 0; i < 8; ++i ) {+ v[i] = S->h[i];+ }++ v[ 8] = blake2b_IV[0];+ v[ 9] = blake2b_IV[1];+ v[10] = blake2b_IV[2];+ v[11] = blake2b_IV[3];+ v[12] = blake2b_IV[4] ^ S->t[0];+ v[13] = blake2b_IV[5] ^ S->t[1];+ v[14] = blake2b_IV[6] ^ S->f[0];+ v[15] = blake2b_IV[7] ^ S->f[1];++ ROUND( 0 );+ ROUND( 1 );+ ROUND( 2 );+ ROUND( 3 );+ ROUND( 4 );+ ROUND( 5 );+ ROUND( 6 );+ ROUND( 7 );+ ROUND( 8 );+ ROUND( 9 );+ ROUND( 10 );+ ROUND( 11 );++ for( i = 0; i < 8; ++i ) {+ S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];+ }+}++#undef G+#undef ROUND++int blake2b_update( blake2b_state *S, const void *pin, size_t inlen )+{+ const unsigned char * in = (const unsigned char *)pin;+ if( inlen > 0 )+ {+ size_t left = S->buflen;+ size_t fill = BLAKE2B_BLOCKBYTES - left;+ if( inlen > fill )+ {+ S->buflen = 0;+ memcpy( S->buf + left, in, fill ); /* Fill buffer */+ blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );+ blake2b_compress( S, S->buf ); /* Compress */+ in += fill; inlen -= fill;+ while(inlen > BLAKE2B_BLOCKBYTES) {+ blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);+ blake2b_compress( S, in );+ in += BLAKE2B_BLOCKBYTES;+ inlen -= BLAKE2B_BLOCKBYTES;+ }+ }+ memcpy( S->buf + S->buflen, in, inlen );+ S->buflen += inlen;+ }+ return 0;+}++int blake2b_final( blake2b_state *S, void *out, size_t outlen )+{+ uint8_t buffer[BLAKE2B_OUTBYTES] = {0};+ size_t i;++ if( out == NULL || outlen < S->outlen )+ return -1;++ if( blake2b_is_lastblock( S ) )+ return -1;++ blake2b_increment_counter( S, S->buflen );+ blake2b_set_lastblock( S );+ memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */+ blake2b_compress( S, S->buf );++ for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */+ store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );++ memcpy( out, buffer, S->outlen );+ secure_zero_memory(buffer, sizeof(buffer));+ return 0;+}++/* inlen, at least, should be uint64_t. Others can be size_t. */+int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_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( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;++ if( keylen > BLAKE2B_KEYBYTES ) return -1;++ if( keylen > 0 )+ {+ if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;+ }+ else+ {+ if( blake2b_init( S, outlen ) < 0 ) return -1;+ }++ blake2b_update( S, ( const uint8_t * )in, inlen );+ blake2b_final( S, out, outlen );+ return 0;+}++int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) {+ return blake2b(out, outlen, in, inlen, key, keylen);+}++#if defined(SUPERCOP)+int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )+{+ return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 );+}+#endif++#if defined(BLAKE2B_SELFTEST)+#include <string.h>+#include "blake2-kat.h"+int main( void )+{+ uint8_t key[BLAKE2B_KEYBYTES];+ uint8_t buf[BLAKE2_KAT_LENGTH];+ size_t i, step;++ for( i = 0; i < BLAKE2B_KEYBYTES; ++i )+ key[i] = ( uint8_t )i;++ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )+ buf[i] = ( uint8_t )i;++ /* Test simple API */+ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )+ {+ uint8_t hash[BLAKE2B_OUTBYTES];+ blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES );++ if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )+ {+ goto fail;+ }+ }++ /* Test streaming API */+ for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) {+ for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {+ uint8_t hash[BLAKE2B_OUTBYTES];+ blake2b_state S;+ uint8_t * p = buf;+ size_t mlen = i;+ int err = 0;++ if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) {+ goto fail;+ }++ while (mlen >= step) {+ if ( (err = blake2b_update(&S, p, step)) < 0 ) {+ goto fail;+ }+ mlen -= step;+ p += step;+ }+ if ( (err = blake2b_update(&S, p, mlen)) < 0) {+ goto fail;+ }+ if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) {+ goto fail;+ }++ if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) {+ goto fail;+ }+ }+ }++ puts( "ok" );+ return 0;+fail:+ puts("error");+ return -1;+}+#endif
− cbits/ref/blake2b.c
@@ -1,416 +0,0 @@-/*- BLAKE2 reference source code package - reference C implementations- - Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the- terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at- your option. The terms of these licenses can be found at:- - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0- - OpenSSL license : https://www.openssl.org/source/license.html- - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- - More information about the BLAKE2 hash function can be found at- https://blake2.net.-*/--#include <stdint.h>-#include <string.h>-#include <stdio.h>--#include "blake2.h"-#include "blake2-impl.h"--static const uint64_t blake2b_IV[8] =-{- 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,- 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,- 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,- 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL-};--static const uint8_t blake2b_sigma[12][16] =-{- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,- { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,- { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,- { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,- { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,- { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,- { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,- { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,- { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }-};---BLAKE2_LOCAL_INLINE(int) blake2b_set_lastnode( blake2b_state *S )-{- S->f[1] = -1;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastnode( blake2b_state *S )-{- S->f[1] = 0;- return 0;-}--/* Some helper functions, not necessarily useful */-BLAKE2_LOCAL_INLINE(int) blake2b_is_lastblock( const blake2b_state *S )-{- return S->f[0] != 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_set_lastblock( blake2b_state *S )-{- if( S->last_node ) blake2b_set_lastnode( S );-- S->f[0] = -1;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastblock( blake2b_state *S )-{- if( S->last_node ) blake2b_clear_lastnode( S );-- S->f[0] = 0;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_increment_counter( blake2b_state *S, const uint64_t inc )-{- S->t[0] += inc;- S->t[1] += ( S->t[0] < inc );- return 0;-}----/* Parameter-related functions */-BLAKE2_LOCAL_INLINE(int) blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length )-{- P->digest_length = digest_length;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )-{- P->fanout = fanout;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )-{- P->depth = depth;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )-{- store32( &P->leaf_length, leaf_length );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )-{- store64( &P->node_offset, node_offset );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )-{- P->node_depth = node_depth;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )-{- P->inner_length = inner_length;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )-{- memcpy( P->salt, salt, BLAKE2B_SALTBYTES );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )-{- memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_init0( blake2b_state *S )-{- memset( S, 0, sizeof( blake2b_state ) );-- for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];-- return 0;-}--/* init xors IV with input parameter block */-int blake2b_init_param( blake2b_state *S, const blake2b_param *P )-{- const uint8_t *p = ( const uint8_t * )( P );-- blake2b_init0( S );-- /* IV XOR ParamBlock */- for( size_t i = 0; i < 8; ++i )- S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );-- return 0;-}----int blake2b_init( blake2b_state *S, const uint8_t outlen )-{- blake2b_param P[1];-- if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;-- P->digest_length = outlen;- P->key_length = 0;- P->fanout = 1;- P->depth = 1;- store32( &P->leaf_length, 0 );- store64( &P->node_offset, 0 );- 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 ) );- return blake2b_init_param( S, P );-}---int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )-{- blake2b_param P[1];-- if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;-- if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;-- P->digest_length = outlen;- P->key_length = keylen;- P->fanout = 1;- P->depth = 1;- store32( &P->leaf_length, 0 );- store64( &P->node_offset, 0 );- 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;-- {- 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 ); /* Burn the key from stack */- }- return 0;-}--static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )-{- uint64_t m[16];- uint64_t v[16];- int i;-- for( i = 0; i < 16; ++i )- m[i] = load64( block + i * sizeof( m[i] ) );-- for( i = 0; i < 8; ++i )- v[i] = S->h[i];-- v[ 8] = blake2b_IV[0];- v[ 9] = blake2b_IV[1];- v[10] = blake2b_IV[2];- v[11] = blake2b_IV[3];- v[12] = S->t[0] ^ blake2b_IV[4];- v[13] = S->t[1] ^ blake2b_IV[5];- v[14] = S->f[0] ^ blake2b_IV[6];- v[15] = S->f[1] ^ blake2b_IV[7];-#define G(r,i,a,b,c,d) \- do { \- a = a + b + m[blake2b_sigma[r][2*i+0]]; \- d = rotr64(d ^ a, 32); \- c = c + d; \- b = rotr64(b ^ c, 24); \- a = a + b + m[blake2b_sigma[r][2*i+1]]; \- d = rotr64(d ^ a, 16); \- c = c + d; \- b = rotr64(b ^ c, 63); \- } while(0)-#define ROUND(r) \- do { \- G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \- G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \- G(r,2,v[ 2],v[ 6],v[10],v[14]); \- G(r,3,v[ 3],v[ 7],v[11],v[15]); \- G(r,4,v[ 0],v[ 5],v[10],v[15]); \- G(r,5,v[ 1],v[ 6],v[11],v[12]); \- G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \- G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \- } while(0)- ROUND( 0 );- ROUND( 1 );- ROUND( 2 );- ROUND( 3 );- ROUND( 4 );- ROUND( 5 );- ROUND( 6 );- ROUND( 7 );- ROUND( 8 );- ROUND( 9 );- ROUND( 10 );- ROUND( 11 );-- for( i = 0; i < 8; ++i )- S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];--#undef G-#undef ROUND- return 0;-}--/* inlen now in bytes */-int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen )-{- while( inlen > 0 )- {- size_t left = S->buflen;- size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;-- if( inlen > fill )- {- memcpy( S->buf + left, in, fill ); /* Fill buffer */- S->buflen += fill;- blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );- blake2b_compress( S, S->buf ); /* Compress */- memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */- S->buflen -= BLAKE2B_BLOCKBYTES;- in += fill;- inlen -= fill;- }- else /* inlen <= fill */- {- memcpy( S->buf + left, in, inlen );- S->buflen += inlen; /* Be lazy, do not compress */- in += inlen;- inlen -= inlen;- }- }-- return 0;-}--/* Is this correct? */-int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen )-{- uint8_t buffer[BLAKE2B_OUTBYTES] = {0};-- if( out == NULL || outlen == 0 || outlen > BLAKE2B_OUTBYTES )- return -1;-- if( blake2b_is_lastblock( S ) )- return -1;-- if( S->buflen > BLAKE2B_BLOCKBYTES )- {- blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );- blake2b_compress( S, S->buf );- S->buflen -= BLAKE2B_BLOCKBYTES;- memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );- }-- blake2b_increment_counter( S, S->buflen );- blake2b_set_lastblock( S );- memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */- blake2b_compress( S, S->buf );-- for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */- store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );-- memcpy( out, buffer, outlen );- return 0;-}--/* inlen, at least, should be uint64_t. Others can be size_t. */-int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, 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( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;-- if( keylen > BLAKE2B_KEYBYTES ) return -1;-- if( keylen > 0 )- {- if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;- }- else- {- if( blake2b_init( S, outlen ) < 0 ) return -1;- }-- blake2b_update( S, ( const uint8_t * )in, inlen );- blake2b_final( S, out, outlen );- return 0;-}--#if defined(SUPERCOP)-int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )-{- return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 );-}-#endif--#if defined(BLAKE2B_SELFTEST)-#include <string.h>-#include "blake2-kat.h"-int main( int argc, char **argv )-{- uint8_t key[BLAKE2B_KEYBYTES];- uint8_t buf[KAT_LENGTH];-- for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i )- key[i] = ( uint8_t )i;-- for( size_t i = 0; i < KAT_LENGTH; ++i )- buf[i] = ( uint8_t )i;-- for( size_t i = 0; i < KAT_LENGTH; ++i )- {- uint8_t hash[BLAKE2B_OUTBYTES];- blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );-- if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )- {- puts( "error" );- return -1;- }- }-- puts( "ok" );- return 0;-}-#endif-
+ cbits/ref/blake2bp-ref.c view
@@ -0,0 +1,359 @@+/*+ BLAKE2 reference source code package - reference C implementations++ Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the+ terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at+ your option. The terms of these licenses can be found at:++ - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0+ - OpenSSL license : https://www.openssl.org/source/license.html+ - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0++ More information about the BLAKE2 hash function can be found at+ https://blake2.net.+*/++#include <stdio.h>+#include <stdlib.h>+#include <string.h>+#include <stdint.h>++#if defined(_OPENMP)+#include <omp.h>+#endif++#include "blake2.h"+#include "blake2-impl.h"++#define PARALLELISM_DEGREE 4++/*+ blake2b_init_param defaults to setting the expecting output length+ from the digest_length parameter block field.++ In some cases, however, we do not want this, as the output length+ of these instances is given by inner_length instead.+*/+static int blake2bp_init_leaf_param( blake2b_state *S, const blake2b_param *P )+{+ int err = blake2b_init_param(S, P);+ S->outlen = P->inner_length;+ return err;+}++static int blake2bp_init_leaf( blake2b_state *S, size_t outlen, size_t keylen, uint64_t offset )+{+ blake2b_param P[1];+ P->digest_length = (uint8_t)outlen;+ P->key_length = (uint8_t)keylen;+ P->fanout = PARALLELISM_DEGREE;+ P->depth = 2;+ store32( &P->leaf_length, 0 );+ store32( &P->node_offset, offset );+ store32( &P->xof_length, 0 );+ P->node_depth = 0;+ P->inner_length = BLAKE2B_OUTBYTES;+ memset( P->reserved, 0, sizeof( P->reserved ) );+ memset( P->salt, 0, sizeof( P->salt ) );+ memset( P->personal, 0, sizeof( P->personal ) );+ return blake2bp_init_leaf_param( S, P );+}++static int blake2bp_init_root( blake2b_state *S, size_t outlen, size_t keylen )+{+ blake2b_param P[1];+ P->digest_length = (uint8_t)outlen;+ P->key_length = (uint8_t)keylen;+ P->fanout = PARALLELISM_DEGREE;+ P->depth = 2;+ store32( &P->leaf_length, 0 );+ store32( &P->node_offset, 0 );+ store32( &P->xof_length, 0 );+ P->node_depth = 1;+ P->inner_length = BLAKE2B_OUTBYTES;+ memset( P->reserved, 0, sizeof( P->reserved ) );+ memset( P->salt, 0, sizeof( P->salt ) );+ memset( P->personal, 0, sizeof( P->personal ) );+ return blake2b_init_param( S, P );+}+++int blake2bp_init( blake2bp_state *S, size_t outlen )+{+ size_t i;++ if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;++ memset( S->buf, 0, sizeof( S->buf ) );+ S->buflen = 0;+ S->outlen = outlen;++ if( blake2bp_init_root( S->R, outlen, 0 ) < 0 )+ return -1;++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ if( blake2bp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1;++ S->R->last_node = 1;+ S->S[PARALLELISM_DEGREE - 1]->last_node = 1;+ return 0;+}++int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen )+{+ size_t i;++ if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;++ if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;++ memset( S->buf, 0, sizeof( S->buf ) );+ S->buflen = 0;+ S->outlen = outlen;++ if( blake2bp_init_root( S->R, outlen, keylen ) < 0 )+ return -1;++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ if( blake2bp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1;++ S->R->last_node = 1;+ S->S[PARALLELISM_DEGREE - 1]->last_node = 1;+ {+ uint8_t block[BLAKE2B_BLOCKBYTES];+ memset( block, 0, BLAKE2B_BLOCKBYTES );+ memcpy( block, key, keylen );++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES );++ secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */+ }+ return 0;+}+++int blake2bp_update( blake2bp_state *S, const void *pin, size_t inlen )+{+ const unsigned char * in = (const unsigned char *)pin;+ size_t left = S->buflen;+ size_t fill = sizeof( S->buf ) - left;+ size_t i;++ if( left && inlen >= fill )+ {+ memcpy( S->buf + left, in, fill );++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES );++ in += fill;+ inlen -= fill;+ left = 0;+ }++#if defined(_OPENMP)+ #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE)+#else++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+#endif+ {+#if defined(_OPENMP)+ size_t i = omp_get_thread_num();+#endif+ size_t inlen__ = inlen;+ const unsigned char *in__ = ( const unsigned char * )in;+ in__ += i * BLAKE2B_BLOCKBYTES;++ while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )+ {+ blake2b_update( S->S[i], in__, BLAKE2B_BLOCKBYTES );+ in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;+ inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;+ }+ }++ in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES );+ inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;++ if( inlen > 0 )+ memcpy( S->buf + left, in, inlen );++ S->buflen = left + inlen;+ return 0;+}++int blake2bp_final( blake2bp_state *S, void *out, size_t outlen )+{+ uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];+ size_t i;++ if(out == NULL || outlen < S->outlen) {+ return -1;+ }++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ {+ if( S->buflen > i * BLAKE2B_BLOCKBYTES )+ {+ size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES;++ if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES;++ blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left );+ }++ blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES );+ }++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES );++ return blake2b_final( S->R, out, S->outlen );+}++int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )+{+ uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];+ blake2b_state S[PARALLELISM_DEGREE][1];+ blake2b_state FS[1];+ size_t i;++ /* Verify parameters */+ if ( NULL == in && inlen > 0 ) return -1;++ if ( NULL == out ) return -1;++ if( NULL == key && keylen > 0 ) return -1;++ if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;++ if( keylen > BLAKE2B_KEYBYTES ) return -1;++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ if( blake2bp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1;++ S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */++ if( keylen > 0 )+ {+ uint8_t block[BLAKE2B_BLOCKBYTES];+ memset( block, 0, BLAKE2B_BLOCKBYTES );+ memcpy( block, key, keylen );++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES );++ secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */+ }++#if defined(_OPENMP)+ #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)+#else++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+#endif+ {+#if defined(_OPENMP)+ size_t i = omp_get_thread_num();+#endif+ size_t inlen__ = inlen;+ const unsigned char *in__ = ( const unsigned char * )in;+ in__ += i * BLAKE2B_BLOCKBYTES;++ while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )+ {+ blake2b_update( S[i], in__, BLAKE2B_BLOCKBYTES );+ in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;+ inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;+ }++ if( inlen__ > i * BLAKE2B_BLOCKBYTES )+ {+ const size_t left = inlen__ - i * BLAKE2B_BLOCKBYTES;+ const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES;+ blake2b_update( S[i], in__, len );+ }++ blake2b_final( S[i], hash[i], BLAKE2B_OUTBYTES );+ }++ if( blake2bp_init_root( FS, outlen, keylen ) < 0 )+ return -1;++ FS->last_node = 1; /* Mark as last node */++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES );++ return blake2b_final( FS, out, outlen );;+}++#if defined(BLAKE2BP_SELFTEST)+#include <string.h>+#include "blake2-kat.h"+int main( void )+{+ uint8_t key[BLAKE2B_KEYBYTES];+ uint8_t buf[BLAKE2_KAT_LENGTH];+ size_t i, step;++ for( i = 0; i < BLAKE2B_KEYBYTES; ++i )+ key[i] = ( uint8_t )i;++ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )+ buf[i] = ( uint8_t )i;++ /* Test simple API */+ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )+ {+ uint8_t hash[BLAKE2B_OUTBYTES];+ blake2bp( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES );++ if( 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) )+ {+ goto fail;+ }+ }++ /* Test streaming API */+ for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) {+ for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {+ uint8_t hash[BLAKE2B_OUTBYTES];+ blake2bp_state S;+ uint8_t * p = buf;+ size_t mlen = i;+ int err = 0;++ if( (err = blake2bp_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) {+ goto fail;+ }++ while (mlen >= step) {+ if ( (err = blake2bp_update(&S, p, step)) < 0 ) {+ goto fail;+ }+ mlen -= step;+ p += step;+ }+ if ( (err = blake2bp_update(&S, p, mlen)) < 0) {+ goto fail;+ }+ if ( (err = blake2bp_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) {+ goto fail;+ }++ if (0 != memcmp(hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES)) {+ goto fail;+ }+ }+ }++ puts( "ok" );+ return 0;+fail:+ puts("error");+ return -1;+}+#endif
− cbits/ref/blake2bp.c
@@ -1,293 +0,0 @@-/*- BLAKE2 reference source code package - reference C implementations- - Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the- terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at- your option. The terms of these licenses can be found at:- - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0- - OpenSSL license : https://www.openssl.org/source/license.html- - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- - More information about the BLAKE2 hash function can be found at- https://blake2.net.-*/--#include <stdio.h>-#include <stdlib.h>-#include <string.h>-#include <stdint.h>--#if defined(_OPENMP)-#include <omp.h>-#endif--#include "blake2.h"-#include "blake2-impl.h"--#define PARALLELISM_DEGREE 4--BLAKE2_LOCAL_INLINE(int) blake2bp_init_leaf( blake2b_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )-{- blake2b_param P[1];- P->digest_length = outlen;- P->key_length = keylen;- P->fanout = PARALLELISM_DEGREE;- P->depth = 2;- store32( &P->leaf_length, 0 );- store64( &P->node_offset, offset );- P->node_depth = 0;- P->inner_length = BLAKE2B_OUTBYTES;- memset( P->reserved, 0, sizeof( P->reserved ) );- memset( P->salt, 0, sizeof( P->salt ) );- memset( P->personal, 0, sizeof( P->personal ) );- return blake2b_init_param( S, P );-}--BLAKE2_LOCAL_INLINE(int) blake2bp_init_root( blake2b_state *S, uint8_t outlen, uint8_t keylen )-{- blake2b_param P[1];- P->digest_length = outlen;- P->key_length = keylen;- P->fanout = PARALLELISM_DEGREE;- P->depth = 2;- store32( &P->leaf_length, 0 );- store64( &P->node_offset, 0 );- P->node_depth = 1;- P->inner_length = BLAKE2B_OUTBYTES;- memset( P->reserved, 0, sizeof( P->reserved ) );- memset( P->salt, 0, sizeof( P->salt ) );- memset( P->personal, 0, sizeof( P->personal ) );- return blake2b_init_param( S, P );-}---int blake2bp_init( blake2bp_state *S, const uint8_t outlen )-{- if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;-- memset( S->buf, 0, sizeof( S->buf ) );- S->buflen = 0;-- if( blake2bp_init_root( S->R, outlen, 0 ) < 0 )- return -1;-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- if( blake2bp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1;-- S->R->last_node = 1;- S->S[PARALLELISM_DEGREE - 1]->last_node = 1;- return 0;-}--int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )-{- if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;-- if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;-- memset( S->buf, 0, sizeof( S->buf ) );- S->buflen = 0;-- if( blake2bp_init_root( S->R, outlen, keylen ) < 0 )- return -1;-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- if( blake2bp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1;-- S->R->last_node = 1;- S->S[PARALLELISM_DEGREE - 1]->last_node = 1;- {- uint8_t block[BLAKE2B_BLOCKBYTES];- memset( block, 0, BLAKE2B_BLOCKBYTES );- memcpy( block, key, keylen );-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES );-- secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */- }- return 0;-}---int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen )-{- size_t left = S->buflen;- size_t fill = sizeof( S->buf ) - left;-- if( left && inlen >= fill )- {- memcpy( S->buf + left, in, fill );-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES );-- in += fill;- inlen -= fill;- left = 0;- }--#if defined(_OPENMP)- #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE)-#else-- for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )-#endif- {-#if defined(_OPENMP)- size_t id__ = omp_get_thread_num();-#endif- uint64_t inlen__ = inlen;- const uint8_t *in__ = ( const uint8_t * )in;- in__ += id__ * BLAKE2B_BLOCKBYTES;-- while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )- {- blake2b_update( S->S[id__], in__, BLAKE2B_BLOCKBYTES );- in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;- inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;- }- }-- in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES );- inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;-- if( inlen > 0 )- memcpy( S->buf + left, in, inlen );-- S->buflen = left + inlen;- return 0;-}--int blake2bp_final( blake2bp_state *S, uint8_t *out, const uint8_t outlen )-{- uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- {- if( S->buflen > i * BLAKE2B_BLOCKBYTES )- {- size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES;-- if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES;-- blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left );- }-- blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES );- }-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES );-- - return blake2b_final( S->R, out, outlen );-}--int blake2bp( uint8_t *out, const void *in, const void *key, uint8_t outlen, uint64_t inlen, uint8_t keylen )-{- uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];- blake2b_state S[PARALLELISM_DEGREE][1];- blake2b_state FS[1];-- /* Verify parameters */- if ( NULL == in && inlen > 0 ) return -1;-- if ( NULL == out ) return -1;-- if( NULL == key && keylen > 0 ) return -1;-- if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;-- if( keylen > BLAKE2B_KEYBYTES ) return -1;-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- if( blake2bp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1;-- S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */-- if( keylen > 0 )- {- uint8_t block[BLAKE2B_BLOCKBYTES];- memset( block, 0, BLAKE2B_BLOCKBYTES );- memcpy( block, key, keylen );-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES );-- secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */- }--#if defined(_OPENMP)- #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)-#else-- for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )-#endif- {-#if defined(_OPENMP)- size_t id__ = omp_get_thread_num();-#endif- uint64_t inlen__ = inlen;- const uint8_t *in__ = ( const uint8_t * )in;- in__ += id__ * BLAKE2B_BLOCKBYTES;-- while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )- {- blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES );- in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;- inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;- }-- if( inlen__ > id__ * BLAKE2B_BLOCKBYTES )- {- const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES;- const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES;- blake2b_update( S[id__], in__, len );- }-- blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES );- }-- if( blake2bp_init_root( FS, outlen, keylen ) < 0 )- return -1;-- FS->last_node = 1; /* Mark as last node */-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES );-- return blake2b_final( FS, out, outlen );;-}--#if defined(BLAKE2BP_SELFTEST)-#include <string.h>-#include "blake2-kat.h"-int main( int argc, char **argv )-{- uint8_t key[BLAKE2B_KEYBYTES];- uint8_t buf[KAT_LENGTH];-- for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i )- key[i] = ( uint8_t )i;-- for( size_t i = 0; i < KAT_LENGTH; ++i )- buf[i] = ( uint8_t )i;-- for( size_t i = 0; i < KAT_LENGTH; ++i )- {- uint8_t hash[BLAKE2B_OUTBYTES];- blake2bp( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );-- if( 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) )- {- puts( "error" );- return -1;- }- }-- puts( "ok" );- return 0;-}-#endif
+ cbits/ref/blake2s-ref.c view
@@ -0,0 +1,367 @@+/*+ BLAKE2 reference source code package - reference C implementations++ Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the+ terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at+ your option. The terms of these licenses can be found at:++ - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0+ - OpenSSL license : https://www.openssl.org/source/license.html+ - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0++ More information about the BLAKE2 hash function can be found at+ https://blake2.net.+*/++#include <stdint.h>+#include <string.h>+#include <stdio.h>++#include "blake2.h"+#include "blake2-impl.h"++static const uint32_t blake2s_IV[8] =+{+ 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,+ 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL+};++static const uint8_t blake2s_sigma[10][16] =+{+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,+ { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,+ { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,+ { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,+ { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,+ { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,+ { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,+ { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,+ { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,+};++static void blake2s_set_lastnode( blake2s_state *S )+{+ S->f[1] = (uint32_t)-1;+}++/* Some helper functions, not necessarily useful */+static int blake2s_is_lastblock( const blake2s_state *S )+{+ return S->f[0] != 0;+}++static void blake2s_set_lastblock( blake2s_state *S )+{+ if( S->last_node ) blake2s_set_lastnode( S );++ S->f[0] = (uint32_t)-1;+}++static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc )+{+ S->t[0] += inc;+ S->t[1] += ( S->t[0] < inc );+}++static void blake2s_init0( blake2s_state *S )+{+ size_t i;+ memset( S, 0, sizeof( blake2s_state ) );++ for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];+}++/* init2 xors IV with input parameter block */+int blake2s_init_param( blake2s_state *S, const blake2s_param *P )+{+ const unsigned char *p = ( const unsigned char * )( P );+ size_t i;++ blake2s_init0( S );++ /* IV XOR ParamBlock */+ for( i = 0; i < 8; ++i )+ S->h[i] ^= load32( &p[i * 4] );++ S->outlen = P->digest_length;+ return 0;+}+++/* Sequential blake2s initialization */+int blake2s_init( blake2s_state *S, size_t outlen )+{+ blake2s_param P[1];++ /* Move interval verification here? */+ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;++ P->digest_length = (uint8_t)outlen;+ P->key_length = 0;+ P->fanout = 1;+ P->depth = 1;+ store32( &P->leaf_length, 0 );+ store32( &P->node_offset, 0 );+ store16( &P->xof_length, 0 );+ 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 ) );+ return blake2s_init_param( S, P );+}++int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )+{+ blake2s_param P[1];++ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;++ if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;++ P->digest_length = (uint8_t)outlen;+ P->key_length = (uint8_t)keylen;+ P->fanout = 1;+ P->depth = 1;+ store32( &P->leaf_length, 0 );+ store32( &P->node_offset, 0 );+ store16( &P->xof_length, 0 );+ 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( blake2s_init_param( S, P ) < 0 ) return -1;++ {+ uint8_t block[BLAKE2S_BLOCKBYTES];+ memset( block, 0, BLAKE2S_BLOCKBYTES );+ memcpy( block, key, keylen );+ blake2s_update( S, block, BLAKE2S_BLOCKBYTES );+ secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */+ }+ return 0;+}++#define G(r,i,a,b,c,d) \+ do { \+ a = a + b + m[blake2s_sigma[r][2*i+0]]; \+ d = rotr32(d ^ a, 16); \+ c = c + d; \+ b = rotr32(b ^ c, 12); \+ a = a + b + m[blake2s_sigma[r][2*i+1]]; \+ d = rotr32(d ^ a, 8); \+ c = c + d; \+ b = rotr32(b ^ c, 7); \+ } while(0)++#define ROUND(r) \+ do { \+ G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \+ G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \+ G(r,2,v[ 2],v[ 6],v[10],v[14]); \+ G(r,3,v[ 3],v[ 7],v[11],v[15]); \+ G(r,4,v[ 0],v[ 5],v[10],v[15]); \+ G(r,5,v[ 1],v[ 6],v[11],v[12]); \+ G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \+ G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \+ } while(0)++static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] )+{+ uint32_t m[16];+ uint32_t v[16];+ size_t i;++ for( i = 0; i < 16; ++i ) {+ m[i] = load32( in + i * sizeof( m[i] ) );+ }++ for( i = 0; i < 8; ++i ) {+ v[i] = S->h[i];+ }++ v[ 8] = blake2s_IV[0];+ v[ 9] = blake2s_IV[1];+ v[10] = blake2s_IV[2];+ v[11] = blake2s_IV[3];+ v[12] = S->t[0] ^ blake2s_IV[4];+ v[13] = S->t[1] ^ blake2s_IV[5];+ v[14] = S->f[0] ^ blake2s_IV[6];+ v[15] = S->f[1] ^ blake2s_IV[7];++ ROUND( 0 );+ ROUND( 1 );+ ROUND( 2 );+ ROUND( 3 );+ ROUND( 4 );+ ROUND( 5 );+ ROUND( 6 );+ ROUND( 7 );+ ROUND( 8 );+ ROUND( 9 );++ for( i = 0; i < 8; ++i ) {+ S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];+ }+}++#undef G+#undef ROUND++int blake2s_update( blake2s_state *S, const void *pin, size_t inlen )+{+ const unsigned char * in = (const unsigned char *)pin;+ if( inlen > 0 )+ {+ size_t left = S->buflen;+ size_t fill = BLAKE2S_BLOCKBYTES - left;+ if( inlen > fill )+ {+ S->buflen = 0;+ memcpy( S->buf + left, in, fill ); /* Fill buffer */+ blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );+ blake2s_compress( S, S->buf ); /* Compress */+ in += fill; inlen -= fill;+ while(inlen > BLAKE2S_BLOCKBYTES) {+ blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);+ blake2s_compress( S, in );+ in += BLAKE2S_BLOCKBYTES;+ inlen -= BLAKE2S_BLOCKBYTES;+ }+ }+ memcpy( S->buf + S->buflen, in, inlen );+ S->buflen += inlen;+ }+ return 0;+}++int blake2s_final( blake2s_state *S, void *out, size_t outlen )+{+ uint8_t buffer[BLAKE2S_OUTBYTES] = {0};+ size_t i;++ if( out == NULL || outlen < S->outlen )+ return -1;++ if( blake2s_is_lastblock( S ) )+ return -1;++ blake2s_increment_counter( S, ( uint32_t )S->buflen );+ blake2s_set_lastblock( S );+ memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */+ blake2s_compress( S, S->buf );++ for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */+ store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );++ memcpy( out, buffer, outlen );+ secure_zero_memory(buffer, sizeof(buffer));+ return 0;+}++int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )+{+ blake2s_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( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;++ if( keylen > BLAKE2S_KEYBYTES ) return -1;++ if( keylen > 0 )+ {+ if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;+ }+ else+ {+ if( blake2s_init( S, outlen ) < 0 ) return -1;+ }++ blake2s_update( S, ( const uint8_t * )in, inlen );+ blake2s_final( S, out, outlen );+ return 0;+}++#if defined(SUPERCOP)+int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )+{+ return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 );+}+#endif++#if defined(BLAKE2S_SELFTEST)+#include <string.h>+#include "blake2-kat.h"+int main( void )+{+ uint8_t key[BLAKE2S_KEYBYTES];+ uint8_t buf[BLAKE2_KAT_LENGTH];+ size_t i, step;++ for( i = 0; i < BLAKE2S_KEYBYTES; ++i )+ key[i] = ( uint8_t )i;++ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )+ buf[i] = ( uint8_t )i;++ /* Test simple API */+ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )+ {+ uint8_t hash[BLAKE2S_OUTBYTES];+ blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES );++ if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )+ {+ goto fail;+ }+ }++ /* Test streaming API */+ for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {+ for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {+ uint8_t hash[BLAKE2S_OUTBYTES];+ blake2s_state S;+ uint8_t * p = buf;+ size_t mlen = i;+ int err = 0;++ if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {+ goto fail;+ }++ while (mlen >= step) {+ if ( (err = blake2s_update(&S, p, step)) < 0 ) {+ goto fail;+ }+ mlen -= step;+ p += step;+ }+ if ( (err = blake2s_update(&S, p, mlen)) < 0) {+ goto fail;+ }+ if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {+ goto fail;+ }++ if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) {+ goto fail;+ }+ }+ }++ puts( "ok" );+ return 0;+fail:+ puts("error");+ return -1;+}+#endif
− cbits/ref/blake2s.c
@@ -1,406 +0,0 @@-/*- BLAKE2 reference source code package - reference C implementations- - Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the- terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at- your option. The terms of these licenses can be found at:- - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0- - OpenSSL license : https://www.openssl.org/source/license.html- - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- - More information about the BLAKE2 hash function can be found at- https://blake2.net.-*/--#include <stdint.h>-#include <string.h>-#include <stdio.h>--#include "blake2.h"-#include "blake2-impl.h"--static const uint32_t blake2s_IV[8] =-{- 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,- 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL-};--static const uint8_t blake2s_sigma[10][16] =-{- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,- { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,- { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,- { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,- { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,- { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,- { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,- { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,- { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,-};--BLAKE2_LOCAL_INLINE(int) blake2s_set_lastnode( blake2s_state *S )-{- S->f[1] = -1;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastnode( blake2s_state *S )-{- S->f[1] = 0;- return 0;-}--/* Some helper functions, not necessarily useful */-BLAKE2_LOCAL_INLINE(int) blake2s_is_lastblock( const blake2s_state *S )-{- return S->f[0] != 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_set_lastblock( blake2s_state *S )-{- if( S->last_node ) blake2s_set_lastnode( S );-- S->f[0] = -1;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastblock( blake2s_state *S )-{- if( S->last_node ) blake2s_clear_lastnode( S );-- S->f[0] = 0;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_increment_counter( blake2s_state *S, const uint32_t inc )-{- S->t[0] += inc;- S->t[1] += ( S->t[0] < inc );- return 0;-}--/* Parameter-related functions */-BLAKE2_LOCAL_INLINE(int) blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )-{- P->digest_length = digest_length;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )-{- P->fanout = fanout;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )-{- P->depth = depth;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )-{- store32( &P->leaf_length, leaf_length );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )-{- store48( P->node_offset, node_offset );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )-{- P->node_depth = node_depth;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )-{- P->inner_length = inner_length;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )-{- memcpy( P->salt, salt, BLAKE2S_SALTBYTES );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )-{- memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_init0( blake2s_state *S )-{- memset( S, 0, sizeof( blake2s_state ) );-- for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];-- return 0;-}--/* init2 xors IV with input parameter block */-int blake2s_init_param( blake2s_state *S, const blake2s_param *P )-{- const uint32_t *p = ( const uint32_t * )( P );-- blake2s_init0( S );-- /* IV XOR ParamBlock */- for( size_t i = 0; i < 8; ++i )- S->h[i] ^= load32( &p[i] );-- return 0;-}---/* Sequential blake2s initialization */-int blake2s_init( blake2s_state *S, const uint8_t outlen )-{- blake2s_param P[1];-- /* Move interval verification here? */- if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;-- P->digest_length = outlen;- P->key_length = 0;- P->fanout = 1;- P->depth = 1;- store32( &P->leaf_length, 0 );- store48( &P->node_offset, 0 );- 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 ) );- return blake2s_init_param( S, P );-}--int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )-{- blake2s_param P[1];-- if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;-- if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;-- P->digest_length = outlen;- P->key_length = keylen;- P->fanout = 1;- P->depth = 1;- store32( &P->leaf_length, 0 );- store48( &P->node_offset, 0 );- 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( blake2s_init_param( S, P ) < 0 ) return -1;-- {- uint8_t block[BLAKE2S_BLOCKBYTES];- memset( block, 0, BLAKE2S_BLOCKBYTES );- memcpy( block, key, keylen );- blake2s_update( S, block, BLAKE2S_BLOCKBYTES );- secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */- }- return 0;-}--static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )-{- uint32_t m[16];- uint32_t v[16];-- for( size_t i = 0; i < 16; ++i )- m[i] = load32( block + i * sizeof( m[i] ) );-- for( size_t i = 0; i < 8; ++i )- v[i] = S->h[i];-- v[ 8] = blake2s_IV[0];- v[ 9] = blake2s_IV[1];- v[10] = blake2s_IV[2];- v[11] = blake2s_IV[3];- v[12] = S->t[0] ^ blake2s_IV[4];- v[13] = S->t[1] ^ blake2s_IV[5];- v[14] = S->f[0] ^ blake2s_IV[6];- v[15] = S->f[1] ^ blake2s_IV[7];-#define G(r,i,a,b,c,d) \- do { \- a = a + b + m[blake2s_sigma[r][2*i+0]]; \- d = rotr32(d ^ a, 16); \- c = c + d; \- b = rotr32(b ^ c, 12); \- a = a + b + m[blake2s_sigma[r][2*i+1]]; \- d = rotr32(d ^ a, 8); \- c = c + d; \- b = rotr32(b ^ c, 7); \- } while(0)-#define ROUND(r) \- do { \- G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \- G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \- G(r,2,v[ 2],v[ 6],v[10],v[14]); \- G(r,3,v[ 3],v[ 7],v[11],v[15]); \- G(r,4,v[ 0],v[ 5],v[10],v[15]); \- G(r,5,v[ 1],v[ 6],v[11],v[12]); \- G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \- G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \- } while(0)- ROUND( 0 );- ROUND( 1 );- ROUND( 2 );- ROUND( 3 );- ROUND( 4 );- ROUND( 5 );- ROUND( 6 );- ROUND( 7 );- ROUND( 8 );- ROUND( 9 );-- for( size_t i = 0; i < 8; ++i )- S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];--#undef G-#undef ROUND- return 0;-}---int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen )-{- while( inlen > 0 )- {- size_t left = S->buflen;- size_t fill = 2 * BLAKE2S_BLOCKBYTES - left;-- if( inlen > fill )- {- memcpy( S->buf + left, in, fill ); /* Fill buffer */- S->buflen += fill;- blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );- blake2s_compress( S, S->buf ); /* Compress */- memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); /* Shift buffer left */- S->buflen -= BLAKE2S_BLOCKBYTES;- in += fill;- inlen -= fill;- }- else /* inlen <= fill */- {- memcpy( S->buf + left, in, inlen );- S->buflen += inlen; /* Be lazy, do not compress */- in += inlen;- inlen -= inlen;- }- }-- return 0;-}--int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen )-{- uint8_t buffer[BLAKE2S_OUTBYTES] = {0};-- if( out == NULL || outlen == 0 || outlen > BLAKE2S_OUTBYTES )- return -1;-- if( blake2s_is_lastblock( S ) )- return -1;--- if( S->buflen > BLAKE2S_BLOCKBYTES )- {- blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );- blake2s_compress( S, S->buf );- S->buflen -= BLAKE2S_BLOCKBYTES;- memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );- }-- blake2s_increment_counter( S, ( uint32_t )S->buflen );- blake2s_set_lastblock( S );- memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */- blake2s_compress( S, S->buf );-- for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */- store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );- - memcpy( out, buffer, outlen );- return 0;-}--int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )-{- blake2s_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( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;-- if( keylen > BLAKE2S_KEYBYTES ) return -1;-- if( keylen > 0 )- {- if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;- }- else- {- if( blake2s_init( S, outlen ) < 0 ) return -1;- }-- blake2s_update( S, ( const uint8_t * )in, inlen );- blake2s_final( S, out, outlen );- return 0;-}--#if defined(SUPERCOP)-int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )-{- return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, inlen, 0 );-}-#endif--#if defined(BLAKE2S_SELFTEST)-#include <string.h>-#include "blake2-kat.h"-int main( int argc, char **argv )-{- uint8_t key[BLAKE2S_KEYBYTES];- uint8_t buf[KAT_LENGTH];-- for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i )- key[i] = ( uint8_t )i;-- for( size_t i = 0; i < KAT_LENGTH; ++i )- buf[i] = ( uint8_t )i;-- for( size_t i = 0; i < KAT_LENGTH; ++i )- {- uint8_t hash[BLAKE2S_OUTBYTES];- blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES );-- if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )- {- puts( "error" );- return -1;- }- }-- puts( "ok" );- return 0;-}-#endif--
+ cbits/ref/blake2sp-ref.c view
@@ -0,0 +1,359 @@+/*+ BLAKE2 reference source code package - reference C implementations++ Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the+ terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at+ your option. The terms of these licenses can be found at:++ - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0+ - OpenSSL license : https://www.openssl.org/source/license.html+ - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0++ More information about the BLAKE2 hash function can be found at+ https://blake2.net.+*/++#include <stdlib.h>+#include <string.h>+#include <stdio.h>++#if defined(_OPENMP)+#include <omp.h>+#endif++#include "blake2.h"+#include "blake2-impl.h"++#define PARALLELISM_DEGREE 8++/*+ blake2sp_init_param defaults to setting the expecting output length+ from the digest_length parameter block field.++ In some cases, however, we do not want this, as the output length+ of these instances is given by inner_length instead.+*/+static int blake2sp_init_leaf_param( blake2s_state *S, const blake2s_param *P )+{+ int err = blake2s_init_param(S, P);+ S->outlen = P->inner_length;+ return err;+}++static int blake2sp_init_leaf( blake2s_state *S, size_t outlen, size_t keylen, uint64_t offset )+{+ blake2s_param P[1];+ P->digest_length = (uint8_t)outlen;+ P->key_length = (uint8_t)keylen;+ P->fanout = PARALLELISM_DEGREE;+ P->depth = 2;+ store32( &P->leaf_length, 0 );+ store32( &P->node_offset, offset );+ store16( &P->xof_length, 0 );+ P->node_depth = 0;+ P->inner_length = BLAKE2S_OUTBYTES;+ memset( P->salt, 0, sizeof( P->salt ) );+ memset( P->personal, 0, sizeof( P->personal ) );+ return blake2sp_init_leaf_param( S, P );+}++static int blake2sp_init_root( blake2s_state *S, size_t outlen, size_t keylen )+{+ blake2s_param P[1];+ P->digest_length = (uint8_t)outlen;+ P->key_length = (uint8_t)keylen;+ P->fanout = PARALLELISM_DEGREE;+ P->depth = 2;+ store32( &P->leaf_length, 0 );+ store32( &P->node_offset, 0 );+ store16( &P->xof_length, 0 );+ P->node_depth = 1;+ P->inner_length = BLAKE2S_OUTBYTES;+ memset( P->salt, 0, sizeof( P->salt ) );+ memset( P->personal, 0, sizeof( P->personal ) );+ return blake2s_init_param( S, P );+}+++int blake2sp_init( blake2sp_state *S, size_t outlen )+{+ size_t i;++ if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;++ memset( S->buf, 0, sizeof( S->buf ) );+ S->buflen = 0;+ S->outlen = outlen;++ if( blake2sp_init_root( S->R, outlen, 0 ) < 0 )+ return -1;++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ if( blake2sp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1;++ S->R->last_node = 1;+ S->S[PARALLELISM_DEGREE - 1]->last_node = 1;+ return 0;+}++int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen )+{+ size_t i;++ if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;++ if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;++ memset( S->buf, 0, sizeof( S->buf ) );+ S->buflen = 0;+ S->outlen = outlen;++ if( blake2sp_init_root( S->R, outlen, keylen ) < 0 )+ return -1;++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ if( blake2sp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1;++ S->R->last_node = 1;+ S->S[PARALLELISM_DEGREE - 1]->last_node = 1;+ {+ uint8_t block[BLAKE2S_BLOCKBYTES];+ memset( block, 0, BLAKE2S_BLOCKBYTES );+ memcpy( block, key, keylen );++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES );++ secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */+ }+ return 0;+}+++int blake2sp_update( blake2sp_state *S, const void *pin, size_t inlen )+{+ const unsigned char * in = (const unsigned char *)pin;+ size_t left = S->buflen;+ size_t fill = sizeof( S->buf ) - left;+ size_t i;++ if( left && inlen >= fill )+ {+ memcpy( S->buf + left, in, fill );++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );++ in += fill;+ inlen -= fill;+ left = 0;+ }++#if defined(_OPENMP)+ #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE)+#else+ for( i = 0; i < PARALLELISM_DEGREE; ++i )+#endif+ {+#if defined(_OPENMP)+ size_t i = omp_get_thread_num();+#endif+ size_t inlen__ = inlen;+ const unsigned char *in__ = ( const unsigned char * )in;+ in__ += i * BLAKE2S_BLOCKBYTES;++ while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )+ {+ blake2s_update( S->S[i], in__, BLAKE2S_BLOCKBYTES );+ in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;+ inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;+ }+ }++ in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );+ inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;++ if( inlen > 0 )+ memcpy( S->buf + left, in, inlen );++ S->buflen = left + inlen;+ return 0;+}+++int blake2sp_final( blake2sp_state *S, void *out, size_t outlen )+{+ uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];+ size_t i;++ if(out == NULL || outlen < S->outlen) {+ return -1;+ }++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ {+ if( S->buflen > i * BLAKE2S_BLOCKBYTES )+ {+ size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;++ if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;++ blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );+ }++ blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES );+ }++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );++ return blake2s_final( S->R, out, S->outlen );+}+++int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )+{+ uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];+ blake2s_state S[PARALLELISM_DEGREE][1];+ blake2s_state FS[1];+ size_t i;++ /* Verify parameters */+ if ( NULL == in && inlen > 0 ) return -1;++ if ( NULL == out ) return -1;++ if ( NULL == key && keylen > 0) return -1;++ if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;++ if( keylen > BLAKE2S_KEYBYTES ) return -1;++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ if( blake2sp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1;++ S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */++ if( keylen > 0 )+ {+ uint8_t block[BLAKE2S_BLOCKBYTES];+ memset( block, 0, BLAKE2S_BLOCKBYTES );+ memcpy( block, key, keylen );++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );++ secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */+ }++#if defined(_OPENMP)+ #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)+#else++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+#endif+ {+#if defined(_OPENMP)+ size_t i = omp_get_thread_num();+#endif+ size_t inlen__ = inlen;+ const unsigned char *in__ = ( const unsigned char * )in;+ in__ += i * BLAKE2S_BLOCKBYTES;++ while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )+ {+ blake2s_update( S[i], in__, BLAKE2S_BLOCKBYTES );+ in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;+ inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;+ }++ if( inlen__ > i * BLAKE2S_BLOCKBYTES )+ {+ const size_t left = inlen__ - i * BLAKE2S_BLOCKBYTES;+ const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;+ blake2s_update( S[i], in__, len );+ }++ blake2s_final( S[i], hash[i], BLAKE2S_OUTBYTES );+ }++ if( blake2sp_init_root( FS, outlen, keylen ) < 0 )+ return -1;++ FS->last_node = 1;++ for( i = 0; i < PARALLELISM_DEGREE; ++i )+ blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );++ return blake2s_final( FS, out, outlen );+}++++#if defined(BLAKE2SP_SELFTEST)+#include <string.h>+#include "blake2-kat.h"+int main( void )+{+ uint8_t key[BLAKE2S_KEYBYTES];+ uint8_t buf[BLAKE2_KAT_LENGTH];+ size_t i, step;++ for( i = 0; i < BLAKE2S_KEYBYTES; ++i )+ key[i] = ( uint8_t )i;++ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )+ buf[i] = ( uint8_t )i;++ /* Test simple API */+ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )+ {+ uint8_t hash[BLAKE2S_OUTBYTES];+ blake2sp( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES );++ if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) )+ {+ goto fail;+ }+ }++ /* Test streaming API */+ for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {+ for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {+ uint8_t hash[BLAKE2S_OUTBYTES];+ blake2sp_state S;+ uint8_t * p = buf;+ size_t mlen = i;+ int err = 0;++ if( (err = blake2sp_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {+ goto fail;+ }++ while (mlen >= step) {+ if ( (err = blake2sp_update(&S, p, step)) < 0 ) {+ goto fail;+ }+ mlen -= step;+ p += step;+ }+ if ( (err = blake2sp_update(&S, p, mlen)) < 0) {+ goto fail;+ }+ if ( (err = blake2sp_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {+ goto fail;+ }++ if (0 != memcmp(hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES)) {+ goto fail;+ }+ }+ }++ puts( "ok" );+ return 0;+fail:+ puts("error");+ return -1;+}+#endif
− cbits/ref/blake2sp.c
@@ -1,299 +0,0 @@-/*- BLAKE2 reference source code package - reference C implementations- - Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the- terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at- your option. The terms of these licenses can be found at:- - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0- - OpenSSL license : https://www.openssl.org/source/license.html- - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- - More information about the BLAKE2 hash function can be found at- https://blake2.net.-*/--#include <stdlib.h>-#include <string.h>-#include <stdio.h>--#if defined(_OPENMP)-#include <omp.h>-#endif--#include "blake2.h"-#include "blake2-impl.h"--#define PARALLELISM_DEGREE 8--BLAKE2_LOCAL_INLINE(int) blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )-{- blake2s_param P[1];- P->digest_length = outlen;- P->key_length = keylen;- P->fanout = PARALLELISM_DEGREE;- P->depth = 2;- store32( &P->leaf_length, 0 );- store48( P->node_offset, offset );- P->node_depth = 0;- P->inner_length = BLAKE2S_OUTBYTES;- memset( P->salt, 0, sizeof( P->salt ) );- memset( P->personal, 0, sizeof( P->personal ) );- return blake2s_init_param( S, P );-}--BLAKE2_LOCAL_INLINE(int) blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen )-{- blake2s_param P[1];- P->digest_length = outlen;- P->key_length = keylen;- P->fanout = PARALLELISM_DEGREE;- P->depth = 2;- store32( &P->leaf_length, 0 );- store48( P->node_offset, 0ULL );- P->node_depth = 1;- P->inner_length = BLAKE2S_OUTBYTES;- memset( P->salt, 0, sizeof( P->salt ) );- memset( P->personal, 0, sizeof( P->personal ) );- return blake2s_init_param( S, P );-}---int blake2sp_init( blake2sp_state *S, const uint8_t outlen )-{- if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;-- memset( S->buf, 0, sizeof( S->buf ) );- S->buflen = 0;-- if( blake2sp_init_root( S->R, outlen, 0 ) < 0 )- return -1;-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- if( blake2sp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1;-- S->R->last_node = 1;- S->S[PARALLELISM_DEGREE - 1]->last_node = 1;- return 0;-}--int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )-{- if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;-- if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;-- memset( S->buf, 0, sizeof( S->buf ) );- S->buflen = 0;-- if( blake2sp_init_root( S->R, outlen, keylen ) < 0 )- return -1;-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- if( blake2sp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1;-- S->R->last_node = 1;- S->S[PARALLELISM_DEGREE - 1]->last_node = 1;- {- uint8_t block[BLAKE2S_BLOCKBYTES];- memset( block, 0, BLAKE2S_BLOCKBYTES );- memcpy( block, key, keylen );-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES );-- secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */- }- return 0;-}---int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen )-{- size_t left = S->buflen;- size_t fill = sizeof( S->buf ) - left;-- if( left && inlen >= fill )- {- memcpy( S->buf + left, in, fill );-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );-- in += fill;- inlen -= fill;- left = 0;- }--#if defined(_OPENMP)- #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE)-#else-- for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )-#endif- {-#if defined(_OPENMP)- size_t id__ = omp_get_thread_num();-#endif- uint64_t inlen__ = inlen;- const uint8_t *in__ = ( const uint8_t * )in;- in__ += id__ * BLAKE2S_BLOCKBYTES;-- while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )- {- blake2s_update( S->S[id__], in__, BLAKE2S_BLOCKBYTES );- in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;- inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;- }- }-- in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );- inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;-- if( inlen > 0 )- memcpy( S->buf + left, in, inlen );-- S->buflen = left + inlen;- return 0;-}---int blake2sp_final( blake2sp_state *S, uint8_t *out, const uint8_t outlen )-{- uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- {- if( S->buflen > i * BLAKE2S_BLOCKBYTES )- {- size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;-- if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;-- blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );- }-- blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES );- }-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );-- return blake2s_final( S->R, out, outlen );-}---int blake2sp( uint8_t *out, const void *in, const void *key, uint8_t outlen, uint64_t inlen, uint8_t keylen )-{- uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];- blake2s_state S[PARALLELISM_DEGREE][1];- blake2s_state FS[1];-- /* Verify parameters */- if ( NULL == in && inlen > 0 ) return -1;-- if ( NULL == out ) return -1;-- if ( NULL == key && keylen > 0) return -1;-- if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;-- if( keylen > BLAKE2S_KEYBYTES ) return -1;-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- if( blake2sp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1;-- S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */-- if( keylen > 0 )- {- uint8_t block[BLAKE2S_BLOCKBYTES];- memset( block, 0, BLAKE2S_BLOCKBYTES );- memcpy( block, key, keylen );-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );-- secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */- }--#if defined(_OPENMP)- #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)-#else-- for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )-#endif- {-#if defined(_OPENMP)- size_t id__ = omp_get_thread_num();-#endif- uint64_t inlen__ = inlen;- const uint8_t *in__ = ( const uint8_t * )in;- in__ += id__ * BLAKE2S_BLOCKBYTES;-- while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )- {- blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES );- in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;- inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;- }-- if( inlen__ > id__ * BLAKE2S_BLOCKBYTES )- {- const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES;- const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;- blake2s_update( S[id__], in__, len );- }-- blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES );- }-- if( blake2sp_init_root( FS, outlen, keylen ) < 0 )- return -1;-- FS->last_node = 1;-- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )- blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );-- return blake2s_final( FS, out, outlen );-}----#if defined(BLAKE2SP_SELFTEST)-#include <string.h>-#include "blake2-kat.h"-int main( int argc, char **argv )-{- uint8_t key[BLAKE2S_KEYBYTES];- uint8_t buf[KAT_LENGTH];-- for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i )- key[i] = ( uint8_t )i;-- for( size_t i = 0; i < KAT_LENGTH; ++i )- buf[i] = ( uint8_t )i;-- for( size_t i = 0; i < KAT_LENGTH; ++i )- {- uint8_t hash[BLAKE2S_OUTBYTES];- blake2sp( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES );-- if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) )- {- puts( "error" );- return -1;- }- }-- puts( "ok" );- return 0;-}-#endif------
cbits/sse/blake2b.c view
@@ -1,14 +1,14 @@ /* BLAKE2 reference source code package - optimized C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */@@ -49,199 +49,93 @@ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL }; -static const uint8_t blake2b_sigma[12][16] =-{- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,- { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,- { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,- { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,- { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,- { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,- { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,- { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,- { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }-};---/* Some helper functions, not necessarily useful */-BLAKE2_LOCAL_INLINE(int) blake2b_set_lastnode( blake2b_state *S )-{- S->f[1] = -1;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastnode( blake2b_state *S )+/* Some helper functions */+static void blake2b_set_lastnode( blake2b_state *S ) {- S->f[1] = 0;- return 0;+ S->f[1] = (uint64_t)-1; } -BLAKE2_LOCAL_INLINE(int) blake2b_is_lastblock( const blake2b_state *S )+static int blake2b_is_lastblock( const blake2b_state *S ) { return S->f[0] != 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_set_lastblock( blake2b_state *S )+static void blake2b_set_lastblock( blake2b_state *S ) { if( S->last_node ) blake2b_set_lastnode( S ); - S->f[0] = -1;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastblock( blake2b_state *S )-{- if( S->last_node ) blake2b_clear_lastnode( S );-- S->f[0] = 0;- return 0;+ S->f[0] = (uint64_t)-1; } --BLAKE2_LOCAL_INLINE(int) blake2b_increment_counter( blake2b_state *S, const uint64_t inc )+static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) {-#if __x86_64__- /* ADD/ADC chain */- __uint128_t t = ( ( __uint128_t )S->t[1] << 64 ) | S->t[0];- t += inc;- S->t[0] = ( uint64_t )( t >> 0 );- S->t[1] = ( uint64_t )( t >> 64 );-#else S->t[0] += inc; S->t[1] += ( S->t[0] < inc );-#endif- return 0; } --/* Parameter-related functions */-BLAKE2_LOCAL_INLINE(int) blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length )-{- P->digest_length = digest_length;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )-{- P->fanout = fanout;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )-{- P->depth = depth;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )-{- P->leaf_length = leaf_length;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )-{- P->node_offset = node_offset;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )-{- P->node_depth = node_depth;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )-{- P->inner_length = inner_length;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )-{- memcpy( P->salt, salt, BLAKE2B_SALTBYTES );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )-{- memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2b_init0( blake2b_state *S )-{- memset( S, 0, sizeof( blake2b_state ) );-- for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];-- return 0;-}- /* init xors IV with input parameter block */ int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) {+ size_t i; /*blake2b_init0( S ); */- const uint8_t * v = ( const uint8_t * )( blake2b_IV );- const uint8_t * p = ( const uint8_t * )( P );- uint8_t * h = ( uint8_t * )( S->h );+ const unsigned char * v = ( const unsigned char * )( blake2b_IV );+ const unsigned char * p = ( const unsigned char * )( P );+ unsigned char * h = ( unsigned char * )( S->h ); /* IV XOR ParamBlock */ memset( S, 0, sizeof( blake2b_state ) ); - for( int i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];+ for( i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; + S->outlen = P->digest_length; return 0; } /* Some sort of default parameter block initialization, for sequential blake2b */-int blake2b_init( blake2b_state *S, const uint8_t outlen )+int blake2b_init( blake2b_state *S, size_t outlen ) {- const blake2b_param P =- {- outlen,- 0,- 1,- 1,- 0,- 0,- 0,- 0,- {0},- {0},- {0}- };+ blake2b_param P[1]; if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - return blake2b_init_param( S, &P );+ P->digest_length = (uint8_t)outlen;+ P->key_length = 0;+ P->fanout = 1;+ P->depth = 1;+ store32( &P->leaf_length, 0 );+ store32( &P->node_offset, 0 );+ store32( &P->xof_length, 0 );+ 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 ) );++ return blake2b_init_param( S, P ); } -int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )+int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) {- const blake2b_param P =- {- outlen,- keylen,- 1,- 1,- 0,- 0,- 0,- 0,- {0},- {0},- {0}- };+ blake2b_param P[1]; if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1; - if( blake2b_init_param( S, &P ) < 0 )+ P->digest_length = (uint8_t)outlen;+ P->key_length = (uint8_t)keylen;+ P->fanout = 1;+ P->depth = 1;+ store32( &P->leaf_length, 0 );+ store32( &P->node_offset, 0 );+ store32( &P->xof_length, 0 );+ 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 0; {@@ -254,7 +148,7 @@ return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )+static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) { __m128i row1l, row1h; __m128i row2l, row2h;@@ -276,22 +170,22 @@ const __m128i m6 = LOADU( block + 96 ); const __m128i m7 = LOADU( block + 112 ); #else- const uint64_t m0 = ( ( uint64_t * )block )[ 0];- const uint64_t m1 = ( ( uint64_t * )block )[ 1];- const uint64_t m2 = ( ( uint64_t * )block )[ 2];- const uint64_t m3 = ( ( uint64_t * )block )[ 3];- const uint64_t m4 = ( ( uint64_t * )block )[ 4];- const uint64_t m5 = ( ( uint64_t * )block )[ 5];- const uint64_t m6 = ( ( uint64_t * )block )[ 6];- const uint64_t m7 = ( ( uint64_t * )block )[ 7];- const uint64_t m8 = ( ( uint64_t * )block )[ 8];- const uint64_t m9 = ( ( uint64_t * )block )[ 9];- const uint64_t m10 = ( ( uint64_t * )block )[10];- const uint64_t m11 = ( ( uint64_t * )block )[11];- const uint64_t m12 = ( ( uint64_t * )block )[12];- const uint64_t m13 = ( ( uint64_t * )block )[13];- const uint64_t m14 = ( ( uint64_t * )block )[14];- const uint64_t m15 = ( ( uint64_t * )block )[15];+ const uint64_t m0 = load64(block + 0 * sizeof(uint64_t));+ const uint64_t m1 = load64(block + 1 * sizeof(uint64_t));+ const uint64_t m2 = load64(block + 2 * sizeof(uint64_t));+ const uint64_t m3 = load64(block + 3 * sizeof(uint64_t));+ const uint64_t m4 = load64(block + 4 * sizeof(uint64_t));+ const uint64_t m5 = load64(block + 5 * sizeof(uint64_t));+ const uint64_t m6 = load64(block + 6 * sizeof(uint64_t));+ const uint64_t m7 = load64(block + 7 * sizeof(uint64_t));+ const uint64_t m8 = load64(block + 8 * sizeof(uint64_t));+ const uint64_t m9 = load64(block + 9 * sizeof(uint64_t));+ const uint64_t m10 = load64(block + 10 * sizeof(uint64_t));+ const uint64_t m11 = load64(block + 11 * sizeof(uint64_t));+ const uint64_t m12 = load64(block + 12 * sizeof(uint64_t));+ const uint64_t m13 = load64(block + 13 * sizeof(uint64_t));+ const uint64_t m14 = load64(block + 14 * sizeof(uint64_t));+ const uint64_t m15 = load64(block + 15 * sizeof(uint64_t)); #endif row1l = LOADU( &S->h[0] ); row1h = LOADU( &S->h[2] );@@ -321,67 +215,56 @@ row2h = _mm_xor_si128( row4h, row2h ); STOREU( &S->h[4], _mm_xor_si128( LOADU( &S->h[4] ), row2l ) ); STOREU( &S->h[6], _mm_xor_si128( LOADU( &S->h[6] ), row2h ) );- return 0; } -int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen )+int blake2b_update( blake2b_state *S, const void *pin, size_t inlen ) {- while( inlen > 0 )+ const unsigned char * in = (const unsigned char *)pin;+ if( inlen > 0 ) { size_t left = S->buflen;- size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;-+ size_t fill = BLAKE2B_BLOCKBYTES - left; if( inlen > fill ) {+ S->buflen = 0; memcpy( S->buf + left, in, fill ); /* Fill buffer */- S->buflen += fill; blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); blake2b_compress( S, S->buf ); /* Compress */- memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */- S->buflen -= BLAKE2B_BLOCKBYTES;- in += fill;- inlen -= fill;- }- else /* inlen <= fill */- {- memcpy( S->buf + left, in, inlen );- S->buflen += inlen; /* Be lazy, do not compress */- in += inlen;- inlen -= inlen;+ in += fill; inlen -= fill;+ while(inlen > BLAKE2B_BLOCKBYTES) {+ blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);+ blake2b_compress( S, in );+ in += BLAKE2B_BLOCKBYTES;+ inlen -= BLAKE2B_BLOCKBYTES;+ } }+ memcpy( S->buf + S->buflen, in, inlen );+ S->buflen += inlen; }- return 0; } -int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen )+int blake2b_final( blake2b_state *S, void *out, size_t outlen ) {- if( outlen > BLAKE2B_OUTBYTES )+ if( out == NULL || outlen < S->outlen ) return -1; if( blake2b_is_lastblock( S ) ) return -1; - if( S->buflen > BLAKE2B_BLOCKBYTES )- {- blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );- blake2b_compress( S, S->buf );- S->buflen -= BLAKE2B_BLOCKBYTES;- memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );- }- blake2b_increment_counter( S, S->buflen ); blake2b_set_lastblock( S );- memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */+ memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ blake2b_compress( S, S->buf );- memcpy( out, &S->h[0], outlen );++ memcpy( out, &S->h[0], S->outlen ); return 0; } -int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )+int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { blake2b_state S[1]; @@ -410,41 +293,81 @@ return 0; } +int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) {+ return blake2b(out, outlen, in, inlen, key, keylen);+}+ #if defined(SUPERCOP) int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) {- return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 );+ return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 ); } #endif #if defined(BLAKE2B_SELFTEST) #include <string.h> #include "blake2-kat.h"-int main( int argc, char **argv )+int main( void ) { uint8_t key[BLAKE2B_KEYBYTES];- uint8_t buf[KAT_LENGTH];+ uint8_t buf[BLAKE2_KAT_LENGTH];+ size_t i, step; - for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i )+ for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) key[i] = ( uint8_t )i; - for( size_t i = 0; i < KAT_LENGTH; ++i )+ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; - for( size_t i = 0; i < KAT_LENGTH; ++i )+ /* Test simple API */+ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2B_OUTBYTES];- blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );+ blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES ); if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) {- puts( "error" );- return -1;+ goto fail; } } + /* Test streaming API */+ for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) {+ for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {+ uint8_t hash[BLAKE2B_OUTBYTES];+ blake2b_state S;+ uint8_t * p = buf;+ size_t mlen = i;+ int err = 0;++ if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) {+ goto fail;+ }++ while (mlen >= step) {+ if ( (err = blake2b_update(&S, p, step)) < 0 ) {+ goto fail;+ }+ mlen -= step;+ p += step;+ }+ if ( (err = blake2b_update(&S, p, mlen)) < 0) {+ goto fail;+ }+ if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) {+ goto fail;+ }++ if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) {+ goto fail;+ }+ }+ }+ puts( "ok" ); return 0;+fail:+ puts("error");+ return -1; } #endif-
cbits/sse/blake2bp.c view
@@ -1,14 +1,14 @@ /* BLAKE2 reference source code package - optimized C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */@@ -27,32 +27,48 @@ #define PARALLELISM_DEGREE 4 -BLAKE2_LOCAL_INLINE(int) blake2bp_init_leaf( blake2b_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )+/*+ blake2b_init_param defaults to setting the expecting output length+ from the digest_length parameter block field.++ In some cases, however, we do not want this, as the output length+ of these instances is given by inner_length instead.+*/+static int blake2bp_init_leaf_param( blake2b_state *S, const blake2b_param *P ) {+ int err = blake2b_init_param(S, P);+ S->outlen = P->inner_length;+ return err;+}++static int blake2bp_init_leaf( blake2b_state *S, size_t outlen, size_t keylen, uint64_t offset )+{ blake2b_param P[1];- P->digest_length = outlen;- P->key_length = keylen;+ P->digest_length = (uint8_t)outlen;+ P->key_length = (uint8_t)keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; P->leaf_length = 0; P->node_offset = offset;+ P->xof_length = 0; P->node_depth = 0; P->inner_length = BLAKE2B_OUTBYTES; memset( P->reserved, 0, sizeof( P->reserved ) ); memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) );- return blake2b_init_param( S, P );+ return blake2bp_init_leaf_param( S, P ); } -BLAKE2_LOCAL_INLINE(int) blake2bp_init_root( blake2b_state *S, uint8_t outlen, uint8_t keylen )+static int blake2bp_init_root( blake2b_state *S, size_t outlen, size_t keylen ) { blake2b_param P[1];- P->digest_length = outlen;- P->key_length = keylen;+ P->digest_length = (uint8_t)outlen;+ P->key_length = (uint8_t)keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; P->leaf_length = 0; P->node_offset = 0;+ P->xof_length = 0; P->node_depth = 1; P->inner_length = BLAKE2B_OUTBYTES; memset( P->reserved, 0, sizeof( P->reserved ) );@@ -62,17 +78,19 @@ } -int blake2bp_init( blake2bp_state *S, const uint8_t outlen )+int blake2bp_init( blake2bp_state *S, size_t outlen ) {+ size_t i; if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0;+ S->outlen = outlen; if( blake2bp_init_root( S->R, outlen, 0 ) < 0 ) return -1; - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1; S->R->last_node = 1;@@ -80,19 +98,22 @@ return 0; } -int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )+int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ) {+ size_t i;+ if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0;+ S->outlen = outlen; if( blake2bp_init_root( S->R, outlen, keylen ) < 0 ) return -1; - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1; S->R->last_node = 1;@@ -102,7 +123,7 @@ memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key, keylen ); - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */@@ -111,16 +132,18 @@ } -int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen )+int blake2bp_update( blake2bp_state *S, const void *pin, size_t inlen ) {+ const unsigned char * in = (const unsigned char *)pin; size_t left = S->buflen; size_t fill = sizeof( S->buf ) - left;+ size_t i; if( left && inlen >= fill ) { memcpy( S->buf + left, in, fill ); - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); in += fill;@@ -132,19 +155,19 @@ #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE) #else - for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) #endif { #if defined(_OPENMP)- size_t id__ = omp_get_thread_num();+ size_t i = omp_get_thread_num(); #endif- uint64_t inlen__ = inlen;- const uint8_t *in__ = ( const uint8_t * )in;- in__ += id__ * BLAKE2B_BLOCKBYTES;+ size_t inlen__ = inlen;+ const unsigned char *in__ = ( const unsigned char * )in;+ in__ += i * BLAKE2B_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) {- blake2b_update( S->S[id__], in__, BLAKE2B_BLOCKBYTES );+ blake2b_update( S->S[i], in__, BLAKE2B_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; }@@ -162,11 +185,16 @@ -int blake2bp_final( blake2bp_state *S, uint8_t *out, const uint8_t outlen )+int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];+ size_t i; - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ if(out == NULL || outlen < S->outlen) {+ return -1;+ }++ for( i = 0; i < PARALLELISM_DEGREE; ++i ) { if( S->buflen > i * BLAKE2B_BLOCKBYTES ) {@@ -180,17 +208,18 @@ blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES ); } - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES ); - return blake2b_final( S->R, out, outlen );+ return blake2b_final( S->R, out, S->outlen ); } -int blake2bp( uint8_t *out, const void *in, const void *key, uint8_t outlen, uint64_t inlen, uint8_t keylen )+int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; blake2b_state S[PARALLELISM_DEGREE][1]; blake2b_state FS[1];+ size_t i; /* Verify parameters */ if ( NULL == in && inlen > 0 ) return -1;@@ -203,7 +232,7 @@ if( keylen > BLAKE2B_KEYBYTES ) return -1; - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1; S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */@@ -214,7 +243,7 @@ memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key, keylen ); - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */@@ -224,31 +253,31 @@ #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) #else - for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) #endif { #if defined(_OPENMP)- size_t id__ = omp_get_thread_num();+ size_t i = omp_get_thread_num(); #endif- uint64_t inlen__ = inlen;- const uint8_t *in__ = ( const uint8_t * )in;- in__ += id__ * BLAKE2B_BLOCKBYTES;+ size_t inlen__ = inlen;+ const unsigned char *in__ = ( const unsigned char * )in;+ in__ += i * BLAKE2B_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) {- blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES );+ blake2b_update( S[i], in__, BLAKE2B_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; } - if( inlen__ > id__ * BLAKE2B_BLOCKBYTES )+ if( inlen__ > i * BLAKE2B_BLOCKBYTES ) {- const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES;+ const size_t left = inlen__ - i * BLAKE2B_BLOCKBYTES; const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES;- blake2b_update( S[id__], in__, len );+ blake2b_update( S[i], in__, len ); } - blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES );+ blake2b_final( S[i], hash[i], BLAKE2B_OUTBYTES ); } if( blake2bp_init_root( FS, outlen, keylen ) < 0 )@@ -256,7 +285,7 @@ FS->last_node = 1; /* Mark as last node */ - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); return blake2b_final( FS, out, outlen );@@ -266,35 +295,67 @@ #if defined(BLAKE2BP_SELFTEST) #include <string.h> #include "blake2-kat.h"-int main( int argc, char **argv )+int main( void ) { uint8_t key[BLAKE2B_KEYBYTES];- uint8_t buf[KAT_LENGTH];+ uint8_t buf[BLAKE2_KAT_LENGTH];+ size_t i, step; - for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i )+ for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) key[i] = ( uint8_t )i; - for( size_t i = 0; i < KAT_LENGTH; ++i )+ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; - for( size_t i = 0; i < KAT_LENGTH; ++i )+ /* Test simple API */+ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2B_OUTBYTES];- /*blake2bp( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ); */- blake2bp_state S[1];- blake2bp_init_key( S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES );- blake2bp_update( S, buf, i );- blake2bp_final( S, hash, BLAKE2B_OUTBYTES );+ blake2bp( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES ); if( 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) ) {- puts( "error" );- return -1;+ goto fail; } } + /* Test streaming API */+ for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) {+ for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {+ uint8_t hash[BLAKE2B_OUTBYTES];+ blake2bp_state S;+ uint8_t * p = buf;+ size_t mlen = i;+ int err = 0;++ if( (err = blake2bp_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) {+ goto fail;+ }++ while (mlen >= step) {+ if ( (err = blake2bp_update(&S, p, step)) < 0 ) {+ goto fail;+ }+ mlen -= step;+ p += step;+ }+ if ( (err = blake2bp_update(&S, p, mlen)) < 0) {+ goto fail;+ }+ if ( (err = blake2bp_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) {+ goto fail;+ }++ if (0 != memcmp(hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES)) {+ goto fail;+ }+ }+ }+ puts( "ok" ); return 0;+fail:+ puts("error");+ return -1; } #endif-
cbits/sse/blake2s.c view
@@ -1,14 +1,14 @@ /* BLAKE2 reference source code package - optimized C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */@@ -45,132 +45,36 @@ 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL }; -static const uint8_t blake2s_sigma[10][16] =-{- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,- { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,- { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,- { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,- { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,- { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,- { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,- { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,- { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,-};---/* Some helper functions, not necessarily useful */-BLAKE2_LOCAL_INLINE(int) blake2s_set_lastnode( blake2s_state *S )-{- S->f[1] = -1;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastnode( blake2s_state *S )+/* Some helper functions */+static void blake2s_set_lastnode( blake2s_state *S ) {- S->f[1] = 0;- return 0;+ S->f[1] = (uint32_t)-1; } -BLAKE2_LOCAL_INLINE(int) blake2s_is_lastblock( const blake2s_state *S )+static int blake2s_is_lastblock( const blake2s_state *S ) { return S->f[0] != 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_set_lastblock( blake2s_state *S )+static void blake2s_set_lastblock( blake2s_state *S ) { if( S->last_node ) blake2s_set_lastnode( S ); - S->f[0] = -1;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastblock( blake2s_state *S )-{- if( S->last_node ) blake2s_clear_lastnode( S );-- S->f[0] = 0;- return 0;+ S->f[0] = (uint32_t)-1; } -BLAKE2_LOCAL_INLINE(int) blake2s_increment_counter( blake2s_state *S, const uint32_t inc )+static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) { uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0]; t += inc; S->t[0] = ( uint32_t )( t >> 0 ); S->t[1] = ( uint32_t )( t >> 32 );- return 0; } --/* Parameter-related functions */-BLAKE2_LOCAL_INLINE(int) blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )-{- P->digest_length = digest_length;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )-{- P->fanout = fanout;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )-{- P->depth = depth;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )-{- P->leaf_length = leaf_length;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )-{- store48( P->node_offset, node_offset );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )-{- P->node_depth = node_depth;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )-{- P->inner_length = inner_length;- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )-{- memcpy( P->salt, salt, BLAKE2S_SALTBYTES );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )-{- memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );- return 0;-}--BLAKE2_LOCAL_INLINE(int) blake2s_init0( blake2s_state *S )-{- memset( S, 0, sizeof( blake2s_state ) );-- for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];-- return 0;-}- /* init2 xors IV with input parameter block */ int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) {+ size_t i; /*blake2s_init0( S ); */ const uint8_t * v = ( const uint8_t * )( blake2s_IV ); const uint8_t * p = ( const uint8_t * )( P );@@ -178,56 +82,61 @@ /* IV XOR ParamBlock */ memset( S, 0, sizeof( blake2s_state ) ); - for( int i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];+ for( i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; + S->outlen = P->digest_length; return 0; } /* Some sort of default parameter block initialization, for sequential blake2s */-int blake2s_init( blake2s_state *S, const uint8_t outlen )+int blake2s_init( blake2s_state *S, size_t outlen ) {- const blake2s_param P =- {- outlen,- 0,- 1,- 1,- 0,- {0},- 0,- 0,- {0},- {0}- };+ blake2s_param P[1];+ /* Move interval verification here? */ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;- return blake2s_init_param( S, &P );++ P->digest_length = (uint8_t)outlen;+ P->key_length = 0;+ P->fanout = 1;+ P->depth = 1;+ store32( &P->leaf_length, 0 );+ store32( &P->node_offset, 0 );+ store16( &P->xof_length, 0 );+ 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 ) );++ return blake2s_init_param( S, P ); } -int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )+int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) {- const blake2s_param P =- {- outlen,- keylen,- 1,- 1,- 0,- {0},- 0,- 0,- {0},- {0}- };+ blake2s_param P[1]; /* Move interval verification here? */ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1; - if( blake2s_init_param( S, &P ) < 0 )+ P->digest_length = (uint8_t)outlen;+ P->key_length = (uint8_t)keylen;+ P->fanout = 1;+ P->depth = 1;+ store32( &P->leaf_length, 0 );+ store32( &P->node_offset, 0 );+ store16( &P->xof_length, 0 );+ 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( blake2s_init_param( S, P ) < 0 ) return -1; {@@ -241,7 +150,7 @@ } -BLAKE2_LOCAL_INLINE(int) blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )+static void blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) { __m128i row1, row2, row3, row4; __m128i buf1, buf2, buf3, buf4;@@ -262,27 +171,27 @@ const __m128i m2 = LOADU( block + 32 ); const __m128i m3 = LOADU( block + 48 ); #else- const uint32_t m0 = ( ( uint32_t * )block )[ 0];- const uint32_t m1 = ( ( uint32_t * )block )[ 1];- const uint32_t m2 = ( ( uint32_t * )block )[ 2];- const uint32_t m3 = ( ( uint32_t * )block )[ 3];- const uint32_t m4 = ( ( uint32_t * )block )[ 4];- const uint32_t m5 = ( ( uint32_t * )block )[ 5];- const uint32_t m6 = ( ( uint32_t * )block )[ 6];- const uint32_t m7 = ( ( uint32_t * )block )[ 7];- const uint32_t m8 = ( ( uint32_t * )block )[ 8];- const uint32_t m9 = ( ( uint32_t * )block )[ 9];- const uint32_t m10 = ( ( uint32_t * )block )[10];- const uint32_t m11 = ( ( uint32_t * )block )[11];- const uint32_t m12 = ( ( uint32_t * )block )[12];- const uint32_t m13 = ( ( uint32_t * )block )[13];- const uint32_t m14 = ( ( uint32_t * )block )[14];- const uint32_t m15 = ( ( uint32_t * )block )[15];+ const uint32_t m0 = load32(block + 0 * sizeof(uint32_t));+ const uint32_t m1 = load32(block + 1 * sizeof(uint32_t));+ const uint32_t m2 = load32(block + 2 * sizeof(uint32_t));+ const uint32_t m3 = load32(block + 3 * sizeof(uint32_t));+ const uint32_t m4 = load32(block + 4 * sizeof(uint32_t));+ const uint32_t m5 = load32(block + 5 * sizeof(uint32_t));+ const uint32_t m6 = load32(block + 6 * sizeof(uint32_t));+ const uint32_t m7 = load32(block + 7 * sizeof(uint32_t));+ const uint32_t m8 = load32(block + 8 * sizeof(uint32_t));+ const uint32_t m9 = load32(block + 9 * sizeof(uint32_t));+ const uint32_t m10 = load32(block + 10 * sizeof(uint32_t));+ const uint32_t m11 = load32(block + 11 * sizeof(uint32_t));+ const uint32_t m12 = load32(block + 12 * sizeof(uint32_t));+ const uint32_t m13 = load32(block + 13 * sizeof(uint32_t));+ const uint32_t m14 = load32(block + 14 * sizeof(uint32_t));+ const uint32_t m15 = load32(block + 15 * sizeof(uint32_t)); #endif row1 = ff0 = LOADU( &S->h[0] ); row2 = ff1 = LOADU( &S->h[4] );- row3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A );- row4 = _mm_xor_si128( _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ), LOADU( &S->t[0] ) );+ row3 = _mm_loadu_si128( (__m128i const *)&blake2s_IV[0] );+ row4 = _mm_xor_si128( _mm_loadu_si128( (__m128i const *)&blake2s_IV[4] ), LOADU( &S->t[0] ) ); ROUND( 0 ); ROUND( 1 ); ROUND( 2 );@@ -295,73 +204,61 @@ ROUND( 9 ); STOREU( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row1, row3 ) ) ); STOREU( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row2, row4 ) ) );- return 0; } -/* inlen now in bytes */-int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen )+int blake2s_update( blake2s_state *S, const void *pin, size_t inlen ) {- while( inlen > 0 )+ const unsigned char * in = (const unsigned char *)pin;+ if( inlen > 0 ) { size_t left = S->buflen;- size_t fill = 2 * BLAKE2S_BLOCKBYTES - left;-+ size_t fill = BLAKE2S_BLOCKBYTES - left; if( inlen > fill ) {+ S->buflen = 0; memcpy( S->buf + left, in, fill ); /* Fill buffer */- S->buflen += fill; blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); blake2s_compress( S, S->buf ); /* Compress */- memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); /* Shift buffer left */- S->buflen -= BLAKE2S_BLOCKBYTES;- in += fill;- inlen -= fill;- }- else /* inlen <= fill */- {- memcpy( S->buf + left, in, inlen );- S->buflen += inlen; /* Be lazy, do not compress */- in += inlen;- inlen -= inlen;+ in += fill; inlen -= fill;+ while(inlen > BLAKE2S_BLOCKBYTES) {+ blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);+ blake2s_compress( S, in );+ in += BLAKE2S_BLOCKBYTES;+ inlen -= BLAKE2S_BLOCKBYTES;+ } }+ memcpy( S->buf + S->buflen, in, inlen );+ S->buflen += inlen; }- return 0; } -/* Is this correct? */-int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen )+int blake2s_final( blake2s_state *S, void *out, size_t outlen ) { uint8_t buffer[BLAKE2S_OUTBYTES] = {0};+ size_t i; - if( outlen > BLAKE2S_OUTBYTES )+ if( out == NULL || outlen < S->outlen ) return -1; if( blake2s_is_lastblock( S ) ) return -1; - if( S->buflen > BLAKE2S_BLOCKBYTES )- {- blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );- blake2s_compress( S, S->buf );- S->buflen -= BLAKE2S_BLOCKBYTES;- memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );- }-- blake2s_increment_counter( S, ( uint32_t )S->buflen );+ blake2s_increment_counter( S, (uint32_t)S->buflen ); blake2s_set_lastblock( S );- memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */+ memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ blake2s_compress( S, S->buf ); - for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */+ for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); - memcpy( out, buffer, outlen );+ memcpy( out, buffer, S->outlen );+ secure_zero_memory( buffer, sizeof(buffer) ); return 0; } /* inlen, at least, should be uint64_t. Others can be size_t. */-int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )+int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { blake2s_state S[1]; @@ -393,39 +290,74 @@ #if defined(SUPERCOP) int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) {- return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, inlen, 0 );+ return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 ); } #endif #if defined(BLAKE2S_SELFTEST) #include <string.h> #include "blake2-kat.h"-int main( int argc, char **argv )+int main( void ) { uint8_t key[BLAKE2S_KEYBYTES];- uint8_t buf[KAT_LENGTH];+ uint8_t buf[BLAKE2_KAT_LENGTH];+ size_t i, step; - for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i )+ for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) key[i] = ( uint8_t )i; - for( size_t i = 0; i < KAT_LENGTH; ++i )+ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; - for( size_t i = 0; i < KAT_LENGTH; ++i )+ /* Test simple API */+ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2S_OUTBYTES];+ blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); - if( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 ||- 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )+ if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) {- puts( "error" );- return -1;+ goto fail; } } + /* Test streaming API */+ for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {+ for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {+ uint8_t hash[BLAKE2S_OUTBYTES];+ blake2s_state S;+ uint8_t * p = buf;+ size_t mlen = i;+ int err = 0;++ if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {+ goto fail;+ }++ while (mlen >= step) {+ if ( (err = blake2s_update(&S, p, step)) < 0 ) {+ goto fail;+ }+ mlen -= step;+ p += step;+ }+ if ( (err = blake2s_update(&S, p, mlen)) < 0) {+ goto fail;+ }+ if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {+ goto fail;+ }++ if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) {+ goto fail;+ }+ }+ }+ puts( "ok" ); return 0;+fail:+ puts("error");+ return -1; } #endif--
cbits/sse/blake2sp.c view
@@ -1,14 +1,14 @@ /* BLAKE2 reference source code package - optimized C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */@@ -26,31 +26,47 @@ #define PARALLELISM_DEGREE 8 -BLAKE2_LOCAL_INLINE(int) blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )+/*+ blake2sp_init_param defaults to setting the expecting output length+ from the digest_length parameter block field.++ In some cases, however, we do not want this, as the output length+ of these instances is given by inner_length instead.+*/+static int blake2sp_init_leaf_param( blake2s_state *S, const blake2s_param *P ) {+ int err = blake2s_init_param(S, P);+ S->outlen = P->inner_length;+ return err;+}++static int blake2sp_init_leaf( blake2s_state *S, size_t outlen, size_t keylen, uint64_t offset )+{ blake2s_param P[1];- P->digest_length = outlen;- P->key_length = keylen;+ P->digest_length = (uint8_t)outlen;+ P->key_length = (uint8_t)keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; P->leaf_length = 0;- store48( P->node_offset, offset );+ P->node_offset = offset;+ P->xof_length = 0; P->node_depth = 0; P->inner_length = BLAKE2S_OUTBYTES; memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) );- return blake2s_init_param( S, P );+ return blake2sp_init_leaf_param( S, P ); } -BLAKE2_LOCAL_INLINE(int) blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen )+static int blake2sp_init_root( blake2s_state *S, size_t outlen, size_t keylen ) { blake2s_param P[1];- P->digest_length = outlen;- P->key_length = keylen;+ P->digest_length = (uint8_t)outlen;+ P->key_length = (uint8_t)keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; P->leaf_length = 0;- store48( P->node_offset, 0ULL );+ P->node_offset = 0;+ P->xof_length = 0; P->node_depth = 1; P->inner_length = BLAKE2S_OUTBYTES; memset( P->salt, 0, sizeof( P->salt ) );@@ -59,17 +75,20 @@ } -int blake2sp_init( blake2sp_state *S, const uint8_t outlen )+int blake2sp_init( blake2sp_state *S, size_t outlen ) {+ size_t i;+ if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0;+ S->outlen = outlen; if( blake2sp_init_root( S->R, outlen, 0 ) < 0 ) return -1; - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2sp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1; S->R->last_node = 1;@@ -77,19 +96,22 @@ return 0; } -int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )+int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ) {+ size_t i;+ if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0;+ S->outlen = outlen; if( blake2sp_init_root( S->R, outlen, keylen ) < 0 ) return -1; - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2sp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1; S->R->last_node = 1;@@ -99,7 +121,7 @@ memset( block, 0, BLAKE2S_BLOCKBYTES ); memcpy( block, key, keylen ); - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES ); secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */@@ -108,16 +130,18 @@ } -int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen )+int blake2sp_update( blake2sp_state *S, const void *pin, size_t inlen ) {+ const unsigned char * in = (const unsigned char *)pin; size_t left = S->buflen; size_t fill = sizeof( S->buf ) - left;+ size_t i; if( left && inlen >= fill ) { memcpy( S->buf + left, in, fill ); - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); in += fill;@@ -129,19 +153,19 @@ #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE) #else - for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) #endif { #if defined(_OPENMP)- size_t id__ = omp_get_thread_num();+ size_t i = omp_get_thread_num(); #endif- uint64_t inlen__ = inlen;- const uint8_t *in__ = ( const uint8_t * )in;- in__ += id__ * BLAKE2S_BLOCKBYTES;+ size_t inlen__ = inlen;+ const unsigned char *in__ = ( const unsigned char * )in;+ in__ += i * BLAKE2S_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) {- blake2s_update( S->S[id__], in__, BLAKE2S_BLOCKBYTES );+ blake2s_update( S->S[i], in__, BLAKE2S_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; }@@ -158,11 +182,16 @@ } -int blake2sp_final( blake2sp_state *S, uint8_t *out, const uint8_t outlen )+int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];+ size_t i; - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ if(out == NULL || outlen < S->outlen) {+ return -1;+ }++ for( i = 0; i < PARALLELISM_DEGREE; ++i ) { if( S->buflen > i * BLAKE2S_BLOCKBYTES ) {@@ -176,18 +205,19 @@ blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES ); } - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES ); - return blake2s_final( S->R, out, outlen );+ return blake2s_final( S->R, out, S->outlen ); } -int blake2sp( uint8_t *out, const void *in, const void *key, uint8_t outlen, uint64_t inlen, uint8_t keylen )+int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; blake2s_state S[PARALLELISM_DEGREE][1]; blake2s_state FS[1];+ size_t i; /* Verify parameters */ if ( NULL == in && inlen > 0 ) return -1;@@ -200,7 +230,7 @@ if( keylen > BLAKE2S_KEYBYTES ) return -1; - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2sp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1; S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */@@ -211,7 +241,7 @@ memset( block, 0, BLAKE2S_BLOCKBYTES ); memcpy( block, key, keylen ); - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES ); secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */@@ -221,31 +251,31 @@ #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) #else - for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) #endif { #if defined(_OPENMP)- size_t id__ = omp_get_thread_num();+ size_t i = omp_get_thread_num(); #endif- uint64_t inlen__ = inlen;- const uint8_t *in__ = ( const uint8_t * )in;- in__ += id__ * BLAKE2S_BLOCKBYTES;+ size_t inlen__ = inlen;+ const unsigned char *in__ = ( const unsigned char * )in;+ in__ += i * BLAKE2S_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) {- blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES );+ blake2s_update( S[i], in__, BLAKE2S_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; } - if( inlen__ > id__ * BLAKE2S_BLOCKBYTES )+ if( inlen__ > i * BLAKE2S_BLOCKBYTES ) {- const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES;+ const size_t left = inlen__ - i * BLAKE2S_BLOCKBYTES; const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;- blake2s_update( S[id__], in__, len );+ blake2s_update( S[i], in__, len ); } - blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES );+ blake2s_final( S[i], hash[i], BLAKE2S_OUTBYTES ); } if( blake2sp_init_root( FS, outlen, keylen ) < 0 )@@ -253,7 +283,7 @@ FS->last_node = 1; - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )+ for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES ); return blake2s_final( FS, out, outlen );@@ -262,34 +292,67 @@ #if defined(BLAKE2SP_SELFTEST) #include <string.h> #include "blake2-kat.h"-int main( int argc, char **argv )+int main( void ) { uint8_t key[BLAKE2S_KEYBYTES];- uint8_t buf[KAT_LENGTH];+ uint8_t buf[BLAKE2_KAT_LENGTH];+ size_t i, step; - for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i )+ for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) key[i] = ( uint8_t )i; - for( size_t i = 0; i < KAT_LENGTH; ++i )+ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; - for( size_t i = 0; i < KAT_LENGTH; ++i )+ /* Test simple API */+ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2S_OUTBYTES];- blake2sp( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES );+ blake2sp( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) ) {- puts( "error" );- return -1;+ goto fail; } } - puts( "ok" );- return 0;-}-#endif+ /* Test streaming API */+ for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {+ for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {+ uint8_t hash[BLAKE2S_OUTBYTES];+ blake2sp_state S;+ uint8_t * p = buf;+ size_t mlen = i;+ int err = 0; + if( (err = blake2sp_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {+ goto fail;+ } + while (mlen >= step) {+ if ( (err = blake2sp_update(&S, p, step)) < 0 ) {+ goto fail;+ }+ mlen -= step;+ p += step;+ }+ if ( (err = blake2sp_update(&S, p, mlen)) < 0) {+ goto fail;+ }+ if ( (err = blake2sp_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {+ goto fail;+ } + if (0 != memcmp(hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES)) {+ goto fail;+ }+ }+ } + puts( "ok" );+ return 0;+fail:+ puts("error");+ return -1;+}+#endif
changelog.md view
@@ -1,3 +1,8 @@+# 0.3.0++* Bring C code up to date+* Use newer GHCs for testing+ # 0.2.0 * Added i686 support
include/ref/blake2-impl.h view
@@ -1,25 +1,36 @@ /* BLAKE2 reference source code package - reference C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */-#pragma once-#ifndef __BLAKE2_IMPL_H__-#define __BLAKE2_IMPL_H__+#ifndef BLAKE2_IMPL_H+#define BLAKE2_IMPL_H #include <stdint.h> #include <string.h> -BLAKE2_LOCAL_INLINE(uint32_t) load32( const void *src )+#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)+ #if defined(_MSC_VER)+ #define BLAKE2_INLINE __inline+ #elif defined(__GNUC__)+ #define BLAKE2_INLINE __inline__+ #else+ #define BLAKE2_INLINE+ #endif+#else+ #define BLAKE2_INLINE inline+#endif++static BLAKE2_INLINE uint32_t load32( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint32_t w;@@ -27,15 +38,14 @@ return w; #else const uint8_t *p = ( const uint8_t * )src;- uint32_t w = *p++;- w |= ( uint32_t )( *p++ ) << 8;- w |= ( uint32_t )( *p++ ) << 16;- w |= ( uint32_t )( *p++ ) << 24;- return w;+ return (( uint32_t )( p[0] ) << 0) |+ (( uint32_t )( p[1] ) << 8) |+ (( uint32_t )( p[2] ) << 16) |+ (( uint32_t )( p[3] ) << 24) ; #endif } -BLAKE2_LOCAL_INLINE(uint64_t) load64( const void *src )+static BLAKE2_INLINE uint64_t load64( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint64_t w;@@ -43,97 +53,108 @@ return w; #else const uint8_t *p = ( const uint8_t * )src;- uint64_t w = *p++;- w |= ( uint64_t )( *p++ ) << 8;- w |= ( uint64_t )( *p++ ) << 16;- w |= ( uint64_t )( *p++ ) << 24;- w |= ( uint64_t )( *p++ ) << 32;- w |= ( uint64_t )( *p++ ) << 40;- w |= ( uint64_t )( *p++ ) << 48;- w |= ( uint64_t )( *p++ ) << 56;- return w;+ return (( uint64_t )( p[0] ) << 0) |+ (( uint64_t )( p[1] ) << 8) |+ (( uint64_t )( p[2] ) << 16) |+ (( uint64_t )( p[3] ) << 24) |+ (( uint64_t )( p[4] ) << 32) |+ (( uint64_t )( p[5] ) << 40) |+ (( uint64_t )( p[6] ) << 48) |+ (( uint64_t )( p[7] ) << 56) ; #endif } -BLAKE2_LOCAL_INLINE(void) store32( void *dst, uint32_t w )+static BLAKE2_INLINE uint16_t load16( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN)- memcpy(dst, &w, sizeof w);+ uint16_t w;+ memcpy(&w, src, sizeof w);+ return w; #else- uint8_t *p = ( uint8_t * )dst;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w;+ const uint8_t *p = ( const uint8_t * )src;+ return ( uint16_t )((( uint32_t )( p[0] ) << 0) |+ (( uint32_t )( p[1] ) << 8)); #endif } -BLAKE2_LOCAL_INLINE(void) store64( void *dst, uint64_t w )+static BLAKE2_INLINE void store16( void *dst, uint16_t w ) { #if defined(NATIVE_LITTLE_ENDIAN) memcpy(dst, &w, sizeof w); #else uint8_t *p = ( uint8_t * )dst; *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8; *p++ = ( uint8_t )w; #endif } -BLAKE2_LOCAL_INLINE(uint64_t) load48( const void *src )+static BLAKE2_INLINE void store32( void *dst, uint32_t w ) {- const uint8_t *p = ( const uint8_t * )src;- uint64_t w = *p++;- w |= ( uint64_t )( *p++ ) << 8;- w |= ( uint64_t )( *p++ ) << 16;- w |= ( uint64_t )( *p++ ) << 24;- w |= ( uint64_t )( *p++ ) << 32;- w |= ( uint64_t )( *p++ ) << 40;- return w;+#if defined(NATIVE_LITTLE_ENDIAN)+ memcpy(dst, &w, sizeof w);+#else+ uint8_t *p = ( uint8_t * )dst;+ p[0] = (uint8_t)(w >> 0);+ p[1] = (uint8_t)(w >> 8);+ p[2] = (uint8_t)(w >> 16);+ p[3] = (uint8_t)(w >> 24);+#endif } -BLAKE2_LOCAL_INLINE(void) store48( void *dst, uint64_t w )+static BLAKE2_INLINE void store64( void *dst, uint64_t w ) {+#if defined(NATIVE_LITTLE_ENDIAN)+ memcpy(dst, &w, sizeof w);+#else uint8_t *p = ( uint8_t * )dst;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w;+ p[0] = (uint8_t)(w >> 0);+ p[1] = (uint8_t)(w >> 8);+ p[2] = (uint8_t)(w >> 16);+ p[3] = (uint8_t)(w >> 24);+ p[4] = (uint8_t)(w >> 32);+ p[5] = (uint8_t)(w >> 40);+ p[6] = (uint8_t)(w >> 48);+ p[7] = (uint8_t)(w >> 56);+#endif } -BLAKE2_LOCAL_INLINE(uint32_t) rotl32( const uint32_t w, const unsigned c )+static BLAKE2_INLINE uint64_t load48( const void *src ) {- return ( w << c ) | ( w >> ( 32 - c ) );+ const uint8_t *p = ( const uint8_t * )src;+ return (( uint64_t )( p[0] ) << 0) |+ (( uint64_t )( p[1] ) << 8) |+ (( uint64_t )( p[2] ) << 16) |+ (( uint64_t )( p[3] ) << 24) |+ (( uint64_t )( p[4] ) << 32) |+ (( uint64_t )( p[5] ) << 40) ; } -BLAKE2_LOCAL_INLINE(uint64_t) rotl64( const uint64_t w, const unsigned c )+static BLAKE2_INLINE void store48( void *dst, uint64_t w ) {- return ( w << c ) | ( w >> ( 64 - c ) );+ uint8_t *p = ( uint8_t * )dst;+ p[0] = (uint8_t)(w >> 0);+ p[1] = (uint8_t)(w >> 8);+ p[2] = (uint8_t)(w >> 16);+ p[3] = (uint8_t)(w >> 24);+ p[4] = (uint8_t)(w >> 32);+ p[5] = (uint8_t)(w >> 40); } -BLAKE2_LOCAL_INLINE(uint32_t) rotr32( const uint32_t w, const unsigned c )+static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c ) { return ( w >> c ) | ( w << ( 32 - c ) ); } -BLAKE2_LOCAL_INLINE(uint64_t) rotr64( const uint64_t w, const unsigned c )+static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c ) { return ( w >> c ) | ( w << ( 64 - c ) ); } /* prevents compiler optimizing out memset() */-BLAKE2_LOCAL_INLINE(void) secure_zero_memory(void *v, size_t n)+static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n) { static void *(*const volatile memset_v)(void *, int, size_t) = &memset; memset_v(v, 0, n); } #endif-
include/ref/blake2.h view
@@ -1,30 +1,27 @@ /* BLAKE2 reference source code package - reference C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */-#pragma once-#ifndef __BLAKE2_H__-#define __BLAKE2_H__+#ifndef BLAKE2_H+#define BLAKE2_H #include <stddef.h> #include <stdint.h> -#ifdef BLAKE2_NO_INLINE-#define BLAKE2_LOCAL_INLINE(type) static type-#endif--#ifndef BLAKE2_LOCAL_INLINE-#define BLAKE2_LOCAL_INLINE(type) static inline type+#if defined(_MSC_VER)+#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))+#else+#define BLAKE2_PACKED(x) x __attribute__((packed)) #endif #if defined(__cplusplus)@@ -49,113 +46,150 @@ BLAKE2B_PERSONALBYTES = 16 }; - typedef struct __blake2s_state+ typedef struct blake2s_state__ { uint32_t h[8]; uint32_t t[2]; uint32_t f[2];- uint8_t buf[2 * BLAKE2S_BLOCKBYTES];+ uint8_t buf[BLAKE2S_BLOCKBYTES]; size_t buflen;+ size_t outlen; uint8_t last_node; } blake2s_state; - typedef struct __blake2b_state+ typedef struct blake2b_state__ { uint64_t h[8]; uint64_t t[2]; uint64_t f[2];- uint8_t buf[2 * BLAKE2B_BLOCKBYTES];+ uint8_t buf[BLAKE2B_BLOCKBYTES]; size_t buflen;+ size_t outlen; uint8_t last_node; } blake2b_state; - typedef struct __blake2sp_state+ typedef struct blake2sp_state__ { blake2s_state S[8][1]; blake2s_state R[1];- uint8_t buf[8 * BLAKE2S_BLOCKBYTES];- size_t buflen;+ uint8_t buf[8 * BLAKE2S_BLOCKBYTES];+ size_t buflen;+ size_t outlen; } blake2sp_state; - typedef struct __blake2bp_state+ typedef struct blake2bp_state__ { blake2b_state S[4][1]; blake2b_state R[1];- uint8_t buf[4 * BLAKE2B_BLOCKBYTES];- size_t buflen;+ uint8_t buf[4 * BLAKE2B_BLOCKBYTES];+ size_t buflen;+ size_t outlen; } blake2bp_state; -#pragma pack(push, 1)- typedef struct __blake2s_param+ BLAKE2_PACKED(struct blake2s_param__ { uint8_t digest_length; /* 1 */ uint8_t key_length; /* 2 */ uint8_t fanout; /* 3 */ uint8_t depth; /* 4 */ uint32_t leaf_length; /* 8 */- uint8_t node_offset[6];// 14+ uint32_t node_offset; /* 12 */+ uint16_t xof_length; /* 14 */ uint8_t node_depth; /* 15 */ uint8_t inner_length; /* 16 */ /* uint8_t reserved[0]; */ uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */- } blake2s_param;+ }); - typedef struct __blake2b_param+ typedef struct blake2s_param__ blake2s_param;++ BLAKE2_PACKED(struct blake2b_param__ { uint8_t digest_length; /* 1 */ uint8_t key_length; /* 2 */ uint8_t fanout; /* 3 */ uint8_t depth; /* 4 */ uint32_t leaf_length; /* 8 */- uint64_t node_offset; /* 16 */+ uint32_t node_offset; /* 12 */+ uint32_t xof_length; /* 16 */ uint8_t node_depth; /* 17 */ uint8_t inner_length; /* 18 */ uint8_t reserved[14]; /* 32 */ uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */- } blake2b_param;-#pragma pack(pop)+ }); + typedef struct blake2b_param__ blake2b_param;++ typedef struct blake2xs_state__+ {+ blake2s_state S[1];+ blake2s_param P[1];+ } blake2xs_state;++ typedef struct blake2xb_state__+ {+ blake2b_state S[1];+ blake2b_param P[1];+ } blake2xb_state;++ /* Padded structs result in a compile-time error */+ enum {+ BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES),+ BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES)+ };+ /* Streaming API */- int blake2s_init( blake2s_state *S, const uint8_t outlen );- int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );+ int blake2s_init( blake2s_state *S, size_t outlen );+ int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); int blake2s_init_param( blake2s_state *S, const blake2s_param *P );- int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen );- int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen );+ int blake2s_update( blake2s_state *S, const void *in, size_t inlen );+ int blake2s_final( blake2s_state *S, void *out, size_t outlen ); - int blake2b_init( blake2b_state *S, const uint8_t outlen );- int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );+ int blake2b_init( blake2b_state *S, size_t outlen );+ int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); int blake2b_init_param( blake2b_state *S, const blake2b_param *P );- int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen );- int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen );+ int blake2b_update( blake2b_state *S, const void *in, size_t inlen );+ int blake2b_final( blake2b_state *S, void *out, size_t outlen ); - int blake2sp_init( blake2sp_state *S, const uint8_t outlen );- int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );- int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen );- int blake2sp_final( blake2sp_state *S, uint8_t *out, uint8_t outlen );+ int blake2sp_init( blake2sp_state *S, size_t outlen );+ int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen );+ int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen );+ int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ); - int blake2bp_init( blake2bp_state *S, const uint8_t outlen );- int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );- int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen );- int blake2bp_final( blake2bp_state *S, uint8_t *out, uint8_t outlen );+ int blake2bp_init( blake2bp_state *S, size_t outlen );+ int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen );+ int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen );+ int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ); + /* Variable output length API */+ int blake2xs_init( blake2xs_state *S, const size_t outlen );+ int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen );+ int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen );+ int blake2xs_final(blake2xs_state *S, void *out, size_t outlen);++ int blake2xb_init( blake2xb_state *S, const size_t outlen );+ int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen );+ int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen );+ int blake2xb_final(blake2xb_state *S, void *out, size_t outlen);+ /* Simple API */- int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );- int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );+ int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );+ int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - int blake2sp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );- int blake2bp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );+ int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );+ int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - static inline int blake2( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )- {- return blake2b( out, in, key, outlen, inlen, keylen );- }+ int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );+ int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + /* This is simply an alias for blake2b */+ int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );+ #if defined(__cplusplus) } #endif #endif-
include/sse/blake2-config.h view
@@ -12,9 +12,8 @@ More information about the BLAKE2 hash function can be found at https://blake2.net. */-#pragma once-#ifndef __BLAKE2_CONFIG_H__-#define __BLAKE2_CONFIG_H__+#ifndef BLAKE2_CONFIG_H+#define BLAKE2_CONFIG_H /* These don't work everywhere */ #if defined(__SSE2__) || defined(__x86_64__) || defined(__amd64__)@@ -71,4 +70,3 @@ #endif #endif-
include/sse/blake2-impl.h view
@@ -1,25 +1,36 @@ /*- BLAKE2 reference source code package - optimized C implementations- + BLAKE2 reference source code package - reference C implementations+ Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */-#pragma once-#ifndef __BLAKE2_IMPL_H__-#define __BLAKE2_IMPL_H__+#ifndef BLAKE2_IMPL_H+#define BLAKE2_IMPL_H #include <stdint.h> #include <string.h> -BLAKE2_LOCAL_INLINE(uint32_t) load32( const void *src )+#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)+ #if defined(_MSC_VER)+ #define BLAKE2_INLINE __inline+ #elif defined(__GNUC__)+ #define BLAKE2_INLINE __inline__+ #else+ #define BLAKE2_INLINE+ #endif+#else+ #define BLAKE2_INLINE inline+#endif++static BLAKE2_INLINE uint32_t load32( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint32_t w;@@ -27,15 +38,14 @@ return w; #else const uint8_t *p = ( const uint8_t * )src;- uint32_t w = *p++;- w |= ( uint32_t )( *p++ ) << 8;- w |= ( uint32_t )( *p++ ) << 16;- w |= ( uint32_t )( *p++ ) << 24;- return w;+ return (( uint32_t )( p[0] ) << 0) |+ (( uint32_t )( p[1] ) << 8) |+ (( uint32_t )( p[2] ) << 16) |+ (( uint32_t )( p[3] ) << 24) ; #endif } -BLAKE2_LOCAL_INLINE(uint64_t) load64( const void *src )+static BLAKE2_INLINE uint64_t load64( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint64_t w;@@ -43,97 +53,108 @@ return w; #else const uint8_t *p = ( const uint8_t * )src;- uint64_t w = *p++;- w |= ( uint64_t )( *p++ ) << 8;- w |= ( uint64_t )( *p++ ) << 16;- w |= ( uint64_t )( *p++ ) << 24;- w |= ( uint64_t )( *p++ ) << 32;- w |= ( uint64_t )( *p++ ) << 40;- w |= ( uint64_t )( *p++ ) << 48;- w |= ( uint64_t )( *p++ ) << 56;- return w;+ return (( uint64_t )( p[0] ) << 0) |+ (( uint64_t )( p[1] ) << 8) |+ (( uint64_t )( p[2] ) << 16) |+ (( uint64_t )( p[3] ) << 24) |+ (( uint64_t )( p[4] ) << 32) |+ (( uint64_t )( p[5] ) << 40) |+ (( uint64_t )( p[6] ) << 48) |+ (( uint64_t )( p[7] ) << 56) ; #endif } -BLAKE2_LOCAL_INLINE(void) store32( void *dst, uint32_t w )+static BLAKE2_INLINE uint16_t load16( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN)- memcpy(dst, &w, sizeof w);+ uint16_t w;+ memcpy(&w, src, sizeof w);+ return w; #else- uint8_t *p = ( uint8_t * )dst;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w;+ const uint8_t *p = ( const uint8_t * )src;+ return ( uint16_t )((( uint32_t )( p[0] ) << 0) |+ (( uint32_t )( p[1] ) << 8)); #endif } -BLAKE2_LOCAL_INLINE(void) store64( void *dst, uint64_t w )+static BLAKE2_INLINE void store16( void *dst, uint16_t w ) { #if defined(NATIVE_LITTLE_ENDIAN) memcpy(dst, &w, sizeof w); #else uint8_t *p = ( uint8_t * )dst; *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8; *p++ = ( uint8_t )w; #endif } -BLAKE2_LOCAL_INLINE(uint64_t) load48( const void *src )+static BLAKE2_INLINE void store32( void *dst, uint32_t w ) {- const uint8_t *p = ( const uint8_t * )src;- uint64_t w = *p++;- w |= ( uint64_t )( *p++ ) << 8;- w |= ( uint64_t )( *p++ ) << 16;- w |= ( uint64_t )( *p++ ) << 24;- w |= ( uint64_t )( *p++ ) << 32;- w |= ( uint64_t )( *p++ ) << 40;- return w;+#if defined(NATIVE_LITTLE_ENDIAN)+ memcpy(dst, &w, sizeof w);+#else+ uint8_t *p = ( uint8_t * )dst;+ p[0] = (uint8_t)(w >> 0);+ p[1] = (uint8_t)(w >> 8);+ p[2] = (uint8_t)(w >> 16);+ p[3] = (uint8_t)(w >> 24);+#endif } -BLAKE2_LOCAL_INLINE(void) store48( void *dst, uint64_t w )+static BLAKE2_INLINE void store64( void *dst, uint64_t w ) {+#if defined(NATIVE_LITTLE_ENDIAN)+ memcpy(dst, &w, sizeof w);+#else uint8_t *p = ( uint8_t * )dst;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w; w >>= 8;- *p++ = ( uint8_t )w;+ p[0] = (uint8_t)(w >> 0);+ p[1] = (uint8_t)(w >> 8);+ p[2] = (uint8_t)(w >> 16);+ p[3] = (uint8_t)(w >> 24);+ p[4] = (uint8_t)(w >> 32);+ p[5] = (uint8_t)(w >> 40);+ p[6] = (uint8_t)(w >> 48);+ p[7] = (uint8_t)(w >> 56);+#endif } -BLAKE2_LOCAL_INLINE(uint32_t) rotl32( const uint32_t w, const unsigned c )+static BLAKE2_INLINE uint64_t load48( const void *src ) {- return ( w << c ) | ( w >> ( 32 - c ) );+ const uint8_t *p = ( const uint8_t * )src;+ return (( uint64_t )( p[0] ) << 0) |+ (( uint64_t )( p[1] ) << 8) |+ (( uint64_t )( p[2] ) << 16) |+ (( uint64_t )( p[3] ) << 24) |+ (( uint64_t )( p[4] ) << 32) |+ (( uint64_t )( p[5] ) << 40) ; } -BLAKE2_LOCAL_INLINE(uint64_t) rotl64( const uint64_t w, const unsigned c )+static BLAKE2_INLINE void store48( void *dst, uint64_t w ) {- return ( w << c ) | ( w >> ( 64 - c ) );+ uint8_t *p = ( uint8_t * )dst;+ p[0] = (uint8_t)(w >> 0);+ p[1] = (uint8_t)(w >> 8);+ p[2] = (uint8_t)(w >> 16);+ p[3] = (uint8_t)(w >> 24);+ p[4] = (uint8_t)(w >> 32);+ p[5] = (uint8_t)(w >> 40); } -BLAKE2_LOCAL_INLINE(uint32_t) rotr32( const uint32_t w, const unsigned c )+static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c ) { return ( w >> c ) | ( w << ( 32 - c ) ); } -BLAKE2_LOCAL_INLINE(uint64_t) rotr64( const uint64_t w, const unsigned c )+static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c ) { return ( w >> c ) | ( w << ( 64 - c ) ); } /* prevents compiler optimizing out memset() */-BLAKE2_LOCAL_INLINE(void) secure_zero_memory(void *v, size_t n)+static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n) { static void *(*const volatile memset_v)(void *, int, size_t) = &memset; memset_v(v, 0, n); } #endif-
include/sse/blake2.h view
@@ -1,30 +1,27 @@ /* BLAKE2 reference source code package - reference C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */-#pragma once-#ifndef __BLAKE2_H__-#define __BLAKE2_H__+#ifndef BLAKE2_H+#define BLAKE2_H #include <stddef.h> #include <stdint.h> -#ifdef BLAKE2_NO_INLINE-#define BLAKE2_LOCAL_INLINE(type) static type-#endif--#ifndef BLAKE2_LOCAL_INLINE-#define BLAKE2_LOCAL_INLINE(type) static inline type+#if defined(_MSC_VER)+#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))+#else+#define BLAKE2_PACKED(x) x __attribute__((packed)) #endif #if defined(__cplusplus)@@ -49,113 +46,150 @@ BLAKE2B_PERSONALBYTES = 16 }; - typedef struct __blake2s_state+ typedef struct blake2s_state__ { uint32_t h[8]; uint32_t t[2]; uint32_t f[2];- uint8_t buf[2 * BLAKE2S_BLOCKBYTES];+ uint8_t buf[BLAKE2S_BLOCKBYTES]; size_t buflen;+ size_t outlen; uint8_t last_node; } blake2s_state; - typedef struct __blake2b_state+ typedef struct blake2b_state__ { uint64_t h[8]; uint64_t t[2]; uint64_t f[2];- uint8_t buf[2 * BLAKE2B_BLOCKBYTES];+ uint8_t buf[BLAKE2B_BLOCKBYTES]; size_t buflen;+ size_t outlen; uint8_t last_node; } blake2b_state; - typedef struct __blake2sp_state+ typedef struct blake2sp_state__ { blake2s_state S[8][1]; blake2s_state R[1];- uint8_t buf[8 * BLAKE2S_BLOCKBYTES];- size_t buflen;+ uint8_t buf[8 * BLAKE2S_BLOCKBYTES];+ size_t buflen;+ size_t outlen; } blake2sp_state; - typedef struct __blake2bp_state+ typedef struct blake2bp_state__ { blake2b_state S[4][1]; blake2b_state R[1];- uint8_t buf[4 * BLAKE2B_BLOCKBYTES];- size_t buflen;+ uint8_t buf[4 * BLAKE2B_BLOCKBYTES];+ size_t buflen;+ size_t outlen; } blake2bp_state; -#pragma pack(push, 1)- typedef struct __blake2s_param+ BLAKE2_PACKED(struct blake2s_param__ { uint8_t digest_length; /* 1 */ uint8_t key_length; /* 2 */ uint8_t fanout; /* 3 */ uint8_t depth; /* 4 */ uint32_t leaf_length; /* 8 */- uint8_t node_offset[6];// 14+ uint32_t node_offset; /* 12 */+ uint16_t xof_length; /* 14 */ uint8_t node_depth; /* 15 */ uint8_t inner_length; /* 16 */ /* uint8_t reserved[0]; */ uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */- } blake2s_param;+ }); - typedef struct __blake2b_param+ typedef struct blake2s_param__ blake2s_param;++ BLAKE2_PACKED(struct blake2b_param__ { uint8_t digest_length; /* 1 */ uint8_t key_length; /* 2 */ uint8_t fanout; /* 3 */ uint8_t depth; /* 4 */ uint32_t leaf_length; /* 8 */- uint64_t node_offset; /* 16 */+ uint32_t node_offset; /* 12 */+ uint32_t xof_length; /* 16 */ uint8_t node_depth; /* 17 */ uint8_t inner_length; /* 18 */ uint8_t reserved[14]; /* 32 */ uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */- } blake2b_param;-#pragma pack(pop)+ }); + typedef struct blake2b_param__ blake2b_param;++ typedef struct blake2xs_state__+ {+ blake2s_state S[1];+ blake2s_param P[1];+ } blake2xs_state;++ typedef struct blake2xb_state__+ {+ blake2b_state S[1];+ blake2b_param P[1];+ } blake2xb_state;++ /* Padded structs result in a compile-time error */+ enum {+ BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES),+ BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES)+ };+ /* Streaming API */- int blake2s_init( blake2s_state *S, const uint8_t outlen );- int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );+ int blake2s_init( blake2s_state *S, size_t outlen );+ int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); int blake2s_init_param( blake2s_state *S, const blake2s_param *P );- int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen );- int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen );+ int blake2s_update( blake2s_state *S, const void *in, size_t inlen );+ int blake2s_final( blake2s_state *S, void *out, size_t outlen ); - int blake2b_init( blake2b_state *S, const uint8_t outlen );- int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );+ int blake2b_init( blake2b_state *S, size_t outlen );+ int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); int blake2b_init_param( blake2b_state *S, const blake2b_param *P );- int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen );- int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen );+ int blake2b_update( blake2b_state *S, const void *in, size_t inlen );+ int blake2b_final( blake2b_state *S, void *out, size_t outlen ); - int blake2sp_init( blake2sp_state *S, const uint8_t outlen );- int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );- int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen );- int blake2sp_final( blake2sp_state *S, uint8_t *out, uint8_t outlen );+ int blake2sp_init( blake2sp_state *S, size_t outlen );+ int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen );+ int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen );+ int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ); - int blake2bp_init( blake2bp_state *S, const uint8_t outlen );- int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );- int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen );- int blake2bp_final( blake2bp_state *S, uint8_t *out, uint8_t outlen );+ int blake2bp_init( blake2bp_state *S, size_t outlen );+ int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen );+ int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen );+ int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ); + /* Variable output length API */+ int blake2xs_init( blake2xs_state *S, const size_t outlen );+ int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen );+ int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen );+ int blake2xs_final(blake2xs_state *S, void *out, size_t outlen);++ int blake2xb_init( blake2xb_state *S, const size_t outlen );+ int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen );+ int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen );+ int blake2xb_final(blake2xb_state *S, void *out, size_t outlen);+ /* Simple API */- int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );- int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );+ int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );+ int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - int blake2sp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );- int blake2bp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );+ int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );+ int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - static inline int blake2( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )- {- return blake2b( out, in, key, outlen, inlen, keylen );- }+ int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );+ int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + /* This is simply an alias for blake2b */+ int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );+ #if defined(__cplusplus) } #endif #endif-
include/sse/blake2b-load-sse2.h view
@@ -1,20 +1,19 @@ /* BLAKE2 reference source code package - optimized C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */-#pragma once-#ifndef __BLAKE2B_LOAD_SSE2_H__-#define __BLAKE2B_LOAD_SSE2_H__+#ifndef BLAKE2B_LOAD_SSE2_H+#define BLAKE2B_LOAD_SSE2_H #define LOAD_MSG_0_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4) #define LOAD_MSG_0_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5)@@ -67,4 +66,3 @@ #endif-
include/sse/blake2b-load-sse41.h view
@@ -1,20 +1,19 @@ /* BLAKE2 reference source code package - optimized C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */-#pragma once-#ifndef __BLAKE2B_LOAD_SSE41_H__-#define __BLAKE2B_LOAD_SSE41_H__+#ifndef BLAKE2B_LOAD_SSE41_H+#define BLAKE2B_LOAD_SSE41_H #define LOAD_MSG_0_1(b0, b1) \ do \@@ -401,4 +400,3 @@ #endif-
include/sse/blake2b-round.h view
@@ -1,20 +1,19 @@ /* BLAKE2 reference source code package - optimized C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */-#pragma once-#ifndef __BLAKE2B_ROUND_H__-#define __BLAKE2B_ROUND_H__+#ifndef BLAKE2B_ROUND_H+#define BLAKE2B_ROUND_H #define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) ) #define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r)@@ -61,7 +60,7 @@ \ row2l = _mm_roti_epi64(row2l, -24); \ row2h = _mm_roti_epi64(row2h, -24); \- + #define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \@@ -80,7 +79,7 @@ \ row2l = _mm_roti_epi64(row2l, -63); \ row2h = _mm_roti_epi64(row2h, -63); \- + #if defined(HAVE_SSSE3) #define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ t0 = _mm_alignr_epi8(row2h, row2l, 8); \@@ -156,4 +155,3 @@ UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); #endif-
include/sse/blake2s-load-sse2.h view
@@ -1,20 +1,19 @@ /* BLAKE2 reference source code package - optimized C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */-#pragma once-#ifndef __BLAKE2S_LOAD_SSE2_H__-#define __BLAKE2S_LOAD_SSE2_H__+#ifndef BLAKE2S_LOAD_SSE2_H+#define BLAKE2S_LOAD_SSE2_H #define LOAD_MSG_0_1(buf) buf = _mm_set_epi32(m6,m4,m2,m0) #define LOAD_MSG_0_2(buf) buf = _mm_set_epi32(m7,m5,m3,m1)
include/sse/blake2s-load-sse41.h view
@@ -1,20 +1,19 @@ /* BLAKE2 reference source code package - optimized C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */-#pragma once-#ifndef __BLAKE2S_LOAD_SSE41_H__-#define __BLAKE2S_LOAD_SSE41_H__+#ifndef BLAKE2S_LOAD_SSE41_H+#define BLAKE2S_LOAD_SSE41_H #define LOAD_MSG_0_1(buf) \ buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(2,0,2,0)));@@ -228,4 +227,3 @@ buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,1,2,3)); #endif-
include/sse/blake2s-load-xop.h view
@@ -1,25 +1,25 @@ /* BLAKE2 reference source code package - optimized C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */-#pragma once-#ifndef __BLAKE2S_LOAD_XOP_H__-#define __BLAKE2S_LOAD_XOP_H__+#ifndef BLAKE2S_LOAD_XOP_H+#define BLAKE2S_LOAD_XOP_H #define TOB(x) ((x)*4*0x01010101 + 0x03020100) /* ..or not TOB */ +#if 0 /* Basic VPPERM emulation, for testing purposes */-/*static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel)+static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel) { const __m128i sixteen = _mm_set1_epi8(16); const __m128i t0 = _mm_shuffle_epi8(src1, sel);@@ -27,7 +27,8 @@ const __m128i mask = _mm_or_si128(_mm_cmpeq_epi8(sel, sixteen), _mm_cmpgt_epi8(sel, sixteen)); /* (>=16) = 0xff : 00 */ return _mm_blendv_epi8(t0, s1, mask);-}*/+}+#endif #define LOAD_MSG_0_1(buf) \ buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) );@@ -168,7 +169,7 @@ #define LOAD_MSG_8_3(buf) \ t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(6),TOB(1),TOB(0),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(5),TOB(4)) ); \- + #define LOAD_MSG_8_4(buf) \ buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(4),TOB(7),TOB(2)) ); @@ -188,4 +189,3 @@ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(6),TOB(0)) ); #endif-
include/sse/blake2s-round.h view
@@ -1,20 +1,19 @@ /* BLAKE2 reference source code package - optimized C implementations- + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at:- + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0- + More information about the BLAKE2 hash function can be found at https://blake2.net. */-#pragma once-#ifndef __BLAKE2S_ROUND_H__-#define __BLAKE2S_ROUND_H__+#ifndef BLAKE2S_ROUND_H+#define BLAKE2S_ROUND_H #define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) ) #define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r)@@ -85,6 +84,5 @@ LOAD_MSG_ ##r ##_4(buf4); \ G2(row1,row2,row3,row4,buf4); \ UNDIAGONALIZE(row1,row2,row3,row4); \- -#endif +#endif
src/Crypto/Hash/BLAKE2/BLAKE2b.hsc view
@@ -17,7 +17,7 @@ ) where import Data.ByteString (ByteString)-import Foreign.C.Types (CInt(..))+import Foreign.C.Types (CInt(..), CSize(..)) import Foreign.ForeignPtr (ForeignPtr) import Foreign.Storable (Storable(..))
src/Crypto/Hash/BLAKE2/BLAKE2bp.hsc view
@@ -17,7 +17,7 @@ ) where import Data.ByteString (ByteString)-import Foreign.C.Types (CInt(..))+import Foreign.C.Types (CInt(..), CSize(..)) import Foreign.ForeignPtr (ForeignPtr) import Foreign.Storable (Storable(..))
src/Crypto/Hash/BLAKE2/BLAKE2s.hsc view
@@ -17,7 +17,7 @@ ) where import Data.ByteString (ByteString)-import Foreign.C.Types (CInt(..))+import Foreign.C.Types (CInt(..), CSize(..)) import Foreign.ForeignPtr (ForeignPtr) import Foreign.Storable (Storable(..))
src/Crypto/Hash/BLAKE2/BLAKE2sp.hsc view
@@ -17,7 +17,7 @@ ) where import Data.ByteString (ByteString)-import Foreign.C.Types (CInt(..))+import Foreign.C.Types (CInt(..), CSize(..)) import Foreign.ForeignPtr (ForeignPtr) import Foreign.Storable (Storable(..))
src/Crypto/Hash/BLAKE2/Internal.hs view
@@ -24,36 +24,32 @@ import Data.ByteString (ByteString) import Data.ByteString.Internal (create, toForeignPtr) import Data.ByteString.Unsafe (unsafeUseAsCStringLen)-import Data.Word (Word8, Word64)-import Foreign.C.Types (CInt(..), CChar)+import Foreign.C.Types (CInt, CSize) import Foreign.ForeignPtr (ForeignPtr, mallocForeignPtr, withForeignPtr) import Foreign.Marshal.Array (copyArray)-import Foreign.Ptr (Ptr)-import Foreign.Storable (Storable(..))+import Foreign.Ptr (Ptr, castPtr)+import Foreign.Storable (Storable) import System.IO.Unsafe (unsafePerformIO) --- int blake2X_init( blake2s_state *S, const uint8_t outlen );-type InitFunc a = Ptr a -> Int -> IO CInt+-- int blake2X_init( blake2X_state *S, size_t outlen );+type InitFunc a = Ptr a -> CSize -> IO CInt --- int blake2X_init_key( blake2s_state *S, const uint8_t outlen, const void--- *key, const uint8_t keylen );-type InitKeyFunc a = Ptr a -> Word8 -> Ptr CChar -> Word8 -> IO CInt+-- int blake2X_init_key( blake2X_state *S, size_t outlen, const void *key, size_t keylen );+type InitKeyFunc a = Ptr a -> CSize -> Ptr () -> CSize -> IO CInt --- int blake2X_update( blake2s_state *S, const uint8_t *in,--- uint64_t inlen );-type UpdateFunc a = Ptr a -> Ptr Word8 -> Word64 -> IO CInt+-- int blake2X_update( blake2X_state *S, const void *in, size_t inlen );+type UpdateFunc a = Ptr a -> Ptr () -> CSize -> IO CInt --- int blake2X_final( blake2s_state *S, uint8_t *out, uint8_t outlen );-type FinalFunc a = Ptr a -> Ptr Word8 -> Word8 -> IO CInt+-- int blake2X_final( blake2X_state *S, void *out, size_t outlen );+type FinalFunc a = Ptr a -> Ptr () -> CSize -> IO CInt --- int blake2X( uint8_t *out, const void *in, const void *key, const--- uint8_t outlen, const uint64_t inlen, uint8_t keylen );-type HashFunc = Ptr Word8- -> Ptr CChar- -> Ptr CChar- -> Word8- -> Word64- -> Word8+-- int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );+type HashFunc = Ptr ()+ -> CSize+ -> Ptr ()+ -> CSize+ -> Ptr ()+ -> CSize -> IO CInt initializer :: Storable a@@ -63,7 +59,7 @@ initializer f outlen = unsafePerformIO $ do fptr <- mallocForeignPtr withForeignPtr fptr $ \ptr -> do- ret <- f ptr outlen+ ret <- f (castPtr ptr) (fromIntegral outlen) if ret == 0 then return fptr else error "initialization failure"@@ -77,9 +73,9 @@ fptr <- mallocForeignPtr withForeignPtr fptr $ \ptr -> unsafeUseAsCStringLen key $ \(kptr, klen) -> do- let klen' = fromIntegral klen+ let klen' = fromIntegral klen outlen' = fromIntegral outlen- ret <- f ptr outlen' kptr klen'+ ret <- f ptr outlen' (castPtr kptr) klen' if ret == 0 then return fptr else error "initialization failure"@@ -97,7 +93,7 @@ withForeignPtr dfp $ \dptr -> withForeignPtr state $ \sptr -> do copyArray nsptr sptr 1- void $ f nsptr dptr dlen'+ void $ f (castPtr nsptr) (castPtr dptr) dlen' return newState finalizer :: Storable a@@ -112,19 +108,21 @@ withForeignPtr state $ \sptr -> do let outlen' = fromIntegral outlen copyArray nsptr sptr 1- void $ f nsptr optr outlen'+ void $ f (castPtr nsptr) (castPtr optr) outlen' hasher :: HashFunc -> Int -> ByteString -> ByteString -> ByteString-hasher h outlen key input =- unsafePerformIO . create outlen $ \out ->+hasher h olen key input =+ unsafePerformIO . create olen $ \ostr -> unsafeUseAsCStringLen key $ \(kstr, klen) -> unsafeUseAsCStringLen input $ \(istr, ilen) ->- let outlen' = fromIntegral outlen- ilen' = fromIntegral ilen- klen' = fromIntegral klen- in void $ h out istr kstr outlen' ilen' klen'+ let olen' = fromIntegral olen+ ilen' = fromIntegral ilen+ klen' = fromIntegral klen+ in void $ h (castPtr ostr) olen'+ (castPtr istr) ilen'+ (castPtr kstr) klen' {-# INLINE hasher #-}