├── .envrc ├── .github └── workflows │ └── haskell.yaml ├── .gitignore ├── LICENSE ├── README.md ├── benchmarks └── bench.hs ├── blake2.cabal ├── cbits ├── ref │ ├── blake2b-ref.c │ ├── blake2bp-ref.c │ ├── blake2s-ref.c │ └── blake2sp-ref.c └── sse │ ├── blake2b.c │ ├── blake2bp.c │ ├── blake2s.c │ └── blake2sp.c ├── changelog.md ├── flake.lock ├── flake.nix ├── include ├── ref │ ├── blake2-impl.h │ └── blake2.h └── sse │ ├── blake2-config.h │ ├── blake2-impl.h │ ├── blake2.h │ ├── blake2b-load-sse2.h │ ├── blake2b-load-sse41.h │ ├── blake2b-round.h │ ├── blake2s-load-sse2.h │ ├── blake2s-load-sse41.h │ ├── blake2s-load-xop.h │ └── blake2s-round.h ├── src └── Crypto │ └── Hash │ └── BLAKE2 │ ├── BLAKE2b.hsc │ ├── BLAKE2bp.hsc │ ├── BLAKE2s.hsc │ ├── BLAKE2sp.hsc │ └── Internal.hs ├── stack.yaml ├── stack.yaml.lock └── tests ├── Imports.hs ├── hlint.hs └── properties.hs /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | 3 | watch_file **/*.cabal **/*.nix flake.lock 4 | -------------------------------------------------------------------------------- /.github/workflows/haskell.yaml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | push: 4 | branches: [master] 5 | pull_request: 6 | branches: [master] 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | build: 13 | name: ghc-${{ matrix.ghc-version }} ${{ matrix.os }} ${{ matrix.llvm && '+' || '-' }}llvm ${{ matrix.support_blake2_sse && '+' || '-' }}support_blake2_sse 14 | runs-on: ${{ matrix.os }} 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | os: [ubuntu-latest] 19 | ghc-version: ['9.6', '9.4', '9.2', '9.0'] 20 | llvm: [false] 21 | support_blake2_sse: [false] 22 | 23 | include: 24 | - os: windows-latest 25 | ghc-version: '9.6' 26 | llvm: false 27 | support_blake2_sse: false 28 | - os: macos-latest 29 | ghc-version: '9.6' 30 | llvm: false 31 | support_blake2_sse: false 32 | - os: ubuntu-latest 33 | ghc-version: '9.6' 34 | llvm: true 35 | support_blake2_sse: true 36 | 37 | steps: 38 | - uses: actions/checkout@v3 39 | 40 | - name: Set up GHC ${{ matrix.ghc-version }} 41 | uses: haskell/actions/setup@v2 42 | id: setup 43 | with: 44 | ghc-version: ${{ matrix.ghc-version }} 45 | # Defaults, added for clarity: 46 | cabal-version: 'latest' 47 | cabal-update: true 48 | 49 | - name: Configure the build 50 | run: | 51 | cabal configure --enable-tests --enable-benchmarks --disable-documentation --flags "${{ contains(fromJson('["9.4", "9.2", "9.0"]'), matrix.ghc-version) && '+' || '-' }}hlint ${{ matrix.llvm && '+' || '-' }}llvm ${{ matrix.support_blake2_sse && '+' || '-' }}support_blake2_sse" 52 | cabal build --dry-run 53 | # The last step generates dist-newstyle/cache/plan.json for the cache key. 54 | 55 | - name: Restore cached dependencies 56 | uses: actions/cache/restore@v3 57 | id: cache 58 | env: 59 | key: ${{ runner.os }}-ghc-${{ steps.setup.outputs.ghc-version }}-cabal-${{ steps.setup.outputs.cabal-version }} 60 | with: 61 | path: ${{ steps.setup.outputs.cabal-store }} 62 | key: ${{ env.key }}-plan-${{ hashFiles('**/plan.json') }} 63 | restore-keys: ${{ env.key }}- 64 | 65 | - name: Install dependencies 66 | run: cabal build all --only-dependencies 67 | 68 | # Cache dependencies already here, so that we do not have to rebuild them should the subsequent steps fail. 69 | - name: Save cached dependencies 70 | uses: actions/cache/save@v3 71 | # Caches are immutable, trying to save with the same key would error. 72 | if: ${{ steps.cache.outputs.cache-primary-key != steps.cache.outputs.cache-matched-key }} 73 | with: 74 | path: ${{ steps.setup.outputs.cabal-store }} 75 | key: ${{ steps.cache.outputs.cache-primary-key }} 76 | 77 | - name: Build 78 | run: cabal build all 79 | 80 | - name: Run tests 81 | run: cabal test all 82 | 83 | - name: Check cabal file 84 | run: cabal check 85 | 86 | - name: Build documentation 87 | run: cabal haddock all 88 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | *.swp 3 | *.log 4 | .cabal-sandbox/ 5 | cabal.sandbox.config 6 | cabal.config 7 | .stack-work/ 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # blake2 2 | 3 | This library provides the [BLAKE2] hash algorithms. 4 | 5 | ## Comparison with other libraries 6 | 7 | This library has fewer dependencies than [cryptonite] and a richer API for 8 | features like keyed hashing and variable-length output. 9 | 10 | [BLAKE2]: https://blake2.net/ 11 | 12 | [cryptonite]: https://github.com/haskell-crypto/cryptonite 13 | -------------------------------------------------------------------------------- /benchmarks/bench.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | module Main where 3 | 4 | import Criterion.Main 5 | import Data.ByteString (ByteString) 6 | import qualified Data.ByteString as B (replicate) 7 | 8 | import qualified Crypto.Hash.BLAKE2.BLAKE2b as B2b 9 | import qualified Crypto.Hash.BLAKE2.BLAKE2bp as B2bp 10 | import qualified Crypto.Hash.BLAKE2.BLAKE2s as B2s 11 | import qualified Crypto.Hash.BLAKE2.BLAKE2sp as B2sp 12 | 13 | kb :: ByteString 14 | kb = B.replicate 1024 3 15 | 16 | mb :: ByteString 17 | mb = B.replicate (1024 ^ (2 :: Int)) 3 18 | 19 | gb :: ByteString 20 | gb = B.replicate (1024 ^ (3 :: Int)) 3 21 | 22 | main :: IO () 23 | main = defaultMain 24 | [ bgroup "blake2s" [ bench "1 kb" $ nf (B2s.hash 32 "") kb 25 | , bench "1 mb" $ nf (B2s.hash 32 "") mb 26 | , bench "1 gb" $ nf (B2s.hash 32 "") gb 27 | ] 28 | , bgroup "blake2sp" [ bench "1 kb" $ nf (B2sp.hash 32 "") kb 29 | , bench "1 mb" $ nf (B2sp.hash 32 "") mb 30 | , bench "1 gb" $ nf (B2sp.hash 32 "") gb 31 | ] 32 | , bgroup "blake2b" [ bench "1 kb" $ nf (B2b.hash 64 "") kb 33 | , bench "1 mb" $ nf (B2b.hash 64 "") mb 34 | , bench "1 gb" $ nf (B2b.hash 64 "") gb 35 | ] 36 | , bgroup "blake2bp" [ bench "1 kb" $ nf (B2bp.hash 64 "") kb 37 | , bench "1 mb" $ nf (B2bp.hash 64 "") mb 38 | , bench "1 gb" $ nf (B2bp.hash 64 "") gb 39 | ] 40 | ] 41 | -------------------------------------------------------------------------------- /blake2.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 3.0 2 | 3 | name: blake2 4 | version: 0.3.0.1 5 | synopsis: A library providing BLAKE2 6 | license: Unlicense 7 | license-file: LICENSE 8 | author: John Galt 9 | maintainer: jgalt@centromere.net 10 | homepage: https://github.com/haskell-cryptography/blake2 11 | bug-reports: https://github.com/haskell-cryptography/blake2/issues 12 | category: Cryptography 13 | description: 14 | This library provides the hash algorithms. 15 | 16 | extra-source-files: 17 | README.md 18 | changelog.md 19 | include/ref/*.h 20 | include/sse/*.h 21 | 22 | source-repository head 23 | type: git 24 | location: https://github.com/haskell-cryptography/blake2.git 25 | 26 | flag hlint 27 | 28 | flag llvm 29 | default: False 30 | manual: True 31 | 32 | flag support_blake2_sse 33 | description: Use SSE optimized version of BLAKE2 34 | default: False 35 | manual: True 36 | 37 | common base 38 | default-language: Haskell2010 39 | ghc-options: -Wall -fwarn-tabs 40 | build-depends: 41 | , base ^>= 4.15 || ^>= 4.16 || ^>= 4.17 || ^>= 4.18 42 | , bytestring ^>= 0.10.12 || ^>= 0.11 43 | 44 | library 45 | import: base 46 | hs-source-dirs: src 47 | exposed-modules: 48 | Crypto.Hash.BLAKE2.BLAKE2b 49 | Crypto.Hash.BLAKE2.BLAKE2bp 50 | Crypto.Hash.BLAKE2.BLAKE2s 51 | Crypto.Hash.BLAKE2.BLAKE2sp 52 | Crypto.Hash.BLAKE2.Internal 53 | cc-options: -std=c99 54 | 55 | if arch(x86_64) || flag(support_blake2_sse) 56 | c-sources: 57 | cbits/sse/blake2b.c 58 | cbits/sse/blake2bp.c 59 | cbits/sse/blake2s.c 60 | cbits/sse/blake2sp.c 61 | include-dirs: include/sse 62 | else 63 | c-sources: 64 | cbits/ref/blake2b-ref.c 65 | cbits/ref/blake2bp-ref.c 66 | cbits/ref/blake2s-ref.c 67 | cbits/ref/blake2sp-ref.c 68 | include-dirs: include/ref 69 | 70 | if flag(llvm) 71 | ghc-options: -fllvm 72 | 73 | test-suite properties 74 | import: base 75 | type: exitcode-stdio-1.0 76 | main-is: properties.hs 77 | hs-source-dirs: tests 78 | 79 | build-depends: 80 | , base16-bytestring ^>= 1.0.0 81 | , blake2 82 | , QuickCheck ^>= 2.14.3 83 | , tasty ^>= 1.4.3 84 | , tasty-quickcheck ^>= 0.10.2 85 | 86 | other-modules: 87 | Imports 88 | 89 | test-suite hlint 90 | import: base 91 | type: exitcode-stdio-1.0 92 | main-is: hlint.hs 93 | hs-source-dirs: tests 94 | 95 | if !flag(hlint) 96 | buildable: False 97 | else 98 | build-depends: hlint ^>= 3.5 99 | 100 | benchmark bench 101 | import: base 102 | type: exitcode-stdio-1.0 103 | main-is: bench.hs 104 | hs-source-dirs: benchmarks 105 | 106 | build-depends: 107 | , blake2 108 | , criterion ^>= 1.6.2 109 | -------------------------------------------------------------------------------- /cbits/ref/blake2b-ref.c: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - reference C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "blake2.h" 21 | #include "blake2-impl.h" 22 | 23 | static const uint64_t blake2b_IV[8] = 24 | { 25 | 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 26 | 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 27 | 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 28 | 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL 29 | }; 30 | 31 | static const uint8_t blake2b_sigma[12][16] = 32 | { 33 | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , 34 | { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , 35 | { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , 36 | { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , 37 | { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , 38 | { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , 39 | { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , 40 | { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , 41 | { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , 42 | { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , 43 | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , 44 | { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } 45 | }; 46 | 47 | 48 | static void blake2b_set_lastnode( blake2b_state *S ) 49 | { 50 | S->f[1] = (uint64_t)-1; 51 | } 52 | 53 | /* Some helper functions, not necessarily useful */ 54 | static int blake2b_is_lastblock( const blake2b_state *S ) 55 | { 56 | return S->f[0] != 0; 57 | } 58 | 59 | static void blake2b_set_lastblock( blake2b_state *S ) 60 | { 61 | if( S->last_node ) blake2b_set_lastnode( S ); 62 | 63 | S->f[0] = (uint64_t)-1; 64 | } 65 | 66 | static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) 67 | { 68 | S->t[0] += inc; 69 | S->t[1] += ( S->t[0] < inc ); 70 | } 71 | 72 | static void blake2b_init0( blake2b_state *S ) 73 | { 74 | size_t i; 75 | memset( S, 0, sizeof( blake2b_state ) ); 76 | 77 | for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; 78 | } 79 | 80 | /* init xors IV with input parameter block */ 81 | int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) 82 | { 83 | const uint8_t *p = ( const uint8_t * )( P ); 84 | size_t i; 85 | 86 | blake2b_init0( S ); 87 | 88 | /* IV XOR ParamBlock */ 89 | for( i = 0; i < 8; ++i ) 90 | S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); 91 | 92 | S->outlen = P->digest_length; 93 | return 0; 94 | } 95 | 96 | 97 | 98 | int blake2b_init( blake2b_state *S, size_t outlen ) 99 | { 100 | blake2b_param P[1]; 101 | 102 | if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; 103 | 104 | P->digest_length = (uint8_t)outlen; 105 | P->key_length = 0; 106 | P->fanout = 1; 107 | P->depth = 1; 108 | store32( &P->leaf_length, 0 ); 109 | store32( &P->node_offset, 0 ); 110 | store32( &P->xof_length, 0 ); 111 | P->node_depth = 0; 112 | P->inner_length = 0; 113 | memset( P->reserved, 0, sizeof( P->reserved ) ); 114 | memset( P->salt, 0, sizeof( P->salt ) ); 115 | memset( P->personal, 0, sizeof( P->personal ) ); 116 | return blake2b_init_param( S, P ); 117 | } 118 | 119 | 120 | int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) 121 | { 122 | blake2b_param P[1]; 123 | 124 | if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; 125 | 126 | if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; 127 | 128 | P->digest_length = (uint8_t)outlen; 129 | P->key_length = (uint8_t)keylen; 130 | P->fanout = 1; 131 | P->depth = 1; 132 | store32( &P->leaf_length, 0 ); 133 | store32( &P->node_offset, 0 ); 134 | store32( &P->xof_length, 0 ); 135 | P->node_depth = 0; 136 | P->inner_length = 0; 137 | memset( P->reserved, 0, sizeof( P->reserved ) ); 138 | memset( P->salt, 0, sizeof( P->salt ) ); 139 | memset( P->personal, 0, sizeof( P->personal ) ); 140 | 141 | if( blake2b_init_param( S, P ) < 0 ) return -1; 142 | 143 | { 144 | uint8_t block[BLAKE2B_BLOCKBYTES]; 145 | memset( block, 0, BLAKE2B_BLOCKBYTES ); 146 | memcpy( block, key, keylen ); 147 | blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); 148 | secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ 149 | } 150 | return 0; 151 | } 152 | 153 | #define G(r,i,a,b,c,d) \ 154 | do { \ 155 | a = a + b + m[blake2b_sigma[r][2*i+0]]; \ 156 | d = rotr64(d ^ a, 32); \ 157 | c = c + d; \ 158 | b = rotr64(b ^ c, 24); \ 159 | a = a + b + m[blake2b_sigma[r][2*i+1]]; \ 160 | d = rotr64(d ^ a, 16); \ 161 | c = c + d; \ 162 | b = rotr64(b ^ c, 63); \ 163 | } while(0) 164 | 165 | #define ROUND(r) \ 166 | do { \ 167 | G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ 168 | G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ 169 | G(r,2,v[ 2],v[ 6],v[10],v[14]); \ 170 | G(r,3,v[ 3],v[ 7],v[11],v[15]); \ 171 | G(r,4,v[ 0],v[ 5],v[10],v[15]); \ 172 | G(r,5,v[ 1],v[ 6],v[11],v[12]); \ 173 | G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ 174 | G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ 175 | } while(0) 176 | 177 | static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) 178 | { 179 | uint64_t m[16]; 180 | uint64_t v[16]; 181 | size_t i; 182 | 183 | for( i = 0; i < 16; ++i ) { 184 | m[i] = load64( block + i * sizeof( m[i] ) ); 185 | } 186 | 187 | for( i = 0; i < 8; ++i ) { 188 | v[i] = S->h[i]; 189 | } 190 | 191 | v[ 8] = blake2b_IV[0]; 192 | v[ 9] = blake2b_IV[1]; 193 | v[10] = blake2b_IV[2]; 194 | v[11] = blake2b_IV[3]; 195 | v[12] = blake2b_IV[4] ^ S->t[0]; 196 | v[13] = blake2b_IV[5] ^ S->t[1]; 197 | v[14] = blake2b_IV[6] ^ S->f[0]; 198 | v[15] = blake2b_IV[7] ^ S->f[1]; 199 | 200 | ROUND( 0 ); 201 | ROUND( 1 ); 202 | ROUND( 2 ); 203 | ROUND( 3 ); 204 | ROUND( 4 ); 205 | ROUND( 5 ); 206 | ROUND( 6 ); 207 | ROUND( 7 ); 208 | ROUND( 8 ); 209 | ROUND( 9 ); 210 | ROUND( 10 ); 211 | ROUND( 11 ); 212 | 213 | for( i = 0; i < 8; ++i ) { 214 | S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; 215 | } 216 | } 217 | 218 | #undef G 219 | #undef ROUND 220 | 221 | int blake2b_update( blake2b_state *S, const void *pin, size_t inlen ) 222 | { 223 | const unsigned char * in = (const unsigned char *)pin; 224 | if( inlen > 0 ) 225 | { 226 | size_t left = S->buflen; 227 | size_t fill = BLAKE2B_BLOCKBYTES - left; 228 | if( inlen > fill ) 229 | { 230 | S->buflen = 0; 231 | memcpy( S->buf + left, in, fill ); /* Fill buffer */ 232 | blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); 233 | blake2b_compress( S, S->buf ); /* Compress */ 234 | in += fill; inlen -= fill; 235 | while(inlen > BLAKE2B_BLOCKBYTES) { 236 | blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); 237 | blake2b_compress( S, in ); 238 | in += BLAKE2B_BLOCKBYTES; 239 | inlen -= BLAKE2B_BLOCKBYTES; 240 | } 241 | } 242 | memcpy( S->buf + S->buflen, in, inlen ); 243 | S->buflen += inlen; 244 | } 245 | return 0; 246 | } 247 | 248 | int blake2b_final( blake2b_state *S, void *out, size_t outlen ) 249 | { 250 | uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; 251 | size_t i; 252 | 253 | if( out == NULL || outlen < S->outlen ) 254 | return -1; 255 | 256 | if( blake2b_is_lastblock( S ) ) 257 | return -1; 258 | 259 | blake2b_increment_counter( S, S->buflen ); 260 | blake2b_set_lastblock( S ); 261 | memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ 262 | blake2b_compress( S, S->buf ); 263 | 264 | for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ 265 | store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); 266 | 267 | memcpy( out, buffer, S->outlen ); 268 | secure_zero_memory(buffer, sizeof(buffer)); 269 | return 0; 270 | } 271 | 272 | /* inlen, at least, should be uint64_t. Others can be size_t. */ 273 | int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) 274 | { 275 | blake2b_state S[1]; 276 | 277 | /* Verify parameters */ 278 | if ( NULL == in && inlen > 0 ) return -1; 279 | 280 | if ( NULL == out ) return -1; 281 | 282 | if( NULL == key && keylen > 0 ) return -1; 283 | 284 | if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; 285 | 286 | if( keylen > BLAKE2B_KEYBYTES ) return -1; 287 | 288 | if( keylen > 0 ) 289 | { 290 | if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; 291 | } 292 | else 293 | { 294 | if( blake2b_init( S, outlen ) < 0 ) return -1; 295 | } 296 | 297 | blake2b_update( S, ( const uint8_t * )in, inlen ); 298 | blake2b_final( S, out, outlen ); 299 | return 0; 300 | } 301 | 302 | int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { 303 | return blake2b(out, outlen, in, inlen, key, keylen); 304 | } 305 | 306 | #if defined(SUPERCOP) 307 | int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) 308 | { 309 | return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 ); 310 | } 311 | #endif 312 | 313 | #if defined(BLAKE2B_SELFTEST) 314 | #include 315 | #include "blake2-kat.h" 316 | int main( void ) 317 | { 318 | uint8_t key[BLAKE2B_KEYBYTES]; 319 | uint8_t buf[BLAKE2_KAT_LENGTH]; 320 | size_t i, step; 321 | 322 | for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) 323 | key[i] = ( uint8_t )i; 324 | 325 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 326 | buf[i] = ( uint8_t )i; 327 | 328 | /* Test simple API */ 329 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 330 | { 331 | uint8_t hash[BLAKE2B_OUTBYTES]; 332 | blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES ); 333 | 334 | if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) 335 | { 336 | goto fail; 337 | } 338 | } 339 | 340 | /* Test streaming API */ 341 | for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) { 342 | for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { 343 | uint8_t hash[BLAKE2B_OUTBYTES]; 344 | blake2b_state S; 345 | uint8_t * p = buf; 346 | size_t mlen = i; 347 | int err = 0; 348 | 349 | if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) { 350 | goto fail; 351 | } 352 | 353 | while (mlen >= step) { 354 | if ( (err = blake2b_update(&S, p, step)) < 0 ) { 355 | goto fail; 356 | } 357 | mlen -= step; 358 | p += step; 359 | } 360 | if ( (err = blake2b_update(&S, p, mlen)) < 0) { 361 | goto fail; 362 | } 363 | if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) { 364 | goto fail; 365 | } 366 | 367 | if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) { 368 | goto fail; 369 | } 370 | } 371 | } 372 | 373 | puts( "ok" ); 374 | return 0; 375 | fail: 376 | puts("error"); 377 | return -1; 378 | } 379 | #endif 380 | -------------------------------------------------------------------------------- /cbits/ref/blake2bp-ref.c: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - reference C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #if defined(_OPENMP) 22 | #include 23 | #endif 24 | 25 | #include "blake2.h" 26 | #include "blake2-impl.h" 27 | 28 | #define PARALLELISM_DEGREE 4 29 | 30 | /* 31 | blake2b_init_param defaults to setting the expecting output length 32 | from the digest_length parameter block field. 33 | 34 | In some cases, however, we do not want this, as the output length 35 | of these instances is given by inner_length instead. 36 | */ 37 | static int blake2bp_init_leaf_param( blake2b_state *S, const blake2b_param *P ) 38 | { 39 | int err = blake2b_init_param(S, P); 40 | S->outlen = P->inner_length; 41 | return err; 42 | } 43 | 44 | static int blake2bp_init_leaf( blake2b_state *S, size_t outlen, size_t keylen, uint64_t offset ) 45 | { 46 | blake2b_param P[1]; 47 | P->digest_length = (uint8_t)outlen; 48 | P->key_length = (uint8_t)keylen; 49 | P->fanout = PARALLELISM_DEGREE; 50 | P->depth = 2; 51 | store32( &P->leaf_length, 0 ); 52 | store32( &P->node_offset, offset ); 53 | store32( &P->xof_length, 0 ); 54 | P->node_depth = 0; 55 | P->inner_length = BLAKE2B_OUTBYTES; 56 | memset( P->reserved, 0, sizeof( P->reserved ) ); 57 | memset( P->salt, 0, sizeof( P->salt ) ); 58 | memset( P->personal, 0, sizeof( P->personal ) ); 59 | return blake2bp_init_leaf_param( S, P ); 60 | } 61 | 62 | static int blake2bp_init_root( blake2b_state *S, size_t outlen, size_t keylen ) 63 | { 64 | blake2b_param P[1]; 65 | P->digest_length = (uint8_t)outlen; 66 | P->key_length = (uint8_t)keylen; 67 | P->fanout = PARALLELISM_DEGREE; 68 | P->depth = 2; 69 | store32( &P->leaf_length, 0 ); 70 | store32( &P->node_offset, 0 ); 71 | store32( &P->xof_length, 0 ); 72 | P->node_depth = 1; 73 | P->inner_length = BLAKE2B_OUTBYTES; 74 | memset( P->reserved, 0, sizeof( P->reserved ) ); 75 | memset( P->salt, 0, sizeof( P->salt ) ); 76 | memset( P->personal, 0, sizeof( P->personal ) ); 77 | return blake2b_init_param( S, P ); 78 | } 79 | 80 | 81 | int blake2bp_init( blake2bp_state *S, size_t outlen ) 82 | { 83 | size_t i; 84 | 85 | if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; 86 | 87 | memset( S->buf, 0, sizeof( S->buf ) ); 88 | S->buflen = 0; 89 | S->outlen = outlen; 90 | 91 | if( blake2bp_init_root( S->R, outlen, 0 ) < 0 ) 92 | return -1; 93 | 94 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 95 | if( blake2bp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1; 96 | 97 | S->R->last_node = 1; 98 | S->S[PARALLELISM_DEGREE - 1]->last_node = 1; 99 | return 0; 100 | } 101 | 102 | int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ) 103 | { 104 | size_t i; 105 | 106 | if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; 107 | 108 | if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; 109 | 110 | memset( S->buf, 0, sizeof( S->buf ) ); 111 | S->buflen = 0; 112 | S->outlen = outlen; 113 | 114 | if( blake2bp_init_root( S->R, outlen, keylen ) < 0 ) 115 | return -1; 116 | 117 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 118 | if( blake2bp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1; 119 | 120 | S->R->last_node = 1; 121 | S->S[PARALLELISM_DEGREE - 1]->last_node = 1; 122 | { 123 | uint8_t block[BLAKE2B_BLOCKBYTES]; 124 | memset( block, 0, BLAKE2B_BLOCKBYTES ); 125 | memcpy( block, key, keylen ); 126 | 127 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 128 | blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES ); 129 | 130 | secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ 131 | } 132 | return 0; 133 | } 134 | 135 | 136 | int blake2bp_update( blake2bp_state *S, const void *pin, size_t inlen ) 137 | { 138 | const unsigned char * in = (const unsigned char *)pin; 139 | size_t left = S->buflen; 140 | size_t fill = sizeof( S->buf ) - left; 141 | size_t i; 142 | 143 | if( left && inlen >= fill ) 144 | { 145 | memcpy( S->buf + left, in, fill ); 146 | 147 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 148 | blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); 149 | 150 | in += fill; 151 | inlen -= fill; 152 | left = 0; 153 | } 154 | 155 | #if defined(_OPENMP) 156 | #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE) 157 | #else 158 | 159 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 160 | #endif 161 | { 162 | #if defined(_OPENMP) 163 | size_t i = omp_get_thread_num(); 164 | #endif 165 | size_t inlen__ = inlen; 166 | const unsigned char *in__ = ( const unsigned char * )in; 167 | in__ += i * BLAKE2B_BLOCKBYTES; 168 | 169 | while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) 170 | { 171 | blake2b_update( S->S[i], in__, BLAKE2B_BLOCKBYTES ); 172 | in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; 173 | inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; 174 | } 175 | } 176 | 177 | in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ); 178 | inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; 179 | 180 | if( inlen > 0 ) 181 | memcpy( S->buf + left, in, inlen ); 182 | 183 | S->buflen = left + inlen; 184 | return 0; 185 | } 186 | 187 | int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ) 188 | { 189 | uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; 190 | size_t i; 191 | 192 | if(out == NULL || outlen < S->outlen) { 193 | return -1; 194 | } 195 | 196 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 197 | { 198 | if( S->buflen > i * BLAKE2B_BLOCKBYTES ) 199 | { 200 | size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES; 201 | 202 | if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES; 203 | 204 | blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left ); 205 | } 206 | 207 | blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES ); 208 | } 209 | 210 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 211 | blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES ); 212 | 213 | return blake2b_final( S->R, out, S->outlen ); 214 | } 215 | 216 | int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) 217 | { 218 | uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; 219 | blake2b_state S[PARALLELISM_DEGREE][1]; 220 | blake2b_state FS[1]; 221 | size_t i; 222 | 223 | /* Verify parameters */ 224 | if ( NULL == in && inlen > 0 ) return -1; 225 | 226 | if ( NULL == out ) return -1; 227 | 228 | if( NULL == key && keylen > 0 ) return -1; 229 | 230 | if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; 231 | 232 | if( keylen > BLAKE2B_KEYBYTES ) return -1; 233 | 234 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 235 | if( blake2bp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1; 236 | 237 | S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */ 238 | 239 | if( keylen > 0 ) 240 | { 241 | uint8_t block[BLAKE2B_BLOCKBYTES]; 242 | memset( block, 0, BLAKE2B_BLOCKBYTES ); 243 | memcpy( block, key, keylen ); 244 | 245 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 246 | blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); 247 | 248 | secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ 249 | } 250 | 251 | #if defined(_OPENMP) 252 | #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) 253 | #else 254 | 255 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 256 | #endif 257 | { 258 | #if defined(_OPENMP) 259 | size_t i = omp_get_thread_num(); 260 | #endif 261 | size_t inlen__ = inlen; 262 | const unsigned char *in__ = ( const unsigned char * )in; 263 | in__ += i * BLAKE2B_BLOCKBYTES; 264 | 265 | while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) 266 | { 267 | blake2b_update( S[i], in__, BLAKE2B_BLOCKBYTES ); 268 | in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; 269 | inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; 270 | } 271 | 272 | if( inlen__ > i * BLAKE2B_BLOCKBYTES ) 273 | { 274 | const size_t left = inlen__ - i * BLAKE2B_BLOCKBYTES; 275 | const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES; 276 | blake2b_update( S[i], in__, len ); 277 | } 278 | 279 | blake2b_final( S[i], hash[i], BLAKE2B_OUTBYTES ); 280 | } 281 | 282 | if( blake2bp_init_root( FS, outlen, keylen ) < 0 ) 283 | return -1; 284 | 285 | FS->last_node = 1; /* Mark as last node */ 286 | 287 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 288 | blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); 289 | 290 | return blake2b_final( FS, out, outlen );; 291 | } 292 | 293 | #if defined(BLAKE2BP_SELFTEST) 294 | #include 295 | #include "blake2-kat.h" 296 | int main( void ) 297 | { 298 | uint8_t key[BLAKE2B_KEYBYTES]; 299 | uint8_t buf[BLAKE2_KAT_LENGTH]; 300 | size_t i, step; 301 | 302 | for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) 303 | key[i] = ( uint8_t )i; 304 | 305 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 306 | buf[i] = ( uint8_t )i; 307 | 308 | /* Test simple API */ 309 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 310 | { 311 | uint8_t hash[BLAKE2B_OUTBYTES]; 312 | blake2bp( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES ); 313 | 314 | if( 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) ) 315 | { 316 | goto fail; 317 | } 318 | } 319 | 320 | /* Test streaming API */ 321 | for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) { 322 | for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { 323 | uint8_t hash[BLAKE2B_OUTBYTES]; 324 | blake2bp_state S; 325 | uint8_t * p = buf; 326 | size_t mlen = i; 327 | int err = 0; 328 | 329 | if( (err = blake2bp_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) { 330 | goto fail; 331 | } 332 | 333 | while (mlen >= step) { 334 | if ( (err = blake2bp_update(&S, p, step)) < 0 ) { 335 | goto fail; 336 | } 337 | mlen -= step; 338 | p += step; 339 | } 340 | if ( (err = blake2bp_update(&S, p, mlen)) < 0) { 341 | goto fail; 342 | } 343 | if ( (err = blake2bp_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) { 344 | goto fail; 345 | } 346 | 347 | if (0 != memcmp(hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES)) { 348 | goto fail; 349 | } 350 | } 351 | } 352 | 353 | puts( "ok" ); 354 | return 0; 355 | fail: 356 | puts("error"); 357 | return -1; 358 | } 359 | #endif 360 | -------------------------------------------------------------------------------- /cbits/ref/blake2s-ref.c: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - reference C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "blake2.h" 21 | #include "blake2-impl.h" 22 | 23 | static const uint32_t blake2s_IV[8] = 24 | { 25 | 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, 26 | 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL 27 | }; 28 | 29 | static const uint8_t blake2s_sigma[10][16] = 30 | { 31 | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , 32 | { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , 33 | { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , 34 | { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , 35 | { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , 36 | { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , 37 | { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , 38 | { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , 39 | { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , 40 | { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , 41 | }; 42 | 43 | static void blake2s_set_lastnode( blake2s_state *S ) 44 | { 45 | S->f[1] = (uint32_t)-1; 46 | } 47 | 48 | /* Some helper functions, not necessarily useful */ 49 | static int blake2s_is_lastblock( const blake2s_state *S ) 50 | { 51 | return S->f[0] != 0; 52 | } 53 | 54 | static void blake2s_set_lastblock( blake2s_state *S ) 55 | { 56 | if( S->last_node ) blake2s_set_lastnode( S ); 57 | 58 | S->f[0] = (uint32_t)-1; 59 | } 60 | 61 | static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) 62 | { 63 | S->t[0] += inc; 64 | S->t[1] += ( S->t[0] < inc ); 65 | } 66 | 67 | static void blake2s_init0( blake2s_state *S ) 68 | { 69 | size_t i; 70 | memset( S, 0, sizeof( blake2s_state ) ); 71 | 72 | for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; 73 | } 74 | 75 | /* init2 xors IV with input parameter block */ 76 | int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) 77 | { 78 | const unsigned char *p = ( const unsigned char * )( P ); 79 | size_t i; 80 | 81 | blake2s_init0( S ); 82 | 83 | /* IV XOR ParamBlock */ 84 | for( i = 0; i < 8; ++i ) 85 | S->h[i] ^= load32( &p[i * 4] ); 86 | 87 | S->outlen = P->digest_length; 88 | return 0; 89 | } 90 | 91 | 92 | /* Sequential blake2s initialization */ 93 | int blake2s_init( blake2s_state *S, size_t outlen ) 94 | { 95 | blake2s_param P[1]; 96 | 97 | /* Move interval verification here? */ 98 | if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; 99 | 100 | P->digest_length = (uint8_t)outlen; 101 | P->key_length = 0; 102 | P->fanout = 1; 103 | P->depth = 1; 104 | store32( &P->leaf_length, 0 ); 105 | store32( &P->node_offset, 0 ); 106 | store16( &P->xof_length, 0 ); 107 | P->node_depth = 0; 108 | P->inner_length = 0; 109 | /* memset(P->reserved, 0, sizeof(P->reserved) ); */ 110 | memset( P->salt, 0, sizeof( P->salt ) ); 111 | memset( P->personal, 0, sizeof( P->personal ) ); 112 | return blake2s_init_param( S, P ); 113 | } 114 | 115 | int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) 116 | { 117 | blake2s_param P[1]; 118 | 119 | if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; 120 | 121 | if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; 122 | 123 | P->digest_length = (uint8_t)outlen; 124 | P->key_length = (uint8_t)keylen; 125 | P->fanout = 1; 126 | P->depth = 1; 127 | store32( &P->leaf_length, 0 ); 128 | store32( &P->node_offset, 0 ); 129 | store16( &P->xof_length, 0 ); 130 | P->node_depth = 0; 131 | P->inner_length = 0; 132 | /* memset(P->reserved, 0, sizeof(P->reserved) ); */ 133 | memset( P->salt, 0, sizeof( P->salt ) ); 134 | memset( P->personal, 0, sizeof( P->personal ) ); 135 | 136 | if( blake2s_init_param( S, P ) < 0 ) return -1; 137 | 138 | { 139 | uint8_t block[BLAKE2S_BLOCKBYTES]; 140 | memset( block, 0, BLAKE2S_BLOCKBYTES ); 141 | memcpy( block, key, keylen ); 142 | blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); 143 | secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ 144 | } 145 | return 0; 146 | } 147 | 148 | #define G(r,i,a,b,c,d) \ 149 | do { \ 150 | a = a + b + m[blake2s_sigma[r][2*i+0]]; \ 151 | d = rotr32(d ^ a, 16); \ 152 | c = c + d; \ 153 | b = rotr32(b ^ c, 12); \ 154 | a = a + b + m[blake2s_sigma[r][2*i+1]]; \ 155 | d = rotr32(d ^ a, 8); \ 156 | c = c + d; \ 157 | b = rotr32(b ^ c, 7); \ 158 | } while(0) 159 | 160 | #define ROUND(r) \ 161 | do { \ 162 | G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ 163 | G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ 164 | G(r,2,v[ 2],v[ 6],v[10],v[14]); \ 165 | G(r,3,v[ 3],v[ 7],v[11],v[15]); \ 166 | G(r,4,v[ 0],v[ 5],v[10],v[15]); \ 167 | G(r,5,v[ 1],v[ 6],v[11],v[12]); \ 168 | G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ 169 | G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ 170 | } while(0) 171 | 172 | static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] ) 173 | { 174 | uint32_t m[16]; 175 | uint32_t v[16]; 176 | size_t i; 177 | 178 | for( i = 0; i < 16; ++i ) { 179 | m[i] = load32( in + i * sizeof( m[i] ) ); 180 | } 181 | 182 | for( i = 0; i < 8; ++i ) { 183 | v[i] = S->h[i]; 184 | } 185 | 186 | v[ 8] = blake2s_IV[0]; 187 | v[ 9] = blake2s_IV[1]; 188 | v[10] = blake2s_IV[2]; 189 | v[11] = blake2s_IV[3]; 190 | v[12] = S->t[0] ^ blake2s_IV[4]; 191 | v[13] = S->t[1] ^ blake2s_IV[5]; 192 | v[14] = S->f[0] ^ blake2s_IV[6]; 193 | v[15] = S->f[1] ^ blake2s_IV[7]; 194 | 195 | ROUND( 0 ); 196 | ROUND( 1 ); 197 | ROUND( 2 ); 198 | ROUND( 3 ); 199 | ROUND( 4 ); 200 | ROUND( 5 ); 201 | ROUND( 6 ); 202 | ROUND( 7 ); 203 | ROUND( 8 ); 204 | ROUND( 9 ); 205 | 206 | for( i = 0; i < 8; ++i ) { 207 | S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; 208 | } 209 | } 210 | 211 | #undef G 212 | #undef ROUND 213 | 214 | int blake2s_update( blake2s_state *S, const void *pin, size_t inlen ) 215 | { 216 | const unsigned char * in = (const unsigned char *)pin; 217 | if( inlen > 0 ) 218 | { 219 | size_t left = S->buflen; 220 | size_t fill = BLAKE2S_BLOCKBYTES - left; 221 | if( inlen > fill ) 222 | { 223 | S->buflen = 0; 224 | memcpy( S->buf + left, in, fill ); /* Fill buffer */ 225 | blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); 226 | blake2s_compress( S, S->buf ); /* Compress */ 227 | in += fill; inlen -= fill; 228 | while(inlen > BLAKE2S_BLOCKBYTES) { 229 | blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); 230 | blake2s_compress( S, in ); 231 | in += BLAKE2S_BLOCKBYTES; 232 | inlen -= BLAKE2S_BLOCKBYTES; 233 | } 234 | } 235 | memcpy( S->buf + S->buflen, in, inlen ); 236 | S->buflen += inlen; 237 | } 238 | return 0; 239 | } 240 | 241 | int blake2s_final( blake2s_state *S, void *out, size_t outlen ) 242 | { 243 | uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; 244 | size_t i; 245 | 246 | if( out == NULL || outlen < S->outlen ) 247 | return -1; 248 | 249 | if( blake2s_is_lastblock( S ) ) 250 | return -1; 251 | 252 | blake2s_increment_counter( S, ( uint32_t )S->buflen ); 253 | blake2s_set_lastblock( S ); 254 | memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ 255 | blake2s_compress( S, S->buf ); 256 | 257 | for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ 258 | store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); 259 | 260 | memcpy( out, buffer, outlen ); 261 | secure_zero_memory(buffer, sizeof(buffer)); 262 | return 0; 263 | } 264 | 265 | int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) 266 | { 267 | blake2s_state S[1]; 268 | 269 | /* Verify parameters */ 270 | if ( NULL == in && inlen > 0 ) return -1; 271 | 272 | if ( NULL == out ) return -1; 273 | 274 | if ( NULL == key && keylen > 0) return -1; 275 | 276 | if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; 277 | 278 | if( keylen > BLAKE2S_KEYBYTES ) return -1; 279 | 280 | if( keylen > 0 ) 281 | { 282 | if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; 283 | } 284 | else 285 | { 286 | if( blake2s_init( S, outlen ) < 0 ) return -1; 287 | } 288 | 289 | blake2s_update( S, ( const uint8_t * )in, inlen ); 290 | blake2s_final( S, out, outlen ); 291 | return 0; 292 | } 293 | 294 | #if defined(SUPERCOP) 295 | int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) 296 | { 297 | return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 ); 298 | } 299 | #endif 300 | 301 | #if defined(BLAKE2S_SELFTEST) 302 | #include 303 | #include "blake2-kat.h" 304 | int main( void ) 305 | { 306 | uint8_t key[BLAKE2S_KEYBYTES]; 307 | uint8_t buf[BLAKE2_KAT_LENGTH]; 308 | size_t i, step; 309 | 310 | for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) 311 | key[i] = ( uint8_t )i; 312 | 313 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 314 | buf[i] = ( uint8_t )i; 315 | 316 | /* Test simple API */ 317 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 318 | { 319 | uint8_t hash[BLAKE2S_OUTBYTES]; 320 | blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); 321 | 322 | if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) 323 | { 324 | goto fail; 325 | } 326 | } 327 | 328 | /* Test streaming API */ 329 | for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { 330 | for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { 331 | uint8_t hash[BLAKE2S_OUTBYTES]; 332 | blake2s_state S; 333 | uint8_t * p = buf; 334 | size_t mlen = i; 335 | int err = 0; 336 | 337 | if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { 338 | goto fail; 339 | } 340 | 341 | while (mlen >= step) { 342 | if ( (err = blake2s_update(&S, p, step)) < 0 ) { 343 | goto fail; 344 | } 345 | mlen -= step; 346 | p += step; 347 | } 348 | if ( (err = blake2s_update(&S, p, mlen)) < 0) { 349 | goto fail; 350 | } 351 | if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { 352 | goto fail; 353 | } 354 | 355 | if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) { 356 | goto fail; 357 | } 358 | } 359 | } 360 | 361 | puts( "ok" ); 362 | return 0; 363 | fail: 364 | puts("error"); 365 | return -1; 366 | } 367 | #endif 368 | -------------------------------------------------------------------------------- /cbits/ref/blake2sp-ref.c: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - reference C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #if defined(_OPENMP) 21 | #include 22 | #endif 23 | 24 | #include "blake2.h" 25 | #include "blake2-impl.h" 26 | 27 | #define PARALLELISM_DEGREE 8 28 | 29 | /* 30 | blake2sp_init_param defaults to setting the expecting output length 31 | from the digest_length parameter block field. 32 | 33 | In some cases, however, we do not want this, as the output length 34 | of these instances is given by inner_length instead. 35 | */ 36 | static int blake2sp_init_leaf_param( blake2s_state *S, const blake2s_param *P ) 37 | { 38 | int err = blake2s_init_param(S, P); 39 | S->outlen = P->inner_length; 40 | return err; 41 | } 42 | 43 | static int blake2sp_init_leaf( blake2s_state *S, size_t outlen, size_t keylen, uint64_t offset ) 44 | { 45 | blake2s_param P[1]; 46 | P->digest_length = (uint8_t)outlen; 47 | P->key_length = (uint8_t)keylen; 48 | P->fanout = PARALLELISM_DEGREE; 49 | P->depth = 2; 50 | store32( &P->leaf_length, 0 ); 51 | store32( &P->node_offset, offset ); 52 | store16( &P->xof_length, 0 ); 53 | P->node_depth = 0; 54 | P->inner_length = BLAKE2S_OUTBYTES; 55 | memset( P->salt, 0, sizeof( P->salt ) ); 56 | memset( P->personal, 0, sizeof( P->personal ) ); 57 | return blake2sp_init_leaf_param( S, P ); 58 | } 59 | 60 | static int blake2sp_init_root( blake2s_state *S, size_t outlen, size_t keylen ) 61 | { 62 | blake2s_param P[1]; 63 | P->digest_length = (uint8_t)outlen; 64 | P->key_length = (uint8_t)keylen; 65 | P->fanout = PARALLELISM_DEGREE; 66 | P->depth = 2; 67 | store32( &P->leaf_length, 0 ); 68 | store32( &P->node_offset, 0 ); 69 | store16( &P->xof_length, 0 ); 70 | P->node_depth = 1; 71 | P->inner_length = BLAKE2S_OUTBYTES; 72 | memset( P->salt, 0, sizeof( P->salt ) ); 73 | memset( P->personal, 0, sizeof( P->personal ) ); 74 | return blake2s_init_param( S, P ); 75 | } 76 | 77 | 78 | int blake2sp_init( blake2sp_state *S, size_t outlen ) 79 | { 80 | size_t i; 81 | 82 | if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; 83 | 84 | memset( S->buf, 0, sizeof( S->buf ) ); 85 | S->buflen = 0; 86 | S->outlen = outlen; 87 | 88 | if( blake2sp_init_root( S->R, outlen, 0 ) < 0 ) 89 | return -1; 90 | 91 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 92 | if( blake2sp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1; 93 | 94 | S->R->last_node = 1; 95 | S->S[PARALLELISM_DEGREE - 1]->last_node = 1; 96 | return 0; 97 | } 98 | 99 | int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ) 100 | { 101 | size_t i; 102 | 103 | if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; 104 | 105 | if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; 106 | 107 | memset( S->buf, 0, sizeof( S->buf ) ); 108 | S->buflen = 0; 109 | S->outlen = outlen; 110 | 111 | if( blake2sp_init_root( S->R, outlen, keylen ) < 0 ) 112 | return -1; 113 | 114 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 115 | if( blake2sp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1; 116 | 117 | S->R->last_node = 1; 118 | S->S[PARALLELISM_DEGREE - 1]->last_node = 1; 119 | { 120 | uint8_t block[BLAKE2S_BLOCKBYTES]; 121 | memset( block, 0, BLAKE2S_BLOCKBYTES ); 122 | memcpy( block, key, keylen ); 123 | 124 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 125 | blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES ); 126 | 127 | secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ 128 | } 129 | return 0; 130 | } 131 | 132 | 133 | int blake2sp_update( blake2sp_state *S, const void *pin, size_t inlen ) 134 | { 135 | const unsigned char * in = (const unsigned char *)pin; 136 | size_t left = S->buflen; 137 | size_t fill = sizeof( S->buf ) - left; 138 | size_t i; 139 | 140 | if( left && inlen >= fill ) 141 | { 142 | memcpy( S->buf + left, in, fill ); 143 | 144 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 145 | blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); 146 | 147 | in += fill; 148 | inlen -= fill; 149 | left = 0; 150 | } 151 | 152 | #if defined(_OPENMP) 153 | #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE) 154 | #else 155 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 156 | #endif 157 | { 158 | #if defined(_OPENMP) 159 | size_t i = omp_get_thread_num(); 160 | #endif 161 | size_t inlen__ = inlen; 162 | const unsigned char *in__ = ( const unsigned char * )in; 163 | in__ += i * BLAKE2S_BLOCKBYTES; 164 | 165 | while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) 166 | { 167 | blake2s_update( S->S[i], in__, BLAKE2S_BLOCKBYTES ); 168 | in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; 169 | inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; 170 | } 171 | } 172 | 173 | in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ); 174 | inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; 175 | 176 | if( inlen > 0 ) 177 | memcpy( S->buf + left, in, inlen ); 178 | 179 | S->buflen = left + inlen; 180 | return 0; 181 | } 182 | 183 | 184 | int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ) 185 | { 186 | uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; 187 | size_t i; 188 | 189 | if(out == NULL || outlen < S->outlen) { 190 | return -1; 191 | } 192 | 193 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 194 | { 195 | if( S->buflen > i * BLAKE2S_BLOCKBYTES ) 196 | { 197 | size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES; 198 | 199 | if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES; 200 | 201 | blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left ); 202 | } 203 | 204 | blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES ); 205 | } 206 | 207 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 208 | blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES ); 209 | 210 | return blake2s_final( S->R, out, S->outlen ); 211 | } 212 | 213 | 214 | int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) 215 | { 216 | uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; 217 | blake2s_state S[PARALLELISM_DEGREE][1]; 218 | blake2s_state FS[1]; 219 | size_t i; 220 | 221 | /* Verify parameters */ 222 | if ( NULL == in && inlen > 0 ) return -1; 223 | 224 | if ( NULL == out ) return -1; 225 | 226 | if ( NULL == key && keylen > 0) return -1; 227 | 228 | if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; 229 | 230 | if( keylen > BLAKE2S_KEYBYTES ) return -1; 231 | 232 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 233 | if( blake2sp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1; 234 | 235 | S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */ 236 | 237 | if( keylen > 0 ) 238 | { 239 | uint8_t block[BLAKE2S_BLOCKBYTES]; 240 | memset( block, 0, BLAKE2S_BLOCKBYTES ); 241 | memcpy( block, key, keylen ); 242 | 243 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 244 | blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES ); 245 | 246 | secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ 247 | } 248 | 249 | #if defined(_OPENMP) 250 | #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) 251 | #else 252 | 253 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 254 | #endif 255 | { 256 | #if defined(_OPENMP) 257 | size_t i = omp_get_thread_num(); 258 | #endif 259 | size_t inlen__ = inlen; 260 | const unsigned char *in__ = ( const unsigned char * )in; 261 | in__ += i * BLAKE2S_BLOCKBYTES; 262 | 263 | while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) 264 | { 265 | blake2s_update( S[i], in__, BLAKE2S_BLOCKBYTES ); 266 | in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; 267 | inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; 268 | } 269 | 270 | if( inlen__ > i * BLAKE2S_BLOCKBYTES ) 271 | { 272 | const size_t left = inlen__ - i * BLAKE2S_BLOCKBYTES; 273 | const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES; 274 | blake2s_update( S[i], in__, len ); 275 | } 276 | 277 | blake2s_final( S[i], hash[i], BLAKE2S_OUTBYTES ); 278 | } 279 | 280 | if( blake2sp_init_root( FS, outlen, keylen ) < 0 ) 281 | return -1; 282 | 283 | FS->last_node = 1; 284 | 285 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 286 | blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES ); 287 | 288 | return blake2s_final( FS, out, outlen ); 289 | } 290 | 291 | 292 | 293 | #if defined(BLAKE2SP_SELFTEST) 294 | #include 295 | #include "blake2-kat.h" 296 | int main( void ) 297 | { 298 | uint8_t key[BLAKE2S_KEYBYTES]; 299 | uint8_t buf[BLAKE2_KAT_LENGTH]; 300 | size_t i, step; 301 | 302 | for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) 303 | key[i] = ( uint8_t )i; 304 | 305 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 306 | buf[i] = ( uint8_t )i; 307 | 308 | /* Test simple API */ 309 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 310 | { 311 | uint8_t hash[BLAKE2S_OUTBYTES]; 312 | blake2sp( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); 313 | 314 | if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) ) 315 | { 316 | goto fail; 317 | } 318 | } 319 | 320 | /* Test streaming API */ 321 | for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { 322 | for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { 323 | uint8_t hash[BLAKE2S_OUTBYTES]; 324 | blake2sp_state S; 325 | uint8_t * p = buf; 326 | size_t mlen = i; 327 | int err = 0; 328 | 329 | if( (err = blake2sp_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { 330 | goto fail; 331 | } 332 | 333 | while (mlen >= step) { 334 | if ( (err = blake2sp_update(&S, p, step)) < 0 ) { 335 | goto fail; 336 | } 337 | mlen -= step; 338 | p += step; 339 | } 340 | if ( (err = blake2sp_update(&S, p, mlen)) < 0) { 341 | goto fail; 342 | } 343 | if ( (err = blake2sp_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { 344 | goto fail; 345 | } 346 | 347 | if (0 != memcmp(hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES)) { 348 | goto fail; 349 | } 350 | } 351 | } 352 | 353 | puts( "ok" ); 354 | return 0; 355 | fail: 356 | puts("error"); 357 | return -1; 358 | } 359 | #endif 360 | -------------------------------------------------------------------------------- /cbits/sse/blake2b.c: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - optimized C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "blake2.h" 21 | #include "blake2-impl.h" 22 | 23 | #include "blake2-config.h" 24 | 25 | #ifdef _MSC_VER 26 | #include /* for _mm_set_epi64x */ 27 | #endif 28 | #include 29 | #if defined(HAVE_SSSE3) 30 | #include 31 | #endif 32 | #if defined(HAVE_SSE41) 33 | #include 34 | #endif 35 | #if defined(HAVE_AVX) 36 | #include 37 | #endif 38 | #if defined(HAVE_XOP) 39 | #include 40 | #endif 41 | 42 | #include "blake2b-round.h" 43 | 44 | static const uint64_t blake2b_IV[8] = 45 | { 46 | 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 47 | 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 48 | 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 49 | 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL 50 | }; 51 | 52 | /* Some helper functions */ 53 | static void blake2b_set_lastnode( blake2b_state *S ) 54 | { 55 | S->f[1] = (uint64_t)-1; 56 | } 57 | 58 | static int blake2b_is_lastblock( const blake2b_state *S ) 59 | { 60 | return S->f[0] != 0; 61 | } 62 | 63 | static void blake2b_set_lastblock( blake2b_state *S ) 64 | { 65 | if( S->last_node ) blake2b_set_lastnode( S ); 66 | 67 | S->f[0] = (uint64_t)-1; 68 | } 69 | 70 | static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) 71 | { 72 | S->t[0] += inc; 73 | S->t[1] += ( S->t[0] < inc ); 74 | } 75 | 76 | /* init xors IV with input parameter block */ 77 | int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) 78 | { 79 | size_t i; 80 | /*blake2b_init0( S ); */ 81 | const unsigned char * v = ( const unsigned char * )( blake2b_IV ); 82 | const unsigned char * p = ( const unsigned char * )( P ); 83 | unsigned char * h = ( unsigned char * )( S->h ); 84 | /* IV XOR ParamBlock */ 85 | memset( S, 0, sizeof( blake2b_state ) ); 86 | 87 | for( i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; 88 | 89 | S->outlen = P->digest_length; 90 | return 0; 91 | } 92 | 93 | 94 | /* Some sort of default parameter block initialization, for sequential blake2b */ 95 | int blake2b_init( blake2b_state *S, size_t outlen ) 96 | { 97 | blake2b_param P[1]; 98 | 99 | if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; 100 | 101 | P->digest_length = (uint8_t)outlen; 102 | P->key_length = 0; 103 | P->fanout = 1; 104 | P->depth = 1; 105 | store32( &P->leaf_length, 0 ); 106 | store32( &P->node_offset, 0 ); 107 | store32( &P->xof_length, 0 ); 108 | P->node_depth = 0; 109 | P->inner_length = 0; 110 | memset( P->reserved, 0, sizeof( P->reserved ) ); 111 | memset( P->salt, 0, sizeof( P->salt ) ); 112 | memset( P->personal, 0, sizeof( P->personal ) ); 113 | 114 | return blake2b_init_param( S, P ); 115 | } 116 | 117 | int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) 118 | { 119 | blake2b_param P[1]; 120 | 121 | if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; 122 | 123 | if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1; 124 | 125 | P->digest_length = (uint8_t)outlen; 126 | P->key_length = (uint8_t)keylen; 127 | P->fanout = 1; 128 | P->depth = 1; 129 | store32( &P->leaf_length, 0 ); 130 | store32( &P->node_offset, 0 ); 131 | store32( &P->xof_length, 0 ); 132 | P->node_depth = 0; 133 | P->inner_length = 0; 134 | memset( P->reserved, 0, sizeof( P->reserved ) ); 135 | memset( P->salt, 0, sizeof( P->salt ) ); 136 | memset( P->personal, 0, sizeof( P->personal ) ); 137 | 138 | if( blake2b_init_param( S, P ) < 0 ) 139 | return 0; 140 | 141 | { 142 | uint8_t block[BLAKE2B_BLOCKBYTES]; 143 | memset( block, 0, BLAKE2B_BLOCKBYTES ); 144 | memcpy( block, key, keylen ); 145 | blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); 146 | secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ 147 | } 148 | return 0; 149 | } 150 | 151 | static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) 152 | { 153 | __m128i row1l, row1h; 154 | __m128i row2l, row2h; 155 | __m128i row3l, row3h; 156 | __m128i row4l, row4h; 157 | __m128i b0, b1; 158 | __m128i t0, t1; 159 | #if defined(HAVE_SSSE3) && !defined(HAVE_XOP) 160 | const __m128i r16 = _mm_setr_epi8( 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9 ); 161 | const __m128i r24 = _mm_setr_epi8( 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10 ); 162 | #endif 163 | #if defined(HAVE_SSE41) 164 | const __m128i m0 = LOADU( block + 00 ); 165 | const __m128i m1 = LOADU( block + 16 ); 166 | const __m128i m2 = LOADU( block + 32 ); 167 | const __m128i m3 = LOADU( block + 48 ); 168 | const __m128i m4 = LOADU( block + 64 ); 169 | const __m128i m5 = LOADU( block + 80 ); 170 | const __m128i m6 = LOADU( block + 96 ); 171 | const __m128i m7 = LOADU( block + 112 ); 172 | #else 173 | const uint64_t m0 = load64(block + 0 * sizeof(uint64_t)); 174 | const uint64_t m1 = load64(block + 1 * sizeof(uint64_t)); 175 | const uint64_t m2 = load64(block + 2 * sizeof(uint64_t)); 176 | const uint64_t m3 = load64(block + 3 * sizeof(uint64_t)); 177 | const uint64_t m4 = load64(block + 4 * sizeof(uint64_t)); 178 | const uint64_t m5 = load64(block + 5 * sizeof(uint64_t)); 179 | const uint64_t m6 = load64(block + 6 * sizeof(uint64_t)); 180 | const uint64_t m7 = load64(block + 7 * sizeof(uint64_t)); 181 | const uint64_t m8 = load64(block + 8 * sizeof(uint64_t)); 182 | const uint64_t m9 = load64(block + 9 * sizeof(uint64_t)); 183 | const uint64_t m10 = load64(block + 10 * sizeof(uint64_t)); 184 | const uint64_t m11 = load64(block + 11 * sizeof(uint64_t)); 185 | const uint64_t m12 = load64(block + 12 * sizeof(uint64_t)); 186 | const uint64_t m13 = load64(block + 13 * sizeof(uint64_t)); 187 | const uint64_t m14 = load64(block + 14 * sizeof(uint64_t)); 188 | const uint64_t m15 = load64(block + 15 * sizeof(uint64_t)); 189 | #endif 190 | row1l = LOADU( &S->h[0] ); 191 | row1h = LOADU( &S->h[2] ); 192 | row2l = LOADU( &S->h[4] ); 193 | row2h = LOADU( &S->h[6] ); 194 | row3l = LOADU( &blake2b_IV[0] ); 195 | row3h = LOADU( &blake2b_IV[2] ); 196 | row4l = _mm_xor_si128( LOADU( &blake2b_IV[4] ), LOADU( &S->t[0] ) ); 197 | row4h = _mm_xor_si128( LOADU( &blake2b_IV[6] ), LOADU( &S->f[0] ) ); 198 | ROUND( 0 ); 199 | ROUND( 1 ); 200 | ROUND( 2 ); 201 | ROUND( 3 ); 202 | ROUND( 4 ); 203 | ROUND( 5 ); 204 | ROUND( 6 ); 205 | ROUND( 7 ); 206 | ROUND( 8 ); 207 | ROUND( 9 ); 208 | ROUND( 10 ); 209 | ROUND( 11 ); 210 | row1l = _mm_xor_si128( row3l, row1l ); 211 | row1h = _mm_xor_si128( row3h, row1h ); 212 | STOREU( &S->h[0], _mm_xor_si128( LOADU( &S->h[0] ), row1l ) ); 213 | STOREU( &S->h[2], _mm_xor_si128( LOADU( &S->h[2] ), row1h ) ); 214 | row2l = _mm_xor_si128( row4l, row2l ); 215 | row2h = _mm_xor_si128( row4h, row2h ); 216 | STOREU( &S->h[4], _mm_xor_si128( LOADU( &S->h[4] ), row2l ) ); 217 | STOREU( &S->h[6], _mm_xor_si128( LOADU( &S->h[6] ), row2h ) ); 218 | } 219 | 220 | 221 | int blake2b_update( blake2b_state *S, const void *pin, size_t inlen ) 222 | { 223 | const unsigned char * in = (const unsigned char *)pin; 224 | if( inlen > 0 ) 225 | { 226 | size_t left = S->buflen; 227 | size_t fill = BLAKE2B_BLOCKBYTES - left; 228 | if( inlen > fill ) 229 | { 230 | S->buflen = 0; 231 | memcpy( S->buf + left, in, fill ); /* Fill buffer */ 232 | blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); 233 | blake2b_compress( S, S->buf ); /* Compress */ 234 | in += fill; inlen -= fill; 235 | while(inlen > BLAKE2B_BLOCKBYTES) { 236 | blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); 237 | blake2b_compress( S, in ); 238 | in += BLAKE2B_BLOCKBYTES; 239 | inlen -= BLAKE2B_BLOCKBYTES; 240 | } 241 | } 242 | memcpy( S->buf + S->buflen, in, inlen ); 243 | S->buflen += inlen; 244 | } 245 | return 0; 246 | } 247 | 248 | 249 | int blake2b_final( blake2b_state *S, void *out, size_t outlen ) 250 | { 251 | if( out == NULL || outlen < S->outlen ) 252 | return -1; 253 | 254 | if( blake2b_is_lastblock( S ) ) 255 | return -1; 256 | 257 | blake2b_increment_counter( S, S->buflen ); 258 | blake2b_set_lastblock( S ); 259 | memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ 260 | blake2b_compress( S, S->buf ); 261 | 262 | memcpy( out, &S->h[0], S->outlen ); 263 | return 0; 264 | } 265 | 266 | 267 | int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) 268 | { 269 | blake2b_state S[1]; 270 | 271 | /* Verify parameters */ 272 | if ( NULL == in && inlen > 0 ) return -1; 273 | 274 | if ( NULL == out ) return -1; 275 | 276 | if( NULL == key && keylen > 0 ) return -1; 277 | 278 | if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; 279 | 280 | if( keylen > BLAKE2B_KEYBYTES ) return -1; 281 | 282 | if( keylen ) 283 | { 284 | if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; 285 | } 286 | else 287 | { 288 | if( blake2b_init( S, outlen ) < 0 ) return -1; 289 | } 290 | 291 | blake2b_update( S, ( const uint8_t * )in, inlen ); 292 | blake2b_final( S, out, outlen ); 293 | return 0; 294 | } 295 | 296 | int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { 297 | return blake2b(out, outlen, in, inlen, key, keylen); 298 | } 299 | 300 | #if defined(SUPERCOP) 301 | int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) 302 | { 303 | return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 ); 304 | } 305 | #endif 306 | 307 | #if defined(BLAKE2B_SELFTEST) 308 | #include 309 | #include "blake2-kat.h" 310 | int main( void ) 311 | { 312 | uint8_t key[BLAKE2B_KEYBYTES]; 313 | uint8_t buf[BLAKE2_KAT_LENGTH]; 314 | size_t i, step; 315 | 316 | for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) 317 | key[i] = ( uint8_t )i; 318 | 319 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 320 | buf[i] = ( uint8_t )i; 321 | 322 | /* Test simple API */ 323 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 324 | { 325 | uint8_t hash[BLAKE2B_OUTBYTES]; 326 | blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES ); 327 | 328 | if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) 329 | { 330 | goto fail; 331 | } 332 | } 333 | 334 | /* Test streaming API */ 335 | for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) { 336 | for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { 337 | uint8_t hash[BLAKE2B_OUTBYTES]; 338 | blake2b_state S; 339 | uint8_t * p = buf; 340 | size_t mlen = i; 341 | int err = 0; 342 | 343 | if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) { 344 | goto fail; 345 | } 346 | 347 | while (mlen >= step) { 348 | if ( (err = blake2b_update(&S, p, step)) < 0 ) { 349 | goto fail; 350 | } 351 | mlen -= step; 352 | p += step; 353 | } 354 | if ( (err = blake2b_update(&S, p, mlen)) < 0) { 355 | goto fail; 356 | } 357 | if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) { 358 | goto fail; 359 | } 360 | 361 | if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) { 362 | goto fail; 363 | } 364 | } 365 | } 366 | 367 | puts( "ok" ); 368 | return 0; 369 | fail: 370 | puts("error"); 371 | return -1; 372 | } 373 | #endif 374 | -------------------------------------------------------------------------------- /cbits/sse/blake2bp.c: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - optimized C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #if defined(_OPENMP) 22 | #include 23 | #endif 24 | 25 | #include "blake2.h" 26 | #include "blake2-impl.h" 27 | 28 | #define PARALLELISM_DEGREE 4 29 | 30 | /* 31 | blake2b_init_param defaults to setting the expecting output length 32 | from the digest_length parameter block field. 33 | 34 | In some cases, however, we do not want this, as the output length 35 | of these instances is given by inner_length instead. 36 | */ 37 | static int blake2bp_init_leaf_param( blake2b_state *S, const blake2b_param *P ) 38 | { 39 | int err = blake2b_init_param(S, P); 40 | S->outlen = P->inner_length; 41 | return err; 42 | } 43 | 44 | static int blake2bp_init_leaf( blake2b_state *S, size_t outlen, size_t keylen, uint64_t offset ) 45 | { 46 | blake2b_param P[1]; 47 | P->digest_length = (uint8_t)outlen; 48 | P->key_length = (uint8_t)keylen; 49 | P->fanout = PARALLELISM_DEGREE; 50 | P->depth = 2; 51 | P->leaf_length = 0; 52 | P->node_offset = offset; 53 | P->xof_length = 0; 54 | P->node_depth = 0; 55 | P->inner_length = BLAKE2B_OUTBYTES; 56 | memset( P->reserved, 0, sizeof( P->reserved ) ); 57 | memset( P->salt, 0, sizeof( P->salt ) ); 58 | memset( P->personal, 0, sizeof( P->personal ) ); 59 | return blake2bp_init_leaf_param( S, P ); 60 | } 61 | 62 | static int blake2bp_init_root( blake2b_state *S, size_t outlen, size_t keylen ) 63 | { 64 | blake2b_param P[1]; 65 | P->digest_length = (uint8_t)outlen; 66 | P->key_length = (uint8_t)keylen; 67 | P->fanout = PARALLELISM_DEGREE; 68 | P->depth = 2; 69 | P->leaf_length = 0; 70 | P->node_offset = 0; 71 | P->xof_length = 0; 72 | P->node_depth = 1; 73 | P->inner_length = BLAKE2B_OUTBYTES; 74 | memset( P->reserved, 0, sizeof( P->reserved ) ); 75 | memset( P->salt, 0, sizeof( P->salt ) ); 76 | memset( P->personal, 0, sizeof( P->personal ) ); 77 | return blake2b_init_param( S, P ); 78 | } 79 | 80 | 81 | int blake2bp_init( blake2bp_state *S, size_t outlen ) 82 | { 83 | size_t i; 84 | if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; 85 | 86 | memset( S->buf, 0, sizeof( S->buf ) ); 87 | S->buflen = 0; 88 | S->outlen = outlen; 89 | 90 | if( blake2bp_init_root( S->R, outlen, 0 ) < 0 ) 91 | return -1; 92 | 93 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 94 | if( blake2bp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1; 95 | 96 | S->R->last_node = 1; 97 | S->S[PARALLELISM_DEGREE - 1]->last_node = 1; 98 | return 0; 99 | } 100 | 101 | int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ) 102 | { 103 | size_t i; 104 | 105 | if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; 106 | 107 | if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; 108 | 109 | memset( S->buf, 0, sizeof( S->buf ) ); 110 | S->buflen = 0; 111 | S->outlen = outlen; 112 | 113 | if( blake2bp_init_root( S->R, outlen, keylen ) < 0 ) 114 | return -1; 115 | 116 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 117 | if( blake2bp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1; 118 | 119 | S->R->last_node = 1; 120 | S->S[PARALLELISM_DEGREE - 1]->last_node = 1; 121 | { 122 | uint8_t block[BLAKE2B_BLOCKBYTES]; 123 | memset( block, 0, BLAKE2B_BLOCKBYTES ); 124 | memcpy( block, key, keylen ); 125 | 126 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 127 | blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES ); 128 | 129 | secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ 130 | } 131 | return 0; 132 | } 133 | 134 | 135 | int blake2bp_update( blake2bp_state *S, const void *pin, size_t inlen ) 136 | { 137 | const unsigned char * in = (const unsigned char *)pin; 138 | size_t left = S->buflen; 139 | size_t fill = sizeof( S->buf ) - left; 140 | size_t i; 141 | 142 | if( left && inlen >= fill ) 143 | { 144 | memcpy( S->buf + left, in, fill ); 145 | 146 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 147 | blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); 148 | 149 | in += fill; 150 | inlen -= fill; 151 | left = 0; 152 | } 153 | 154 | #if defined(_OPENMP) 155 | #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE) 156 | #else 157 | 158 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 159 | #endif 160 | { 161 | #if defined(_OPENMP) 162 | size_t i = omp_get_thread_num(); 163 | #endif 164 | size_t inlen__ = inlen; 165 | const unsigned char *in__ = ( const unsigned char * )in; 166 | in__ += i * BLAKE2B_BLOCKBYTES; 167 | 168 | while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) 169 | { 170 | blake2b_update( S->S[i], in__, BLAKE2B_BLOCKBYTES ); 171 | in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; 172 | inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; 173 | } 174 | } 175 | 176 | in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ); 177 | inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; 178 | 179 | if( inlen > 0 ) 180 | memcpy( S->buf + left, in, inlen ); 181 | 182 | S->buflen = left + inlen; 183 | return 0; 184 | } 185 | 186 | 187 | 188 | int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ) 189 | { 190 | uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; 191 | size_t i; 192 | 193 | if(out == NULL || outlen < S->outlen) { 194 | return -1; 195 | } 196 | 197 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 198 | { 199 | if( S->buflen > i * BLAKE2B_BLOCKBYTES ) 200 | { 201 | size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES; 202 | 203 | if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES; 204 | 205 | blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left ); 206 | } 207 | 208 | blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES ); 209 | } 210 | 211 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 212 | blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES ); 213 | 214 | return blake2b_final( S->R, out, S->outlen ); 215 | } 216 | 217 | int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) 218 | { 219 | uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; 220 | blake2b_state S[PARALLELISM_DEGREE][1]; 221 | blake2b_state FS[1]; 222 | size_t i; 223 | 224 | /* Verify parameters */ 225 | if ( NULL == in && inlen > 0 ) return -1; 226 | 227 | if ( NULL == out ) return -1; 228 | 229 | if( NULL == key && keylen > 0 ) return -1; 230 | 231 | if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; 232 | 233 | if( keylen > BLAKE2B_KEYBYTES ) return -1; 234 | 235 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 236 | if( blake2bp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1; 237 | 238 | S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */ 239 | 240 | if( keylen > 0 ) 241 | { 242 | uint8_t block[BLAKE2B_BLOCKBYTES]; 243 | memset( block, 0, BLAKE2B_BLOCKBYTES ); 244 | memcpy( block, key, keylen ); 245 | 246 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 247 | blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); 248 | 249 | secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ 250 | } 251 | 252 | #if defined(_OPENMP) 253 | #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) 254 | #else 255 | 256 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 257 | #endif 258 | { 259 | #if defined(_OPENMP) 260 | size_t i = omp_get_thread_num(); 261 | #endif 262 | size_t inlen__ = inlen; 263 | const unsigned char *in__ = ( const unsigned char * )in; 264 | in__ += i * BLAKE2B_BLOCKBYTES; 265 | 266 | while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) 267 | { 268 | blake2b_update( S[i], in__, BLAKE2B_BLOCKBYTES ); 269 | in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; 270 | inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; 271 | } 272 | 273 | if( inlen__ > i * BLAKE2B_BLOCKBYTES ) 274 | { 275 | const size_t left = inlen__ - i * BLAKE2B_BLOCKBYTES; 276 | const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES; 277 | blake2b_update( S[i], in__, len ); 278 | } 279 | 280 | blake2b_final( S[i], hash[i], BLAKE2B_OUTBYTES ); 281 | } 282 | 283 | if( blake2bp_init_root( FS, outlen, keylen ) < 0 ) 284 | return -1; 285 | 286 | FS->last_node = 1; /* Mark as last node */ 287 | 288 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 289 | blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); 290 | 291 | return blake2b_final( FS, out, outlen ); 292 | } 293 | 294 | 295 | #if defined(BLAKE2BP_SELFTEST) 296 | #include 297 | #include "blake2-kat.h" 298 | int main( void ) 299 | { 300 | uint8_t key[BLAKE2B_KEYBYTES]; 301 | uint8_t buf[BLAKE2_KAT_LENGTH]; 302 | size_t i, step; 303 | 304 | for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) 305 | key[i] = ( uint8_t )i; 306 | 307 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 308 | buf[i] = ( uint8_t )i; 309 | 310 | /* Test simple API */ 311 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 312 | { 313 | uint8_t hash[BLAKE2B_OUTBYTES]; 314 | blake2bp( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES ); 315 | 316 | if( 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) ) 317 | { 318 | goto fail; 319 | } 320 | } 321 | 322 | /* Test streaming API */ 323 | for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) { 324 | for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { 325 | uint8_t hash[BLAKE2B_OUTBYTES]; 326 | blake2bp_state S; 327 | uint8_t * p = buf; 328 | size_t mlen = i; 329 | int err = 0; 330 | 331 | if( (err = blake2bp_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) { 332 | goto fail; 333 | } 334 | 335 | while (mlen >= step) { 336 | if ( (err = blake2bp_update(&S, p, step)) < 0 ) { 337 | goto fail; 338 | } 339 | mlen -= step; 340 | p += step; 341 | } 342 | if ( (err = blake2bp_update(&S, p, mlen)) < 0) { 343 | goto fail; 344 | } 345 | if ( (err = blake2bp_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) { 346 | goto fail; 347 | } 348 | 349 | if (0 != memcmp(hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES)) { 350 | goto fail; 351 | } 352 | } 353 | } 354 | 355 | puts( "ok" ); 356 | return 0; 357 | fail: 358 | puts("error"); 359 | return -1; 360 | } 361 | #endif 362 | -------------------------------------------------------------------------------- /cbits/sse/blake2s.c: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - optimized C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "blake2.h" 21 | #include "blake2-impl.h" 22 | 23 | #include "blake2-config.h" 24 | 25 | 26 | #include 27 | #if defined(HAVE_SSSE3) 28 | #include 29 | #endif 30 | #if defined(HAVE_SSE41) 31 | #include 32 | #endif 33 | #if defined(HAVE_AVX) 34 | #include 35 | #endif 36 | #if defined(HAVE_XOP) 37 | #include 38 | #endif 39 | 40 | #include "blake2s-round.h" 41 | 42 | static const uint32_t blake2s_IV[8] = 43 | { 44 | 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, 45 | 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL 46 | }; 47 | 48 | /* Some helper functions */ 49 | static void blake2s_set_lastnode( blake2s_state *S ) 50 | { 51 | S->f[1] = (uint32_t)-1; 52 | } 53 | 54 | static int blake2s_is_lastblock( const blake2s_state *S ) 55 | { 56 | return S->f[0] != 0; 57 | } 58 | 59 | static void blake2s_set_lastblock( blake2s_state *S ) 60 | { 61 | if( S->last_node ) blake2s_set_lastnode( S ); 62 | 63 | S->f[0] = (uint32_t)-1; 64 | } 65 | 66 | static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) 67 | { 68 | uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0]; 69 | t += inc; 70 | S->t[0] = ( uint32_t )( t >> 0 ); 71 | S->t[1] = ( uint32_t )( t >> 32 ); 72 | } 73 | 74 | /* init2 xors IV with input parameter block */ 75 | int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) 76 | { 77 | size_t i; 78 | /*blake2s_init0( S ); */ 79 | const uint8_t * v = ( const uint8_t * )( blake2s_IV ); 80 | const uint8_t * p = ( const uint8_t * )( P ); 81 | uint8_t * h = ( uint8_t * )( S->h ); 82 | /* IV XOR ParamBlock */ 83 | memset( S, 0, sizeof( blake2s_state ) ); 84 | 85 | for( i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; 86 | 87 | S->outlen = P->digest_length; 88 | return 0; 89 | } 90 | 91 | 92 | /* Some sort of default parameter block initialization, for sequential blake2s */ 93 | int blake2s_init( blake2s_state *S, size_t outlen ) 94 | { 95 | blake2s_param P[1]; 96 | 97 | /* Move interval verification here? */ 98 | if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; 99 | 100 | P->digest_length = (uint8_t)outlen; 101 | P->key_length = 0; 102 | P->fanout = 1; 103 | P->depth = 1; 104 | store32( &P->leaf_length, 0 ); 105 | store32( &P->node_offset, 0 ); 106 | store16( &P->xof_length, 0 ); 107 | P->node_depth = 0; 108 | P->inner_length = 0; 109 | /* memset(P->reserved, 0, sizeof(P->reserved) ); */ 110 | memset( P->salt, 0, sizeof( P->salt ) ); 111 | memset( P->personal, 0, sizeof( P->personal ) ); 112 | 113 | return blake2s_init_param( S, P ); 114 | } 115 | 116 | 117 | int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) 118 | { 119 | blake2s_param P[1]; 120 | 121 | /* Move interval verification here? */ 122 | if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; 123 | 124 | if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1; 125 | 126 | P->digest_length = (uint8_t)outlen; 127 | P->key_length = (uint8_t)keylen; 128 | P->fanout = 1; 129 | P->depth = 1; 130 | store32( &P->leaf_length, 0 ); 131 | store32( &P->node_offset, 0 ); 132 | store16( &P->xof_length, 0 ); 133 | P->node_depth = 0; 134 | P->inner_length = 0; 135 | /* memset(P->reserved, 0, sizeof(P->reserved) ); */ 136 | memset( P->salt, 0, sizeof( P->salt ) ); 137 | memset( P->personal, 0, sizeof( P->personal ) ); 138 | 139 | if( blake2s_init_param( S, P ) < 0 ) 140 | return -1; 141 | 142 | { 143 | uint8_t block[BLAKE2S_BLOCKBYTES]; 144 | memset( block, 0, BLAKE2S_BLOCKBYTES ); 145 | memcpy( block, key, keylen ); 146 | blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); 147 | secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ 148 | } 149 | return 0; 150 | } 151 | 152 | 153 | static void blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) 154 | { 155 | __m128i row1, row2, row3, row4; 156 | __m128i buf1, buf2, buf3, buf4; 157 | #if defined(HAVE_SSE41) 158 | __m128i t0, t1; 159 | #if !defined(HAVE_XOP) 160 | __m128i t2; 161 | #endif 162 | #endif 163 | __m128i ff0, ff1; 164 | #if defined(HAVE_SSSE3) && !defined(HAVE_XOP) 165 | const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 ); 166 | const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 ); 167 | #endif 168 | #if defined(HAVE_SSE41) 169 | const __m128i m0 = LOADU( block + 00 ); 170 | const __m128i m1 = LOADU( block + 16 ); 171 | const __m128i m2 = LOADU( block + 32 ); 172 | const __m128i m3 = LOADU( block + 48 ); 173 | #else 174 | const uint32_t m0 = load32(block + 0 * sizeof(uint32_t)); 175 | const uint32_t m1 = load32(block + 1 * sizeof(uint32_t)); 176 | const uint32_t m2 = load32(block + 2 * sizeof(uint32_t)); 177 | const uint32_t m3 = load32(block + 3 * sizeof(uint32_t)); 178 | const uint32_t m4 = load32(block + 4 * sizeof(uint32_t)); 179 | const uint32_t m5 = load32(block + 5 * sizeof(uint32_t)); 180 | const uint32_t m6 = load32(block + 6 * sizeof(uint32_t)); 181 | const uint32_t m7 = load32(block + 7 * sizeof(uint32_t)); 182 | const uint32_t m8 = load32(block + 8 * sizeof(uint32_t)); 183 | const uint32_t m9 = load32(block + 9 * sizeof(uint32_t)); 184 | const uint32_t m10 = load32(block + 10 * sizeof(uint32_t)); 185 | const uint32_t m11 = load32(block + 11 * sizeof(uint32_t)); 186 | const uint32_t m12 = load32(block + 12 * sizeof(uint32_t)); 187 | const uint32_t m13 = load32(block + 13 * sizeof(uint32_t)); 188 | const uint32_t m14 = load32(block + 14 * sizeof(uint32_t)); 189 | const uint32_t m15 = load32(block + 15 * sizeof(uint32_t)); 190 | #endif 191 | row1 = ff0 = LOADU( &S->h[0] ); 192 | row2 = ff1 = LOADU( &S->h[4] ); 193 | row3 = _mm_loadu_si128( (__m128i const *)&blake2s_IV[0] ); 194 | row4 = _mm_xor_si128( _mm_loadu_si128( (__m128i const *)&blake2s_IV[4] ), LOADU( &S->t[0] ) ); 195 | ROUND( 0 ); 196 | ROUND( 1 ); 197 | ROUND( 2 ); 198 | ROUND( 3 ); 199 | ROUND( 4 ); 200 | ROUND( 5 ); 201 | ROUND( 6 ); 202 | ROUND( 7 ); 203 | ROUND( 8 ); 204 | ROUND( 9 ); 205 | STOREU( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row1, row3 ) ) ); 206 | STOREU( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row2, row4 ) ) ); 207 | } 208 | 209 | int blake2s_update( blake2s_state *S, const void *pin, size_t inlen ) 210 | { 211 | const unsigned char * in = (const unsigned char *)pin; 212 | if( inlen > 0 ) 213 | { 214 | size_t left = S->buflen; 215 | size_t fill = BLAKE2S_BLOCKBYTES - left; 216 | if( inlen > fill ) 217 | { 218 | S->buflen = 0; 219 | memcpy( S->buf + left, in, fill ); /* Fill buffer */ 220 | blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); 221 | blake2s_compress( S, S->buf ); /* Compress */ 222 | in += fill; inlen -= fill; 223 | while(inlen > BLAKE2S_BLOCKBYTES) { 224 | blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); 225 | blake2s_compress( S, in ); 226 | in += BLAKE2S_BLOCKBYTES; 227 | inlen -= BLAKE2S_BLOCKBYTES; 228 | } 229 | } 230 | memcpy( S->buf + S->buflen, in, inlen ); 231 | S->buflen += inlen; 232 | } 233 | return 0; 234 | } 235 | 236 | int blake2s_final( blake2s_state *S, void *out, size_t outlen ) 237 | { 238 | uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; 239 | size_t i; 240 | 241 | if( out == NULL || outlen < S->outlen ) 242 | return -1; 243 | 244 | if( blake2s_is_lastblock( S ) ) 245 | return -1; 246 | 247 | blake2s_increment_counter( S, (uint32_t)S->buflen ); 248 | blake2s_set_lastblock( S ); 249 | memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ 250 | blake2s_compress( S, S->buf ); 251 | 252 | for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ 253 | store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); 254 | 255 | memcpy( out, buffer, S->outlen ); 256 | secure_zero_memory( buffer, sizeof(buffer) ); 257 | return 0; 258 | } 259 | 260 | /* inlen, at least, should be uint64_t. Others can be size_t. */ 261 | int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) 262 | { 263 | blake2s_state S[1]; 264 | 265 | /* Verify parameters */ 266 | if ( NULL == in && inlen > 0 ) return -1; 267 | 268 | if ( NULL == out ) return -1; 269 | 270 | if ( NULL == key && keylen > 0) return -1; 271 | 272 | if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; 273 | 274 | if( keylen > BLAKE2S_KEYBYTES ) return -1; 275 | 276 | if( keylen > 0 ) 277 | { 278 | if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; 279 | } 280 | else 281 | { 282 | if( blake2s_init( S, outlen ) < 0 ) return -1; 283 | } 284 | 285 | blake2s_update( S, ( const uint8_t * )in, inlen ); 286 | blake2s_final( S, out, outlen ); 287 | return 0; 288 | } 289 | 290 | #if defined(SUPERCOP) 291 | int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) 292 | { 293 | return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 ); 294 | } 295 | #endif 296 | 297 | #if defined(BLAKE2S_SELFTEST) 298 | #include 299 | #include "blake2-kat.h" 300 | int main( void ) 301 | { 302 | uint8_t key[BLAKE2S_KEYBYTES]; 303 | uint8_t buf[BLAKE2_KAT_LENGTH]; 304 | size_t i, step; 305 | 306 | for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) 307 | key[i] = ( uint8_t )i; 308 | 309 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 310 | buf[i] = ( uint8_t )i; 311 | 312 | /* Test simple API */ 313 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 314 | { 315 | uint8_t hash[BLAKE2S_OUTBYTES]; 316 | blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); 317 | 318 | if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) 319 | { 320 | goto fail; 321 | } 322 | } 323 | 324 | /* Test streaming API */ 325 | for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { 326 | for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { 327 | uint8_t hash[BLAKE2S_OUTBYTES]; 328 | blake2s_state S; 329 | uint8_t * p = buf; 330 | size_t mlen = i; 331 | int err = 0; 332 | 333 | if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { 334 | goto fail; 335 | } 336 | 337 | while (mlen >= step) { 338 | if ( (err = blake2s_update(&S, p, step)) < 0 ) { 339 | goto fail; 340 | } 341 | mlen -= step; 342 | p += step; 343 | } 344 | if ( (err = blake2s_update(&S, p, mlen)) < 0) { 345 | goto fail; 346 | } 347 | if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { 348 | goto fail; 349 | } 350 | 351 | if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) { 352 | goto fail; 353 | } 354 | } 355 | } 356 | 357 | puts( "ok" ); 358 | return 0; 359 | fail: 360 | puts("error"); 361 | return -1; 362 | } 363 | #endif 364 | -------------------------------------------------------------------------------- /cbits/sse/blake2sp.c: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - optimized C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #if defined(_OPENMP) 21 | #include 22 | #endif 23 | 24 | #include "blake2.h" 25 | #include "blake2-impl.h" 26 | 27 | #define PARALLELISM_DEGREE 8 28 | 29 | /* 30 | blake2sp_init_param defaults to setting the expecting output length 31 | from the digest_length parameter block field. 32 | 33 | In some cases, however, we do not want this, as the output length 34 | of these instances is given by inner_length instead. 35 | */ 36 | static int blake2sp_init_leaf_param( blake2s_state *S, const blake2s_param *P ) 37 | { 38 | int err = blake2s_init_param(S, P); 39 | S->outlen = P->inner_length; 40 | return err; 41 | } 42 | 43 | static int blake2sp_init_leaf( blake2s_state *S, size_t outlen, size_t keylen, uint64_t offset ) 44 | { 45 | blake2s_param P[1]; 46 | P->digest_length = (uint8_t)outlen; 47 | P->key_length = (uint8_t)keylen; 48 | P->fanout = PARALLELISM_DEGREE; 49 | P->depth = 2; 50 | P->leaf_length = 0; 51 | P->node_offset = offset; 52 | P->xof_length = 0; 53 | P->node_depth = 0; 54 | P->inner_length = BLAKE2S_OUTBYTES; 55 | memset( P->salt, 0, sizeof( P->salt ) ); 56 | memset( P->personal, 0, sizeof( P->personal ) ); 57 | return blake2sp_init_leaf_param( S, P ); 58 | } 59 | 60 | static int blake2sp_init_root( blake2s_state *S, size_t outlen, size_t keylen ) 61 | { 62 | blake2s_param P[1]; 63 | P->digest_length = (uint8_t)outlen; 64 | P->key_length = (uint8_t)keylen; 65 | P->fanout = PARALLELISM_DEGREE; 66 | P->depth = 2; 67 | P->leaf_length = 0; 68 | P->node_offset = 0; 69 | P->xof_length = 0; 70 | P->node_depth = 1; 71 | P->inner_length = BLAKE2S_OUTBYTES; 72 | memset( P->salt, 0, sizeof( P->salt ) ); 73 | memset( P->personal, 0, sizeof( P->personal ) ); 74 | return blake2s_init_param( S, P ); 75 | } 76 | 77 | 78 | int blake2sp_init( blake2sp_state *S, size_t outlen ) 79 | { 80 | size_t i; 81 | 82 | if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; 83 | 84 | memset( S->buf, 0, sizeof( S->buf ) ); 85 | S->buflen = 0; 86 | S->outlen = outlen; 87 | 88 | if( blake2sp_init_root( S->R, outlen, 0 ) < 0 ) 89 | return -1; 90 | 91 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 92 | if( blake2sp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1; 93 | 94 | S->R->last_node = 1; 95 | S->S[PARALLELISM_DEGREE - 1]->last_node = 1; 96 | return 0; 97 | } 98 | 99 | int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ) 100 | { 101 | size_t i; 102 | 103 | if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; 104 | 105 | if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; 106 | 107 | memset( S->buf, 0, sizeof( S->buf ) ); 108 | S->buflen = 0; 109 | S->outlen = outlen; 110 | 111 | if( blake2sp_init_root( S->R, outlen, keylen ) < 0 ) 112 | return -1; 113 | 114 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 115 | if( blake2sp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1; 116 | 117 | S->R->last_node = 1; 118 | S->S[PARALLELISM_DEGREE - 1]->last_node = 1; 119 | { 120 | uint8_t block[BLAKE2S_BLOCKBYTES]; 121 | memset( block, 0, BLAKE2S_BLOCKBYTES ); 122 | memcpy( block, key, keylen ); 123 | 124 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 125 | blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES ); 126 | 127 | secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ 128 | } 129 | return 0; 130 | } 131 | 132 | 133 | int blake2sp_update( blake2sp_state *S, const void *pin, size_t inlen ) 134 | { 135 | const unsigned char * in = (const unsigned char *)pin; 136 | size_t left = S->buflen; 137 | size_t fill = sizeof( S->buf ) - left; 138 | size_t i; 139 | 140 | if( left && inlen >= fill ) 141 | { 142 | memcpy( S->buf + left, in, fill ); 143 | 144 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 145 | blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); 146 | 147 | in += fill; 148 | inlen -= fill; 149 | left = 0; 150 | } 151 | 152 | #if defined(_OPENMP) 153 | #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE) 154 | #else 155 | 156 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 157 | #endif 158 | { 159 | #if defined(_OPENMP) 160 | size_t i = omp_get_thread_num(); 161 | #endif 162 | size_t inlen__ = inlen; 163 | const unsigned char *in__ = ( const unsigned char * )in; 164 | in__ += i * BLAKE2S_BLOCKBYTES; 165 | 166 | while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) 167 | { 168 | blake2s_update( S->S[i], in__, BLAKE2S_BLOCKBYTES ); 169 | in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; 170 | inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; 171 | } 172 | } 173 | 174 | in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ); 175 | inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; 176 | 177 | if( inlen > 0 ) 178 | memcpy( S->buf + left, in, inlen ); 179 | 180 | S->buflen = left + inlen; 181 | return 0; 182 | } 183 | 184 | 185 | int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ) 186 | { 187 | uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; 188 | size_t i; 189 | 190 | if(out == NULL || outlen < S->outlen) { 191 | return -1; 192 | } 193 | 194 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 195 | { 196 | if( S->buflen > i * BLAKE2S_BLOCKBYTES ) 197 | { 198 | size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES; 199 | 200 | if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES; 201 | 202 | blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left ); 203 | } 204 | 205 | blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES ); 206 | } 207 | 208 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 209 | blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES ); 210 | 211 | return blake2s_final( S->R, out, S->outlen ); 212 | } 213 | 214 | 215 | int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) 216 | { 217 | uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; 218 | blake2s_state S[PARALLELISM_DEGREE][1]; 219 | blake2s_state FS[1]; 220 | size_t i; 221 | 222 | /* Verify parameters */ 223 | if ( NULL == in && inlen > 0 ) return -1; 224 | 225 | if ( NULL == out ) return -1; 226 | 227 | if ( NULL == key && keylen > 0) return -1; 228 | 229 | if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; 230 | 231 | if( keylen > BLAKE2S_KEYBYTES ) return -1; 232 | 233 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 234 | if( blake2sp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1; 235 | 236 | S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */ 237 | 238 | if( keylen > 0 ) 239 | { 240 | uint8_t block[BLAKE2S_BLOCKBYTES]; 241 | memset( block, 0, BLAKE2S_BLOCKBYTES ); 242 | memcpy( block, key, keylen ); 243 | 244 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 245 | blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES ); 246 | 247 | secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ 248 | } 249 | 250 | #if defined(_OPENMP) 251 | #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) 252 | #else 253 | 254 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 255 | #endif 256 | { 257 | #if defined(_OPENMP) 258 | size_t i = omp_get_thread_num(); 259 | #endif 260 | size_t inlen__ = inlen; 261 | const unsigned char *in__ = ( const unsigned char * )in; 262 | in__ += i * BLAKE2S_BLOCKBYTES; 263 | 264 | while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) 265 | { 266 | blake2s_update( S[i], in__, BLAKE2S_BLOCKBYTES ); 267 | in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; 268 | inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; 269 | } 270 | 271 | if( inlen__ > i * BLAKE2S_BLOCKBYTES ) 272 | { 273 | const size_t left = inlen__ - i * BLAKE2S_BLOCKBYTES; 274 | const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES; 275 | blake2s_update( S[i], in__, len ); 276 | } 277 | 278 | blake2s_final( S[i], hash[i], BLAKE2S_OUTBYTES ); 279 | } 280 | 281 | if( blake2sp_init_root( FS, outlen, keylen ) < 0 ) 282 | return -1; 283 | 284 | FS->last_node = 1; 285 | 286 | for( i = 0; i < PARALLELISM_DEGREE; ++i ) 287 | blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES ); 288 | 289 | return blake2s_final( FS, out, outlen ); 290 | } 291 | 292 | #if defined(BLAKE2SP_SELFTEST) 293 | #include 294 | #include "blake2-kat.h" 295 | int main( void ) 296 | { 297 | uint8_t key[BLAKE2S_KEYBYTES]; 298 | uint8_t buf[BLAKE2_KAT_LENGTH]; 299 | size_t i, step; 300 | 301 | for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) 302 | key[i] = ( uint8_t )i; 303 | 304 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 305 | buf[i] = ( uint8_t )i; 306 | 307 | /* Test simple API */ 308 | for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) 309 | { 310 | uint8_t hash[BLAKE2S_OUTBYTES]; 311 | blake2sp( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); 312 | 313 | if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) ) 314 | { 315 | goto fail; 316 | } 317 | } 318 | 319 | /* Test streaming API */ 320 | for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { 321 | for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { 322 | uint8_t hash[BLAKE2S_OUTBYTES]; 323 | blake2sp_state S; 324 | uint8_t * p = buf; 325 | size_t mlen = i; 326 | int err = 0; 327 | 328 | if( (err = blake2sp_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { 329 | goto fail; 330 | } 331 | 332 | while (mlen >= step) { 333 | if ( (err = blake2sp_update(&S, p, step)) < 0 ) { 334 | goto fail; 335 | } 336 | mlen -= step; 337 | p += step; 338 | } 339 | if ( (err = blake2sp_update(&S, p, mlen)) < 0) { 340 | goto fail; 341 | } 342 | if ( (err = blake2sp_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { 343 | goto fail; 344 | } 345 | 346 | if (0 != memcmp(hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES)) { 347 | goto fail; 348 | } 349 | } 350 | } 351 | 352 | puts( "ok" ); 353 | return 0; 354 | fail: 355 | puts("error"); 356 | return -1; 357 | } 358 | #endif 359 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # 0.3.0.1 2 | 3 | * Miscellaneous cleanup and dependency version updates 4 | 5 | # 0.3.0 6 | 7 | * Bring C code up to date 8 | * Use newer GHCs for testing 9 | 10 | # 0.2.0 11 | 12 | * Added i686 support 13 | * Updated documentation 14 | * Added GHC 7.10.3, 8.0.2 to unit tests 15 | 16 | # 0.1.0 17 | 18 | * First version. 19 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1687171271, 9 | "narHash": "sha256-BJlq+ozK2B1sJDQXS3tzJM5a+oVZmi1q0FlBK/Xqv7M=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "abfb11bd1aec8ced1c9bb9adfe68018230f4fb3c", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1687518131, 24 | "narHash": "sha256-KirltRIc4SFfk8bTNudIqgKAALH5oqpW3PefmkfWK5M=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "3d8a93602bc54ece7a4e689d9aea1a574e2bbc24", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "id": "nixpkgs", 32 | "type": "indirect" 33 | } 34 | }, 35 | "root": { 36 | "inputs": { 37 | "flake-utils": "flake-utils", 38 | "nixpkgs": "nixpkgs" 39 | } 40 | }, 41 | "systems": { 42 | "locked": { 43 | "lastModified": 1681028828, 44 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 45 | "owner": "nix-systems", 46 | "repo": "default", 47 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 48 | "type": "github" 49 | }, 50 | "original": { 51 | "owner": "nix-systems", 52 | "repo": "default", 53 | "type": "github" 54 | } 55 | } 56 | }, 57 | "root": "root", 58 | "version": 7 59 | } 60 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Haskell bindings for BLAKE2"; 3 | 4 | inputs = { 5 | flake-utils.url = "github:numtide/flake-utils"; 6 | }; 7 | 8 | outputs = { self, nixpkgs, flake-utils }: 9 | flake-utils.lib.eachDefaultSystem (system: 10 | let 11 | pkgs = import nixpkgs { 12 | inherit system; 13 | }; 14 | 15 | packageName = "blake2"; 16 | 17 | project = pkgs.haskellPackages.developPackage { 18 | root = ./.; 19 | name = packageName; 20 | }; 21 | in { 22 | packages.${packageName} = project; 23 | defaultPackage = self.packages.${system}.${packageName}; 24 | devShells.default = pkgs.mkShell { 25 | inputsFrom = [ project.env ]; 26 | buildInputs = [ pkgs.haskell-language-server pkgs.cabal-install ]; 27 | }; 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /include/ref/blake2-impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - reference C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | #ifndef BLAKE2_IMPL_H 16 | #define BLAKE2_IMPL_H 17 | 18 | #include 19 | #include 20 | 21 | #if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) 22 | #if defined(_MSC_VER) 23 | #define BLAKE2_INLINE __inline 24 | #elif defined(__GNUC__) 25 | #define BLAKE2_INLINE __inline__ 26 | #else 27 | #define BLAKE2_INLINE 28 | #endif 29 | #else 30 | #define BLAKE2_INLINE inline 31 | #endif 32 | 33 | static BLAKE2_INLINE uint32_t load32( const void *src ) 34 | { 35 | #if defined(NATIVE_LITTLE_ENDIAN) 36 | uint32_t w; 37 | memcpy(&w, src, sizeof w); 38 | return w; 39 | #else 40 | const uint8_t *p = ( const uint8_t * )src; 41 | return (( uint32_t )( p[0] ) << 0) | 42 | (( uint32_t )( p[1] ) << 8) | 43 | (( uint32_t )( p[2] ) << 16) | 44 | (( uint32_t )( p[3] ) << 24) ; 45 | #endif 46 | } 47 | 48 | static BLAKE2_INLINE uint64_t load64( const void *src ) 49 | { 50 | #if defined(NATIVE_LITTLE_ENDIAN) 51 | uint64_t w; 52 | memcpy(&w, src, sizeof w); 53 | return w; 54 | #else 55 | const uint8_t *p = ( const uint8_t * )src; 56 | return (( uint64_t )( p[0] ) << 0) | 57 | (( uint64_t )( p[1] ) << 8) | 58 | (( uint64_t )( p[2] ) << 16) | 59 | (( uint64_t )( p[3] ) << 24) | 60 | (( uint64_t )( p[4] ) << 32) | 61 | (( uint64_t )( p[5] ) << 40) | 62 | (( uint64_t )( p[6] ) << 48) | 63 | (( uint64_t )( p[7] ) << 56) ; 64 | #endif 65 | } 66 | 67 | static BLAKE2_INLINE uint16_t load16( const void *src ) 68 | { 69 | #if defined(NATIVE_LITTLE_ENDIAN) 70 | uint16_t w; 71 | memcpy(&w, src, sizeof w); 72 | return w; 73 | #else 74 | const uint8_t *p = ( const uint8_t * )src; 75 | return ( uint16_t )((( uint32_t )( p[0] ) << 0) | 76 | (( uint32_t )( p[1] ) << 8)); 77 | #endif 78 | } 79 | 80 | static BLAKE2_INLINE void store16( void *dst, uint16_t w ) 81 | { 82 | #if defined(NATIVE_LITTLE_ENDIAN) 83 | memcpy(dst, &w, sizeof w); 84 | #else 85 | uint8_t *p = ( uint8_t * )dst; 86 | *p++ = ( uint8_t )w; w >>= 8; 87 | *p++ = ( uint8_t )w; 88 | #endif 89 | } 90 | 91 | static BLAKE2_INLINE void store32( void *dst, uint32_t w ) 92 | { 93 | #if defined(NATIVE_LITTLE_ENDIAN) 94 | memcpy(dst, &w, sizeof w); 95 | #else 96 | uint8_t *p = ( uint8_t * )dst; 97 | p[0] = (uint8_t)(w >> 0); 98 | p[1] = (uint8_t)(w >> 8); 99 | p[2] = (uint8_t)(w >> 16); 100 | p[3] = (uint8_t)(w >> 24); 101 | #endif 102 | } 103 | 104 | static BLAKE2_INLINE void store64( void *dst, uint64_t w ) 105 | { 106 | #if defined(NATIVE_LITTLE_ENDIAN) 107 | memcpy(dst, &w, sizeof w); 108 | #else 109 | uint8_t *p = ( uint8_t * )dst; 110 | p[0] = (uint8_t)(w >> 0); 111 | p[1] = (uint8_t)(w >> 8); 112 | p[2] = (uint8_t)(w >> 16); 113 | p[3] = (uint8_t)(w >> 24); 114 | p[4] = (uint8_t)(w >> 32); 115 | p[5] = (uint8_t)(w >> 40); 116 | p[6] = (uint8_t)(w >> 48); 117 | p[7] = (uint8_t)(w >> 56); 118 | #endif 119 | } 120 | 121 | static BLAKE2_INLINE uint64_t load48( const void *src ) 122 | { 123 | const uint8_t *p = ( const uint8_t * )src; 124 | return (( uint64_t )( p[0] ) << 0) | 125 | (( uint64_t )( p[1] ) << 8) | 126 | (( uint64_t )( p[2] ) << 16) | 127 | (( uint64_t )( p[3] ) << 24) | 128 | (( uint64_t )( p[4] ) << 32) | 129 | (( uint64_t )( p[5] ) << 40) ; 130 | } 131 | 132 | static BLAKE2_INLINE void store48( void *dst, uint64_t w ) 133 | { 134 | uint8_t *p = ( uint8_t * )dst; 135 | p[0] = (uint8_t)(w >> 0); 136 | p[1] = (uint8_t)(w >> 8); 137 | p[2] = (uint8_t)(w >> 16); 138 | p[3] = (uint8_t)(w >> 24); 139 | p[4] = (uint8_t)(w >> 32); 140 | p[5] = (uint8_t)(w >> 40); 141 | } 142 | 143 | static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c ) 144 | { 145 | return ( w >> c ) | ( w << ( 32 - c ) ); 146 | } 147 | 148 | static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c ) 149 | { 150 | return ( w >> c ) | ( w << ( 64 - c ) ); 151 | } 152 | 153 | /* prevents compiler optimizing out memset() */ 154 | static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n) 155 | { 156 | static void *(*const volatile memset_v)(void *, int, size_t) = &memset; 157 | memset_v(v, 0, n); 158 | } 159 | 160 | #endif 161 | -------------------------------------------------------------------------------- /include/ref/blake2.h: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - reference C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | #ifndef BLAKE2_H 16 | #define BLAKE2_H 17 | 18 | #include 19 | #include 20 | 21 | #if defined(_MSC_VER) 22 | #define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop)) 23 | #else 24 | #define BLAKE2_PACKED(x) x __attribute__((packed)) 25 | #endif 26 | 27 | #if defined(__cplusplus) 28 | extern "C" { 29 | #endif 30 | 31 | enum blake2s_constant 32 | { 33 | BLAKE2S_BLOCKBYTES = 64, 34 | BLAKE2S_OUTBYTES = 32, 35 | BLAKE2S_KEYBYTES = 32, 36 | BLAKE2S_SALTBYTES = 8, 37 | BLAKE2S_PERSONALBYTES = 8 38 | }; 39 | 40 | enum blake2b_constant 41 | { 42 | BLAKE2B_BLOCKBYTES = 128, 43 | BLAKE2B_OUTBYTES = 64, 44 | BLAKE2B_KEYBYTES = 64, 45 | BLAKE2B_SALTBYTES = 16, 46 | BLAKE2B_PERSONALBYTES = 16 47 | }; 48 | 49 | typedef struct blake2s_state__ 50 | { 51 | uint32_t h[8]; 52 | uint32_t t[2]; 53 | uint32_t f[2]; 54 | uint8_t buf[BLAKE2S_BLOCKBYTES]; 55 | size_t buflen; 56 | size_t outlen; 57 | uint8_t last_node; 58 | } blake2s_state; 59 | 60 | typedef struct blake2b_state__ 61 | { 62 | uint64_t h[8]; 63 | uint64_t t[2]; 64 | uint64_t f[2]; 65 | uint8_t buf[BLAKE2B_BLOCKBYTES]; 66 | size_t buflen; 67 | size_t outlen; 68 | uint8_t last_node; 69 | } blake2b_state; 70 | 71 | typedef struct blake2sp_state__ 72 | { 73 | blake2s_state S[8][1]; 74 | blake2s_state R[1]; 75 | uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; 76 | size_t buflen; 77 | size_t outlen; 78 | } blake2sp_state; 79 | 80 | typedef struct blake2bp_state__ 81 | { 82 | blake2b_state S[4][1]; 83 | blake2b_state R[1]; 84 | uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; 85 | size_t buflen; 86 | size_t outlen; 87 | } blake2bp_state; 88 | 89 | 90 | BLAKE2_PACKED(struct blake2s_param__ 91 | { 92 | uint8_t digest_length; /* 1 */ 93 | uint8_t key_length; /* 2 */ 94 | uint8_t fanout; /* 3 */ 95 | uint8_t depth; /* 4 */ 96 | uint32_t leaf_length; /* 8 */ 97 | uint32_t node_offset; /* 12 */ 98 | uint16_t xof_length; /* 14 */ 99 | uint8_t node_depth; /* 15 */ 100 | uint8_t inner_length; /* 16 */ 101 | /* uint8_t reserved[0]; */ 102 | uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ 103 | uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ 104 | }); 105 | 106 | typedef struct blake2s_param__ blake2s_param; 107 | 108 | BLAKE2_PACKED(struct blake2b_param__ 109 | { 110 | uint8_t digest_length; /* 1 */ 111 | uint8_t key_length; /* 2 */ 112 | uint8_t fanout; /* 3 */ 113 | uint8_t depth; /* 4 */ 114 | uint32_t leaf_length; /* 8 */ 115 | uint32_t node_offset; /* 12 */ 116 | uint32_t xof_length; /* 16 */ 117 | uint8_t node_depth; /* 17 */ 118 | uint8_t inner_length; /* 18 */ 119 | uint8_t reserved[14]; /* 32 */ 120 | uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ 121 | uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ 122 | }); 123 | 124 | typedef struct blake2b_param__ blake2b_param; 125 | 126 | typedef struct blake2xs_state__ 127 | { 128 | blake2s_state S[1]; 129 | blake2s_param P[1]; 130 | } blake2xs_state; 131 | 132 | typedef struct blake2xb_state__ 133 | { 134 | blake2b_state S[1]; 135 | blake2b_param P[1]; 136 | } blake2xb_state; 137 | 138 | /* Padded structs result in a compile-time error */ 139 | enum { 140 | BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES), 141 | BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES) 142 | }; 143 | 144 | /* Streaming API */ 145 | int blake2s_init( blake2s_state *S, size_t outlen ); 146 | int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); 147 | int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); 148 | int blake2s_update( blake2s_state *S, const void *in, size_t inlen ); 149 | int blake2s_final( blake2s_state *S, void *out, size_t outlen ); 150 | 151 | int blake2b_init( blake2b_state *S, size_t outlen ); 152 | int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); 153 | int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); 154 | int blake2b_update( blake2b_state *S, const void *in, size_t inlen ); 155 | int blake2b_final( blake2b_state *S, void *out, size_t outlen ); 156 | 157 | int blake2sp_init( blake2sp_state *S, size_t outlen ); 158 | int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ); 159 | int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen ); 160 | int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ); 161 | 162 | int blake2bp_init( blake2bp_state *S, size_t outlen ); 163 | int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ); 164 | int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen ); 165 | int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ); 166 | 167 | /* Variable output length API */ 168 | int blake2xs_init( blake2xs_state *S, const size_t outlen ); 169 | int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen ); 170 | int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen ); 171 | int blake2xs_final(blake2xs_state *S, void *out, size_t outlen); 172 | 173 | int blake2xb_init( blake2xb_state *S, const size_t outlen ); 174 | int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen ); 175 | int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen ); 176 | int blake2xb_final(blake2xb_state *S, void *out, size_t outlen); 177 | 178 | /* Simple API */ 179 | int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 180 | int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 181 | 182 | int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 183 | int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 184 | 185 | int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 186 | int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 187 | 188 | /* This is simply an alias for blake2b */ 189 | int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 190 | 191 | #if defined(__cplusplus) 192 | } 193 | #endif 194 | 195 | #endif 196 | -------------------------------------------------------------------------------- /include/sse/blake2-config.h: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - optimized C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | #ifndef BLAKE2_CONFIG_H 16 | #define BLAKE2_CONFIG_H 17 | 18 | /* These don't work everywhere */ 19 | #if defined(__SSE2__) || defined(__x86_64__) || defined(__amd64__) 20 | #define HAVE_SSE2 21 | #endif 22 | 23 | #if defined(__SSSE3__) 24 | #define HAVE_SSSE3 25 | #endif 26 | 27 | #if defined(__SSE4_1__) 28 | #define HAVE_SSE41 29 | #endif 30 | 31 | #if defined(__AVX__) 32 | #define HAVE_AVX 33 | #endif 34 | 35 | #if defined(__XOP__) 36 | #define HAVE_XOP 37 | #endif 38 | 39 | 40 | #ifdef HAVE_AVX2 41 | #ifndef HAVE_AVX 42 | #define HAVE_AVX 43 | #endif 44 | #endif 45 | 46 | #ifdef HAVE_XOP 47 | #ifndef HAVE_AVX 48 | #define HAVE_AVX 49 | #endif 50 | #endif 51 | 52 | #ifdef HAVE_AVX 53 | #ifndef HAVE_SSE41 54 | #define HAVE_SSE41 55 | #endif 56 | #endif 57 | 58 | #ifdef HAVE_SSE41 59 | #ifndef HAVE_SSSE3 60 | #define HAVE_SSSE3 61 | #endif 62 | #endif 63 | 64 | #ifdef HAVE_SSSE3 65 | #define HAVE_SSE2 66 | #endif 67 | 68 | #if !defined(HAVE_SSE2) 69 | #error "This code requires at least SSE2." 70 | #endif 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /include/sse/blake2-impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - reference C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | #ifndef BLAKE2_IMPL_H 16 | #define BLAKE2_IMPL_H 17 | 18 | #include 19 | #include 20 | 21 | #if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) 22 | #if defined(_MSC_VER) 23 | #define BLAKE2_INLINE __inline 24 | #elif defined(__GNUC__) 25 | #define BLAKE2_INLINE __inline__ 26 | #else 27 | #define BLAKE2_INLINE 28 | #endif 29 | #else 30 | #define BLAKE2_INLINE inline 31 | #endif 32 | 33 | static BLAKE2_INLINE uint32_t load32( const void *src ) 34 | { 35 | #if defined(NATIVE_LITTLE_ENDIAN) 36 | uint32_t w; 37 | memcpy(&w, src, sizeof w); 38 | return w; 39 | #else 40 | const uint8_t *p = ( const uint8_t * )src; 41 | return (( uint32_t )( p[0] ) << 0) | 42 | (( uint32_t )( p[1] ) << 8) | 43 | (( uint32_t )( p[2] ) << 16) | 44 | (( uint32_t )( p[3] ) << 24) ; 45 | #endif 46 | } 47 | 48 | static BLAKE2_INLINE uint64_t load64( const void *src ) 49 | { 50 | #if defined(NATIVE_LITTLE_ENDIAN) 51 | uint64_t w; 52 | memcpy(&w, src, sizeof w); 53 | return w; 54 | #else 55 | const uint8_t *p = ( const uint8_t * )src; 56 | return (( uint64_t )( p[0] ) << 0) | 57 | (( uint64_t )( p[1] ) << 8) | 58 | (( uint64_t )( p[2] ) << 16) | 59 | (( uint64_t )( p[3] ) << 24) | 60 | (( uint64_t )( p[4] ) << 32) | 61 | (( uint64_t )( p[5] ) << 40) | 62 | (( uint64_t )( p[6] ) << 48) | 63 | (( uint64_t )( p[7] ) << 56) ; 64 | #endif 65 | } 66 | 67 | static BLAKE2_INLINE uint16_t load16( const void *src ) 68 | { 69 | #if defined(NATIVE_LITTLE_ENDIAN) 70 | uint16_t w; 71 | memcpy(&w, src, sizeof w); 72 | return w; 73 | #else 74 | const uint8_t *p = ( const uint8_t * )src; 75 | return ( uint16_t )((( uint32_t )( p[0] ) << 0) | 76 | (( uint32_t )( p[1] ) << 8)); 77 | #endif 78 | } 79 | 80 | static BLAKE2_INLINE void store16( void *dst, uint16_t w ) 81 | { 82 | #if defined(NATIVE_LITTLE_ENDIAN) 83 | memcpy(dst, &w, sizeof w); 84 | #else 85 | uint8_t *p = ( uint8_t * )dst; 86 | *p++ = ( uint8_t )w; w >>= 8; 87 | *p++ = ( uint8_t )w; 88 | #endif 89 | } 90 | 91 | static BLAKE2_INLINE void store32( void *dst, uint32_t w ) 92 | { 93 | #if defined(NATIVE_LITTLE_ENDIAN) 94 | memcpy(dst, &w, sizeof w); 95 | #else 96 | uint8_t *p = ( uint8_t * )dst; 97 | p[0] = (uint8_t)(w >> 0); 98 | p[1] = (uint8_t)(w >> 8); 99 | p[2] = (uint8_t)(w >> 16); 100 | p[3] = (uint8_t)(w >> 24); 101 | #endif 102 | } 103 | 104 | static BLAKE2_INLINE void store64( void *dst, uint64_t w ) 105 | { 106 | #if defined(NATIVE_LITTLE_ENDIAN) 107 | memcpy(dst, &w, sizeof w); 108 | #else 109 | uint8_t *p = ( uint8_t * )dst; 110 | p[0] = (uint8_t)(w >> 0); 111 | p[1] = (uint8_t)(w >> 8); 112 | p[2] = (uint8_t)(w >> 16); 113 | p[3] = (uint8_t)(w >> 24); 114 | p[4] = (uint8_t)(w >> 32); 115 | p[5] = (uint8_t)(w >> 40); 116 | p[6] = (uint8_t)(w >> 48); 117 | p[7] = (uint8_t)(w >> 56); 118 | #endif 119 | } 120 | 121 | static BLAKE2_INLINE uint64_t load48( const void *src ) 122 | { 123 | const uint8_t *p = ( const uint8_t * )src; 124 | return (( uint64_t )( p[0] ) << 0) | 125 | (( uint64_t )( p[1] ) << 8) | 126 | (( uint64_t )( p[2] ) << 16) | 127 | (( uint64_t )( p[3] ) << 24) | 128 | (( uint64_t )( p[4] ) << 32) | 129 | (( uint64_t )( p[5] ) << 40) ; 130 | } 131 | 132 | static BLAKE2_INLINE void store48( void *dst, uint64_t w ) 133 | { 134 | uint8_t *p = ( uint8_t * )dst; 135 | p[0] = (uint8_t)(w >> 0); 136 | p[1] = (uint8_t)(w >> 8); 137 | p[2] = (uint8_t)(w >> 16); 138 | p[3] = (uint8_t)(w >> 24); 139 | p[4] = (uint8_t)(w >> 32); 140 | p[5] = (uint8_t)(w >> 40); 141 | } 142 | 143 | static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c ) 144 | { 145 | return ( w >> c ) | ( w << ( 32 - c ) ); 146 | } 147 | 148 | static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c ) 149 | { 150 | return ( w >> c ) | ( w << ( 64 - c ) ); 151 | } 152 | 153 | /* prevents compiler optimizing out memset() */ 154 | static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n) 155 | { 156 | static void *(*const volatile memset_v)(void *, int, size_t) = &memset; 157 | memset_v(v, 0, n); 158 | } 159 | 160 | #endif 161 | -------------------------------------------------------------------------------- /include/sse/blake2.h: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - reference C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | #ifndef BLAKE2_H 16 | #define BLAKE2_H 17 | 18 | #include 19 | #include 20 | 21 | #if defined(_MSC_VER) 22 | #define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop)) 23 | #else 24 | #define BLAKE2_PACKED(x) x __attribute__((packed)) 25 | #endif 26 | 27 | #if defined(__cplusplus) 28 | extern "C" { 29 | #endif 30 | 31 | enum blake2s_constant 32 | { 33 | BLAKE2S_BLOCKBYTES = 64, 34 | BLAKE2S_OUTBYTES = 32, 35 | BLAKE2S_KEYBYTES = 32, 36 | BLAKE2S_SALTBYTES = 8, 37 | BLAKE2S_PERSONALBYTES = 8 38 | }; 39 | 40 | enum blake2b_constant 41 | { 42 | BLAKE2B_BLOCKBYTES = 128, 43 | BLAKE2B_OUTBYTES = 64, 44 | BLAKE2B_KEYBYTES = 64, 45 | BLAKE2B_SALTBYTES = 16, 46 | BLAKE2B_PERSONALBYTES = 16 47 | }; 48 | 49 | typedef struct blake2s_state__ 50 | { 51 | uint32_t h[8]; 52 | uint32_t t[2]; 53 | uint32_t f[2]; 54 | uint8_t buf[BLAKE2S_BLOCKBYTES]; 55 | size_t buflen; 56 | size_t outlen; 57 | uint8_t last_node; 58 | } blake2s_state; 59 | 60 | typedef struct blake2b_state__ 61 | { 62 | uint64_t h[8]; 63 | uint64_t t[2]; 64 | uint64_t f[2]; 65 | uint8_t buf[BLAKE2B_BLOCKBYTES]; 66 | size_t buflen; 67 | size_t outlen; 68 | uint8_t last_node; 69 | } blake2b_state; 70 | 71 | typedef struct blake2sp_state__ 72 | { 73 | blake2s_state S[8][1]; 74 | blake2s_state R[1]; 75 | uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; 76 | size_t buflen; 77 | size_t outlen; 78 | } blake2sp_state; 79 | 80 | typedef struct blake2bp_state__ 81 | { 82 | blake2b_state S[4][1]; 83 | blake2b_state R[1]; 84 | uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; 85 | size_t buflen; 86 | size_t outlen; 87 | } blake2bp_state; 88 | 89 | 90 | BLAKE2_PACKED(struct blake2s_param__ 91 | { 92 | uint8_t digest_length; /* 1 */ 93 | uint8_t key_length; /* 2 */ 94 | uint8_t fanout; /* 3 */ 95 | uint8_t depth; /* 4 */ 96 | uint32_t leaf_length; /* 8 */ 97 | uint32_t node_offset; /* 12 */ 98 | uint16_t xof_length; /* 14 */ 99 | uint8_t node_depth; /* 15 */ 100 | uint8_t inner_length; /* 16 */ 101 | /* uint8_t reserved[0]; */ 102 | uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ 103 | uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ 104 | }); 105 | 106 | typedef struct blake2s_param__ blake2s_param; 107 | 108 | BLAKE2_PACKED(struct blake2b_param__ 109 | { 110 | uint8_t digest_length; /* 1 */ 111 | uint8_t key_length; /* 2 */ 112 | uint8_t fanout; /* 3 */ 113 | uint8_t depth; /* 4 */ 114 | uint32_t leaf_length; /* 8 */ 115 | uint32_t node_offset; /* 12 */ 116 | uint32_t xof_length; /* 16 */ 117 | uint8_t node_depth; /* 17 */ 118 | uint8_t inner_length; /* 18 */ 119 | uint8_t reserved[14]; /* 32 */ 120 | uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ 121 | uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ 122 | }); 123 | 124 | typedef struct blake2b_param__ blake2b_param; 125 | 126 | typedef struct blake2xs_state__ 127 | { 128 | blake2s_state S[1]; 129 | blake2s_param P[1]; 130 | } blake2xs_state; 131 | 132 | typedef struct blake2xb_state__ 133 | { 134 | blake2b_state S[1]; 135 | blake2b_param P[1]; 136 | } blake2xb_state; 137 | 138 | /* Padded structs result in a compile-time error */ 139 | enum { 140 | BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES), 141 | BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES) 142 | }; 143 | 144 | /* Streaming API */ 145 | int blake2s_init( blake2s_state *S, size_t outlen ); 146 | int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); 147 | int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); 148 | int blake2s_update( blake2s_state *S, const void *in, size_t inlen ); 149 | int blake2s_final( blake2s_state *S, void *out, size_t outlen ); 150 | 151 | int blake2b_init( blake2b_state *S, size_t outlen ); 152 | int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); 153 | int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); 154 | int blake2b_update( blake2b_state *S, const void *in, size_t inlen ); 155 | int blake2b_final( blake2b_state *S, void *out, size_t outlen ); 156 | 157 | int blake2sp_init( blake2sp_state *S, size_t outlen ); 158 | int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ); 159 | int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen ); 160 | int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ); 161 | 162 | int blake2bp_init( blake2bp_state *S, size_t outlen ); 163 | int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ); 164 | int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen ); 165 | int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ); 166 | 167 | /* Variable output length API */ 168 | int blake2xs_init( blake2xs_state *S, const size_t outlen ); 169 | int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen ); 170 | int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen ); 171 | int blake2xs_final(blake2xs_state *S, void *out, size_t outlen); 172 | 173 | int blake2xb_init( blake2xb_state *S, const size_t outlen ); 174 | int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen ); 175 | int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen ); 176 | int blake2xb_final(blake2xb_state *S, void *out, size_t outlen); 177 | 178 | /* Simple API */ 179 | int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 180 | int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 181 | 182 | int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 183 | int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 184 | 185 | int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 186 | int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 187 | 188 | /* This is simply an alias for blake2b */ 189 | int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 190 | 191 | #if defined(__cplusplus) 192 | } 193 | #endif 194 | 195 | #endif 196 | -------------------------------------------------------------------------------- /include/sse/blake2b-load-sse2.h: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - optimized C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | #ifndef BLAKE2B_LOAD_SSE2_H 16 | #define BLAKE2B_LOAD_SSE2_H 17 | 18 | #define LOAD_MSG_0_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4) 19 | #define LOAD_MSG_0_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5) 20 | #define LOAD_MSG_0_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12) 21 | #define LOAD_MSG_0_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13) 22 | #define LOAD_MSG_1_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9) 23 | #define LOAD_MSG_1_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15) 24 | #define LOAD_MSG_1_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11) 25 | #define LOAD_MSG_1_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7) 26 | #define LOAD_MSG_2_1(b0, b1) b0 = _mm_set_epi64x(m12, m11); b1 = _mm_set_epi64x(m15, m5) 27 | #define LOAD_MSG_2_2(b0, b1) b0 = _mm_set_epi64x(m0, m8); b1 = _mm_set_epi64x(m13, m2) 28 | #define LOAD_MSG_2_3(b0, b1) b0 = _mm_set_epi64x(m3, m10); b1 = _mm_set_epi64x(m9, m7) 29 | #define LOAD_MSG_2_4(b0, b1) b0 = _mm_set_epi64x(m6, m14); b1 = _mm_set_epi64x(m4, m1) 30 | #define LOAD_MSG_3_1(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m13) 31 | #define LOAD_MSG_3_2(b0, b1) b0 = _mm_set_epi64x(m1, m9); b1 = _mm_set_epi64x(m14, m12) 32 | #define LOAD_MSG_3_3(b0, b1) b0 = _mm_set_epi64x(m5, m2); b1 = _mm_set_epi64x(m15, m4) 33 | #define LOAD_MSG_3_4(b0, b1) b0 = _mm_set_epi64x(m10, m6); b1 = _mm_set_epi64x(m8, m0) 34 | #define LOAD_MSG_4_1(b0, b1) b0 = _mm_set_epi64x(m5, m9); b1 = _mm_set_epi64x(m10, m2) 35 | #define LOAD_MSG_4_2(b0, b1) b0 = _mm_set_epi64x(m7, m0); b1 = _mm_set_epi64x(m15, m4) 36 | #define LOAD_MSG_4_3(b0, b1) b0 = _mm_set_epi64x(m11, m14); b1 = _mm_set_epi64x(m3, m6) 37 | #define LOAD_MSG_4_4(b0, b1) b0 = _mm_set_epi64x(m12, m1); b1 = _mm_set_epi64x(m13, m8) 38 | #define LOAD_MSG_5_1(b0, b1) b0 = _mm_set_epi64x(m6, m2); b1 = _mm_set_epi64x(m8, m0) 39 | #define LOAD_MSG_5_2(b0, b1) b0 = _mm_set_epi64x(m10, m12); b1 = _mm_set_epi64x(m3, m11) 40 | #define LOAD_MSG_5_3(b0, b1) b0 = _mm_set_epi64x(m7, m4); b1 = _mm_set_epi64x(m1, m15) 41 | #define LOAD_MSG_5_4(b0, b1) b0 = _mm_set_epi64x(m5, m13); b1 = _mm_set_epi64x(m9, m14) 42 | #define LOAD_MSG_6_1(b0, b1) b0 = _mm_set_epi64x(m1, m12); b1 = _mm_set_epi64x(m4, m14) 43 | #define LOAD_MSG_6_2(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m10, m13) 44 | #define LOAD_MSG_6_3(b0, b1) b0 = _mm_set_epi64x(m6, m0); b1 = _mm_set_epi64x(m8, m9) 45 | #define LOAD_MSG_6_4(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m2) 46 | #define LOAD_MSG_7_1(b0, b1) b0 = _mm_set_epi64x(m7, m13); b1 = _mm_set_epi64x(m3, m12) 47 | #define LOAD_MSG_7_2(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m9, m1) 48 | #define LOAD_MSG_7_3(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m2, m8) 49 | #define LOAD_MSG_7_4(b0, b1) b0 = _mm_set_epi64x(m4, m0); b1 = _mm_set_epi64x(m10, m6) 50 | #define LOAD_MSG_8_1(b0, b1) b0 = _mm_set_epi64x(m14, m6); b1 = _mm_set_epi64x(m0, m11) 51 | #define LOAD_MSG_8_2(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m8, m3) 52 | #define LOAD_MSG_8_3(b0, b1) b0 = _mm_set_epi64x(m13, m12); b1 = _mm_set_epi64x(m10, m1) 53 | #define LOAD_MSG_8_4(b0, b1) b0 = _mm_set_epi64x(m7, m2); b1 = _mm_set_epi64x(m5, m4) 54 | #define LOAD_MSG_9_1(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m1, m7) 55 | #define LOAD_MSG_9_2(b0, b1) b0 = _mm_set_epi64x(m4, m2); b1 = _mm_set_epi64x(m5, m6) 56 | #define LOAD_MSG_9_3(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m13, m3) 57 | #define LOAD_MSG_9_4(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m0, m12) 58 | #define LOAD_MSG_10_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4) 59 | #define LOAD_MSG_10_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5) 60 | #define LOAD_MSG_10_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12) 61 | #define LOAD_MSG_10_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13) 62 | #define LOAD_MSG_11_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9) 63 | #define LOAD_MSG_11_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15) 64 | #define LOAD_MSG_11_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11) 65 | #define LOAD_MSG_11_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7) 66 | 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /include/sse/blake2b-load-sse41.h: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - optimized C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | #ifndef BLAKE2B_LOAD_SSE41_H 16 | #define BLAKE2B_LOAD_SSE41_H 17 | 18 | #define LOAD_MSG_0_1(b0, b1) \ 19 | do \ 20 | { \ 21 | b0 = _mm_unpacklo_epi64(m0, m1); \ 22 | b1 = _mm_unpacklo_epi64(m2, m3); \ 23 | } while(0) 24 | 25 | 26 | #define LOAD_MSG_0_2(b0, b1) \ 27 | do \ 28 | { \ 29 | b0 = _mm_unpackhi_epi64(m0, m1); \ 30 | b1 = _mm_unpackhi_epi64(m2, m3); \ 31 | } while(0) 32 | 33 | 34 | #define LOAD_MSG_0_3(b0, b1) \ 35 | do \ 36 | { \ 37 | b0 = _mm_unpacklo_epi64(m4, m5); \ 38 | b1 = _mm_unpacklo_epi64(m6, m7); \ 39 | } while(0) 40 | 41 | 42 | #define LOAD_MSG_0_4(b0, b1) \ 43 | do \ 44 | { \ 45 | b0 = _mm_unpackhi_epi64(m4, m5); \ 46 | b1 = _mm_unpackhi_epi64(m6, m7); \ 47 | } while(0) 48 | 49 | 50 | #define LOAD_MSG_1_1(b0, b1) \ 51 | do \ 52 | { \ 53 | b0 = _mm_unpacklo_epi64(m7, m2); \ 54 | b1 = _mm_unpackhi_epi64(m4, m6); \ 55 | } while(0) 56 | 57 | 58 | #define LOAD_MSG_1_2(b0, b1) \ 59 | do \ 60 | { \ 61 | b0 = _mm_unpacklo_epi64(m5, m4); \ 62 | b1 = _mm_alignr_epi8(m3, m7, 8); \ 63 | } while(0) 64 | 65 | 66 | #define LOAD_MSG_1_3(b0, b1) \ 67 | do \ 68 | { \ 69 | b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \ 70 | b1 = _mm_unpackhi_epi64(m5, m2); \ 71 | } while(0) 72 | 73 | 74 | #define LOAD_MSG_1_4(b0, b1) \ 75 | do \ 76 | { \ 77 | b0 = _mm_unpacklo_epi64(m6, m1); \ 78 | b1 = _mm_unpackhi_epi64(m3, m1); \ 79 | } while(0) 80 | 81 | 82 | #define LOAD_MSG_2_1(b0, b1) \ 83 | do \ 84 | { \ 85 | b0 = _mm_alignr_epi8(m6, m5, 8); \ 86 | b1 = _mm_unpackhi_epi64(m2, m7); \ 87 | } while(0) 88 | 89 | 90 | #define LOAD_MSG_2_2(b0, b1) \ 91 | do \ 92 | { \ 93 | b0 = _mm_unpacklo_epi64(m4, m0); \ 94 | b1 = _mm_blend_epi16(m1, m6, 0xF0); \ 95 | } while(0) 96 | 97 | 98 | #define LOAD_MSG_2_3(b0, b1) \ 99 | do \ 100 | { \ 101 | b0 = _mm_blend_epi16(m5, m1, 0xF0); \ 102 | b1 = _mm_unpackhi_epi64(m3, m4); \ 103 | } while(0) 104 | 105 | 106 | #define LOAD_MSG_2_4(b0, b1) \ 107 | do \ 108 | { \ 109 | b0 = _mm_unpacklo_epi64(m7, m3); \ 110 | b1 = _mm_alignr_epi8(m2, m0, 8); \ 111 | } while(0) 112 | 113 | 114 | #define LOAD_MSG_3_1(b0, b1) \ 115 | do \ 116 | { \ 117 | b0 = _mm_unpackhi_epi64(m3, m1); \ 118 | b1 = _mm_unpackhi_epi64(m6, m5); \ 119 | } while(0) 120 | 121 | 122 | #define LOAD_MSG_3_2(b0, b1) \ 123 | do \ 124 | { \ 125 | b0 = _mm_unpackhi_epi64(m4, m0); \ 126 | b1 = _mm_unpacklo_epi64(m6, m7); \ 127 | } while(0) 128 | 129 | 130 | #define LOAD_MSG_3_3(b0, b1) \ 131 | do \ 132 | { \ 133 | b0 = _mm_blend_epi16(m1, m2, 0xF0); \ 134 | b1 = _mm_blend_epi16(m2, m7, 0xF0); \ 135 | } while(0) 136 | 137 | 138 | #define LOAD_MSG_3_4(b0, b1) \ 139 | do \ 140 | { \ 141 | b0 = _mm_unpacklo_epi64(m3, m5); \ 142 | b1 = _mm_unpacklo_epi64(m0, m4); \ 143 | } while(0) 144 | 145 | 146 | #define LOAD_MSG_4_1(b0, b1) \ 147 | do \ 148 | { \ 149 | b0 = _mm_unpackhi_epi64(m4, m2); \ 150 | b1 = _mm_unpacklo_epi64(m1, m5); \ 151 | } while(0) 152 | 153 | 154 | #define LOAD_MSG_4_2(b0, b1) \ 155 | do \ 156 | { \ 157 | b0 = _mm_blend_epi16(m0, m3, 0xF0); \ 158 | b1 = _mm_blend_epi16(m2, m7, 0xF0); \ 159 | } while(0) 160 | 161 | 162 | #define LOAD_MSG_4_3(b0, b1) \ 163 | do \ 164 | { \ 165 | b0 = _mm_blend_epi16(m7, m5, 0xF0); \ 166 | b1 = _mm_blend_epi16(m3, m1, 0xF0); \ 167 | } while(0) 168 | 169 | 170 | #define LOAD_MSG_4_4(b0, b1) \ 171 | do \ 172 | { \ 173 | b0 = _mm_alignr_epi8(m6, m0, 8); \ 174 | b1 = _mm_blend_epi16(m4, m6, 0xF0); \ 175 | } while(0) 176 | 177 | 178 | #define LOAD_MSG_5_1(b0, b1) \ 179 | do \ 180 | { \ 181 | b0 = _mm_unpacklo_epi64(m1, m3); \ 182 | b1 = _mm_unpacklo_epi64(m0, m4); \ 183 | } while(0) 184 | 185 | 186 | #define LOAD_MSG_5_2(b0, b1) \ 187 | do \ 188 | { \ 189 | b0 = _mm_unpacklo_epi64(m6, m5); \ 190 | b1 = _mm_unpackhi_epi64(m5, m1); \ 191 | } while(0) 192 | 193 | 194 | #define LOAD_MSG_5_3(b0, b1) \ 195 | do \ 196 | { \ 197 | b0 = _mm_blend_epi16(m2, m3, 0xF0); \ 198 | b1 = _mm_unpackhi_epi64(m7, m0); \ 199 | } while(0) 200 | 201 | 202 | #define LOAD_MSG_5_4(b0, b1) \ 203 | do \ 204 | { \ 205 | b0 = _mm_unpackhi_epi64(m6, m2); \ 206 | b1 = _mm_blend_epi16(m7, m4, 0xF0); \ 207 | } while(0) 208 | 209 | 210 | #define LOAD_MSG_6_1(b0, b1) \ 211 | do \ 212 | { \ 213 | b0 = _mm_blend_epi16(m6, m0, 0xF0); \ 214 | b1 = _mm_unpacklo_epi64(m7, m2); \ 215 | } while(0) 216 | 217 | 218 | #define LOAD_MSG_6_2(b0, b1) \ 219 | do \ 220 | { \ 221 | b0 = _mm_unpackhi_epi64(m2, m7); \ 222 | b1 = _mm_alignr_epi8(m5, m6, 8); \ 223 | } while(0) 224 | 225 | 226 | #define LOAD_MSG_6_3(b0, b1) \ 227 | do \ 228 | { \ 229 | b0 = _mm_unpacklo_epi64(m0, m3); \ 230 | b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1,0,3,2)); \ 231 | } while(0) 232 | 233 | 234 | #define LOAD_MSG_6_4(b0, b1) \ 235 | do \ 236 | { \ 237 | b0 = _mm_unpackhi_epi64(m3, m1); \ 238 | b1 = _mm_blend_epi16(m1, m5, 0xF0); \ 239 | } while(0) 240 | 241 | 242 | #define LOAD_MSG_7_1(b0, b1) \ 243 | do \ 244 | { \ 245 | b0 = _mm_unpackhi_epi64(m6, m3); \ 246 | b1 = _mm_blend_epi16(m6, m1, 0xF0); \ 247 | } while(0) 248 | 249 | 250 | #define LOAD_MSG_7_2(b0, b1) \ 251 | do \ 252 | { \ 253 | b0 = _mm_alignr_epi8(m7, m5, 8); \ 254 | b1 = _mm_unpackhi_epi64(m0, m4); \ 255 | } while(0) 256 | 257 | 258 | #define LOAD_MSG_7_3(b0, b1) \ 259 | do \ 260 | { \ 261 | b0 = _mm_unpackhi_epi64(m2, m7); \ 262 | b1 = _mm_unpacklo_epi64(m4, m1); \ 263 | } while(0) 264 | 265 | 266 | #define LOAD_MSG_7_4(b0, b1) \ 267 | do \ 268 | { \ 269 | b0 = _mm_unpacklo_epi64(m0, m2); \ 270 | b1 = _mm_unpacklo_epi64(m3, m5); \ 271 | } while(0) 272 | 273 | 274 | #define LOAD_MSG_8_1(b0, b1) \ 275 | do \ 276 | { \ 277 | b0 = _mm_unpacklo_epi64(m3, m7); \ 278 | b1 = _mm_alignr_epi8(m0, m5, 8); \ 279 | } while(0) 280 | 281 | 282 | #define LOAD_MSG_8_2(b0, b1) \ 283 | do \ 284 | { \ 285 | b0 = _mm_unpackhi_epi64(m7, m4); \ 286 | b1 = _mm_alignr_epi8(m4, m1, 8); \ 287 | } while(0) 288 | 289 | 290 | #define LOAD_MSG_8_3(b0, b1) \ 291 | do \ 292 | { \ 293 | b0 = m6; \ 294 | b1 = _mm_alignr_epi8(m5, m0, 8); \ 295 | } while(0) 296 | 297 | 298 | #define LOAD_MSG_8_4(b0, b1) \ 299 | do \ 300 | { \ 301 | b0 = _mm_blend_epi16(m1, m3, 0xF0); \ 302 | b1 = m2; \ 303 | } while(0) 304 | 305 | 306 | #define LOAD_MSG_9_1(b0, b1) \ 307 | do \ 308 | { \ 309 | b0 = _mm_unpacklo_epi64(m5, m4); \ 310 | b1 = _mm_unpackhi_epi64(m3, m0); \ 311 | } while(0) 312 | 313 | 314 | #define LOAD_MSG_9_2(b0, b1) \ 315 | do \ 316 | { \ 317 | b0 = _mm_unpacklo_epi64(m1, m2); \ 318 | b1 = _mm_blend_epi16(m3, m2, 0xF0); \ 319 | } while(0) 320 | 321 | 322 | #define LOAD_MSG_9_3(b0, b1) \ 323 | do \ 324 | { \ 325 | b0 = _mm_unpackhi_epi64(m7, m4); \ 326 | b1 = _mm_unpackhi_epi64(m1, m6); \ 327 | } while(0) 328 | 329 | 330 | #define LOAD_MSG_9_4(b0, b1) \ 331 | do \ 332 | { \ 333 | b0 = _mm_alignr_epi8(m7, m5, 8); \ 334 | b1 = _mm_unpacklo_epi64(m6, m0); \ 335 | } while(0) 336 | 337 | 338 | #define LOAD_MSG_10_1(b0, b1) \ 339 | do \ 340 | { \ 341 | b0 = _mm_unpacklo_epi64(m0, m1); \ 342 | b1 = _mm_unpacklo_epi64(m2, m3); \ 343 | } while(0) 344 | 345 | 346 | #define LOAD_MSG_10_2(b0, b1) \ 347 | do \ 348 | { \ 349 | b0 = _mm_unpackhi_epi64(m0, m1); \ 350 | b1 = _mm_unpackhi_epi64(m2, m3); \ 351 | } while(0) 352 | 353 | 354 | #define LOAD_MSG_10_3(b0, b1) \ 355 | do \ 356 | { \ 357 | b0 = _mm_unpacklo_epi64(m4, m5); \ 358 | b1 = _mm_unpacklo_epi64(m6, m7); \ 359 | } while(0) 360 | 361 | 362 | #define LOAD_MSG_10_4(b0, b1) \ 363 | do \ 364 | { \ 365 | b0 = _mm_unpackhi_epi64(m4, m5); \ 366 | b1 = _mm_unpackhi_epi64(m6, m7); \ 367 | } while(0) 368 | 369 | 370 | #define LOAD_MSG_11_1(b0, b1) \ 371 | do \ 372 | { \ 373 | b0 = _mm_unpacklo_epi64(m7, m2); \ 374 | b1 = _mm_unpackhi_epi64(m4, m6); \ 375 | } while(0) 376 | 377 | 378 | #define LOAD_MSG_11_2(b0, b1) \ 379 | do \ 380 | { \ 381 | b0 = _mm_unpacklo_epi64(m5, m4); \ 382 | b1 = _mm_alignr_epi8(m3, m7, 8); \ 383 | } while(0) 384 | 385 | 386 | #define LOAD_MSG_11_3(b0, b1) \ 387 | do \ 388 | { \ 389 | b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \ 390 | b1 = _mm_unpackhi_epi64(m5, m2); \ 391 | } while(0) 392 | 393 | 394 | #define LOAD_MSG_11_4(b0, b1) \ 395 | do \ 396 | { \ 397 | b0 = _mm_unpacklo_epi64(m6, m1); \ 398 | b1 = _mm_unpackhi_epi64(m3, m1); \ 399 | } while(0) 400 | 401 | 402 | #endif 403 | -------------------------------------------------------------------------------- /include/sse/blake2b-round.h: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - optimized C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | #ifndef BLAKE2B_ROUND_H 16 | #define BLAKE2B_ROUND_H 17 | 18 | #define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) ) 19 | #define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) 20 | 21 | #define TOF(reg) _mm_castsi128_ps((reg)) 22 | #define TOI(reg) _mm_castps_si128((reg)) 23 | 24 | #define LIKELY(x) __builtin_expect((x),1) 25 | 26 | 27 | /* Microarchitecture-specific macros */ 28 | #ifndef HAVE_XOP 29 | #ifdef HAVE_SSSE3 30 | #define _mm_roti_epi64(x, c) \ 31 | (-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \ 32 | : (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \ 33 | : (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \ 34 | : (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \ 35 | : _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c)))) 36 | #else 37 | #define _mm_roti_epi64(r, c) _mm_xor_si128(_mm_srli_epi64( (r), -(c) ),_mm_slli_epi64( (r), 64-(-(c)) )) 38 | #endif 39 | #else 40 | /* ... */ 41 | #endif 42 | 43 | 44 | 45 | #define G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ 46 | row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ 47 | row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ 48 | \ 49 | row4l = _mm_xor_si128(row4l, row1l); \ 50 | row4h = _mm_xor_si128(row4h, row1h); \ 51 | \ 52 | row4l = _mm_roti_epi64(row4l, -32); \ 53 | row4h = _mm_roti_epi64(row4h, -32); \ 54 | \ 55 | row3l = _mm_add_epi64(row3l, row4l); \ 56 | row3h = _mm_add_epi64(row3h, row4h); \ 57 | \ 58 | row2l = _mm_xor_si128(row2l, row3l); \ 59 | row2h = _mm_xor_si128(row2h, row3h); \ 60 | \ 61 | row2l = _mm_roti_epi64(row2l, -24); \ 62 | row2h = _mm_roti_epi64(row2h, -24); \ 63 | 64 | #define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ 65 | row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ 66 | row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ 67 | \ 68 | row4l = _mm_xor_si128(row4l, row1l); \ 69 | row4h = _mm_xor_si128(row4h, row1h); \ 70 | \ 71 | row4l = _mm_roti_epi64(row4l, -16); \ 72 | row4h = _mm_roti_epi64(row4h, -16); \ 73 | \ 74 | row3l = _mm_add_epi64(row3l, row4l); \ 75 | row3h = _mm_add_epi64(row3h, row4h); \ 76 | \ 77 | row2l = _mm_xor_si128(row2l, row3l); \ 78 | row2h = _mm_xor_si128(row2h, row3h); \ 79 | \ 80 | row2l = _mm_roti_epi64(row2l, -63); \ 81 | row2h = _mm_roti_epi64(row2h, -63); \ 82 | 83 | #if defined(HAVE_SSSE3) 84 | #define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ 85 | t0 = _mm_alignr_epi8(row2h, row2l, 8); \ 86 | t1 = _mm_alignr_epi8(row2l, row2h, 8); \ 87 | row2l = t0; \ 88 | row2h = t1; \ 89 | \ 90 | t0 = row3l; \ 91 | row3l = row3h; \ 92 | row3h = t0; \ 93 | \ 94 | t0 = _mm_alignr_epi8(row4h, row4l, 8); \ 95 | t1 = _mm_alignr_epi8(row4l, row4h, 8); \ 96 | row4l = t1; \ 97 | row4h = t0; 98 | 99 | #define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ 100 | t0 = _mm_alignr_epi8(row2l, row2h, 8); \ 101 | t1 = _mm_alignr_epi8(row2h, row2l, 8); \ 102 | row2l = t0; \ 103 | row2h = t1; \ 104 | \ 105 | t0 = row3l; \ 106 | row3l = row3h; \ 107 | row3h = t0; \ 108 | \ 109 | t0 = _mm_alignr_epi8(row4l, row4h, 8); \ 110 | t1 = _mm_alignr_epi8(row4h, row4l, 8); \ 111 | row4l = t1; \ 112 | row4h = t0; 113 | #else 114 | 115 | #define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ 116 | t0 = row4l;\ 117 | t1 = row2l;\ 118 | row4l = row3l;\ 119 | row3l = row3h;\ 120 | row3h = row4l;\ 121 | row4l = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t0, t0)); \ 122 | row4h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row4h, row4h)); \ 123 | row2l = _mm_unpackhi_epi64(row2l, _mm_unpacklo_epi64(row2h, row2h)); \ 124 | row2h = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(t1, t1)) 125 | 126 | #define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ 127 | t0 = row3l;\ 128 | row3l = row3h;\ 129 | row3h = t0;\ 130 | t0 = row2l;\ 131 | t1 = row4l;\ 132 | row2l = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(row2l, row2l)); \ 133 | row2h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row2h, row2h)); \ 134 | row4l = _mm_unpackhi_epi64(row4l, _mm_unpacklo_epi64(row4h, row4h)); \ 135 | row4h = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t1, t1)) 136 | 137 | #endif 138 | 139 | #if defined(HAVE_SSE41) 140 | #include "blake2b-load-sse41.h" 141 | #else 142 | #include "blake2b-load-sse2.h" 143 | #endif 144 | 145 | #define ROUND(r) \ 146 | LOAD_MSG_ ##r ##_1(b0, b1); \ 147 | G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ 148 | LOAD_MSG_ ##r ##_2(b0, b1); \ 149 | G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ 150 | DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ 151 | LOAD_MSG_ ##r ##_3(b0, b1); \ 152 | G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ 153 | LOAD_MSG_ ##r ##_4(b0, b1); \ 154 | G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ 155 | UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); 156 | 157 | #endif 158 | -------------------------------------------------------------------------------- /include/sse/blake2s-load-sse2.h: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - optimized C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | #ifndef BLAKE2S_LOAD_SSE2_H 16 | #define BLAKE2S_LOAD_SSE2_H 17 | 18 | #define LOAD_MSG_0_1(buf) buf = _mm_set_epi32(m6,m4,m2,m0) 19 | #define LOAD_MSG_0_2(buf) buf = _mm_set_epi32(m7,m5,m3,m1) 20 | #define LOAD_MSG_0_3(buf) buf = _mm_set_epi32(m14,m12,m10,m8) 21 | #define LOAD_MSG_0_4(buf) buf = _mm_set_epi32(m15,m13,m11,m9) 22 | #define LOAD_MSG_1_1(buf) buf = _mm_set_epi32(m13,m9,m4,m14) 23 | #define LOAD_MSG_1_2(buf) buf = _mm_set_epi32(m6,m15,m8,m10) 24 | #define LOAD_MSG_1_3(buf) buf = _mm_set_epi32(m5,m11,m0,m1) 25 | #define LOAD_MSG_1_4(buf) buf = _mm_set_epi32(m3,m7,m2,m12) 26 | #define LOAD_MSG_2_1(buf) buf = _mm_set_epi32(m15,m5,m12,m11) 27 | #define LOAD_MSG_2_2(buf) buf = _mm_set_epi32(m13,m2,m0,m8) 28 | #define LOAD_MSG_2_3(buf) buf = _mm_set_epi32(m9,m7,m3,m10) 29 | #define LOAD_MSG_2_4(buf) buf = _mm_set_epi32(m4,m1,m6,m14) 30 | #define LOAD_MSG_3_1(buf) buf = _mm_set_epi32(m11,m13,m3,m7) 31 | #define LOAD_MSG_3_2(buf) buf = _mm_set_epi32(m14,m12,m1,m9) 32 | #define LOAD_MSG_3_3(buf) buf = _mm_set_epi32(m15,m4,m5,m2) 33 | #define LOAD_MSG_3_4(buf) buf = _mm_set_epi32(m8,m0,m10,m6) 34 | #define LOAD_MSG_4_1(buf) buf = _mm_set_epi32(m10,m2,m5,m9) 35 | #define LOAD_MSG_4_2(buf) buf = _mm_set_epi32(m15,m4,m7,m0) 36 | #define LOAD_MSG_4_3(buf) buf = _mm_set_epi32(m3,m6,m11,m14) 37 | #define LOAD_MSG_4_4(buf) buf = _mm_set_epi32(m13,m8,m12,m1) 38 | #define LOAD_MSG_5_1(buf) buf = _mm_set_epi32(m8,m0,m6,m2) 39 | #define LOAD_MSG_5_2(buf) buf = _mm_set_epi32(m3,m11,m10,m12) 40 | #define LOAD_MSG_5_3(buf) buf = _mm_set_epi32(m1,m15,m7,m4) 41 | #define LOAD_MSG_5_4(buf) buf = _mm_set_epi32(m9,m14,m5,m13) 42 | #define LOAD_MSG_6_1(buf) buf = _mm_set_epi32(m4,m14,m1,m12) 43 | #define LOAD_MSG_6_2(buf) buf = _mm_set_epi32(m10,m13,m15,m5) 44 | #define LOAD_MSG_6_3(buf) buf = _mm_set_epi32(m8,m9,m6,m0) 45 | #define LOAD_MSG_6_4(buf) buf = _mm_set_epi32(m11,m2,m3,m7) 46 | #define LOAD_MSG_7_1(buf) buf = _mm_set_epi32(m3,m12,m7,m13) 47 | #define LOAD_MSG_7_2(buf) buf = _mm_set_epi32(m9,m1,m14,m11) 48 | #define LOAD_MSG_7_3(buf) buf = _mm_set_epi32(m2,m8,m15,m5) 49 | #define LOAD_MSG_7_4(buf) buf = _mm_set_epi32(m10,m6,m4,m0) 50 | #define LOAD_MSG_8_1(buf) buf = _mm_set_epi32(m0,m11,m14,m6) 51 | #define LOAD_MSG_8_2(buf) buf = _mm_set_epi32(m8,m3,m9,m15) 52 | #define LOAD_MSG_8_3(buf) buf = _mm_set_epi32(m10,m1,m13,m12) 53 | #define LOAD_MSG_8_4(buf) buf = _mm_set_epi32(m5,m4,m7,m2) 54 | #define LOAD_MSG_9_1(buf) buf = _mm_set_epi32(m1,m7,m8,m10) 55 | #define LOAD_MSG_9_2(buf) buf = _mm_set_epi32(m5,m6,m4,m2) 56 | #define LOAD_MSG_9_3(buf) buf = _mm_set_epi32(m13,m3,m9,m15) 57 | #define LOAD_MSG_9_4(buf) buf = _mm_set_epi32(m0,m12,m14,m11) 58 | 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /include/sse/blake2s-load-sse41.h: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - optimized C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | #ifndef BLAKE2S_LOAD_SSE41_H 16 | #define BLAKE2S_LOAD_SSE41_H 17 | 18 | #define LOAD_MSG_0_1(buf) \ 19 | buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(2,0,2,0))); 20 | 21 | #define LOAD_MSG_0_2(buf) \ 22 | buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(3,1,3,1))); 23 | 24 | #define LOAD_MSG_0_3(buf) \ 25 | buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(2,0,2,0))); 26 | 27 | #define LOAD_MSG_0_4(buf) \ 28 | buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(3,1,3,1))); 29 | 30 | #define LOAD_MSG_1_1(buf) \ 31 | t0 = _mm_blend_epi16(m1, m2, 0x0C); \ 32 | t1 = _mm_slli_si128(m3, 4); \ 33 | t2 = _mm_blend_epi16(t0, t1, 0xF0); \ 34 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3)); 35 | 36 | #define LOAD_MSG_1_2(buf) \ 37 | t0 = _mm_shuffle_epi32(m2,_MM_SHUFFLE(0,0,2,0)); \ 38 | t1 = _mm_blend_epi16(m1,m3,0xC0); \ 39 | t2 = _mm_blend_epi16(t0, t1, 0xF0); \ 40 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); 41 | 42 | #define LOAD_MSG_1_3(buf) \ 43 | t0 = _mm_slli_si128(m1, 4); \ 44 | t1 = _mm_blend_epi16(m2, t0, 0x30); \ 45 | t2 = _mm_blend_epi16(m0, t1, 0xF0); \ 46 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); 47 | 48 | #define LOAD_MSG_1_4(buf) \ 49 | t0 = _mm_unpackhi_epi32(m0,m1); \ 50 | t1 = _mm_slli_si128(m3, 4); \ 51 | t2 = _mm_blend_epi16(t0, t1, 0x0C); \ 52 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); 53 | 54 | #define LOAD_MSG_2_1(buf) \ 55 | t0 = _mm_unpackhi_epi32(m2,m3); \ 56 | t1 = _mm_blend_epi16(m3,m1,0x0C); \ 57 | t2 = _mm_blend_epi16(t0, t1, 0x0F); \ 58 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); 59 | 60 | #define LOAD_MSG_2_2(buf) \ 61 | t0 = _mm_unpacklo_epi32(m2,m0); \ 62 | t1 = _mm_blend_epi16(t0, m0, 0xF0); \ 63 | t2 = _mm_slli_si128(m3, 8); \ 64 | buf = _mm_blend_epi16(t1, t2, 0xC0); 65 | 66 | #define LOAD_MSG_2_3(buf) \ 67 | t0 = _mm_blend_epi16(m0, m2, 0x3C); \ 68 | t1 = _mm_srli_si128(m1, 12); \ 69 | t2 = _mm_blend_epi16(t0,t1,0x03); \ 70 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,3,2)); 71 | 72 | #define LOAD_MSG_2_4(buf) \ 73 | t0 = _mm_slli_si128(m3, 4); \ 74 | t1 = _mm_blend_epi16(m0, m1, 0x33); \ 75 | t2 = _mm_blend_epi16(t1, t0, 0xC0); \ 76 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(0,1,2,3)); 77 | 78 | #define LOAD_MSG_3_1(buf) \ 79 | t0 = _mm_unpackhi_epi32(m0,m1); \ 80 | t1 = _mm_unpackhi_epi32(t0, m2); \ 81 | t2 = _mm_blend_epi16(t1, m3, 0x0C); \ 82 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); 83 | 84 | #define LOAD_MSG_3_2(buf) \ 85 | t0 = _mm_slli_si128(m2, 8); \ 86 | t1 = _mm_blend_epi16(m3,m0,0x0C); \ 87 | t2 = _mm_blend_epi16(t1, t0, 0xC0); \ 88 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); 89 | 90 | #define LOAD_MSG_3_3(buf) \ 91 | t0 = _mm_blend_epi16(m0,m1,0x0F); \ 92 | t1 = _mm_blend_epi16(t0, m3, 0xC0); \ 93 | buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2)); 94 | 95 | #define LOAD_MSG_3_4(buf) \ 96 | t0 = _mm_unpacklo_epi32(m0,m2); \ 97 | t1 = _mm_unpackhi_epi32(m1,m2); \ 98 | buf = _mm_unpacklo_epi64(t1,t0); 99 | 100 | #define LOAD_MSG_4_1(buf) \ 101 | t0 = _mm_unpacklo_epi64(m1,m2); \ 102 | t1 = _mm_unpackhi_epi64(m0,m2); \ 103 | t2 = _mm_blend_epi16(t0,t1,0x33); \ 104 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); 105 | 106 | #define LOAD_MSG_4_2(buf) \ 107 | t0 = _mm_unpackhi_epi64(m1,m3); \ 108 | t1 = _mm_unpacklo_epi64(m0,m1); \ 109 | buf = _mm_blend_epi16(t0,t1,0x33); 110 | 111 | #define LOAD_MSG_4_3(buf) \ 112 | t0 = _mm_unpackhi_epi64(m3,m1); \ 113 | t1 = _mm_unpackhi_epi64(m2,m0); \ 114 | buf = _mm_blend_epi16(t1,t0,0x33); 115 | 116 | #define LOAD_MSG_4_4(buf) \ 117 | t0 = _mm_blend_epi16(m0,m2,0x03); \ 118 | t1 = _mm_slli_si128(t0, 8); \ 119 | t2 = _mm_blend_epi16(t1,m3,0x0F); \ 120 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,0,3)); 121 | 122 | #define LOAD_MSG_5_1(buf) \ 123 | t0 = _mm_unpackhi_epi32(m0,m1); \ 124 | t1 = _mm_unpacklo_epi32(m0,m2); \ 125 | buf = _mm_unpacklo_epi64(t0,t1); 126 | 127 | #define LOAD_MSG_5_2(buf) \ 128 | t0 = _mm_srli_si128(m2, 4); \ 129 | t1 = _mm_blend_epi16(m0,m3,0x03); \ 130 | buf = _mm_blend_epi16(t1,t0,0x3C); 131 | 132 | #define LOAD_MSG_5_3(buf) \ 133 | t0 = _mm_blend_epi16(m1,m0,0x0C); \ 134 | t1 = _mm_srli_si128(m3, 4); \ 135 | t2 = _mm_blend_epi16(t0,t1,0x30); \ 136 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,3,0)); 137 | 138 | #define LOAD_MSG_5_4(buf) \ 139 | t0 = _mm_unpacklo_epi64(m1,m2); \ 140 | t1= _mm_shuffle_epi32(m3, _MM_SHUFFLE(0,2,0,1)); \ 141 | buf = _mm_blend_epi16(t0,t1,0x33); 142 | 143 | #define LOAD_MSG_6_1(buf) \ 144 | t0 = _mm_slli_si128(m1, 12); \ 145 | t1 = _mm_blend_epi16(m0,m3,0x33); \ 146 | buf = _mm_blend_epi16(t1,t0,0xC0); 147 | 148 | #define LOAD_MSG_6_2(buf) \ 149 | t0 = _mm_blend_epi16(m3,m2,0x30); \ 150 | t1 = _mm_srli_si128(m1, 4); \ 151 | t2 = _mm_blend_epi16(t0,t1,0x03); \ 152 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,3,0)); 153 | 154 | #define LOAD_MSG_6_3(buf) \ 155 | t0 = _mm_unpacklo_epi64(m0,m2); \ 156 | t1 = _mm_srli_si128(m1, 4); \ 157 | buf = _mm_shuffle_epi32(_mm_blend_epi16(t0,t1,0x0C), _MM_SHUFFLE(2,3,1,0)); 158 | 159 | #define LOAD_MSG_6_4(buf) \ 160 | t0 = _mm_unpackhi_epi32(m1,m2); \ 161 | t1 = _mm_unpackhi_epi64(m0,t0); \ 162 | buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2)); 163 | 164 | #define LOAD_MSG_7_1(buf) \ 165 | t0 = _mm_unpackhi_epi32(m0,m1); \ 166 | t1 = _mm_blend_epi16(t0,m3,0x0F); \ 167 | buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(2,0,3,1)); 168 | 169 | #define LOAD_MSG_7_2(buf) \ 170 | t0 = _mm_blend_epi16(m2,m3,0x30); \ 171 | t1 = _mm_srli_si128(m0,4); \ 172 | t2 = _mm_blend_epi16(t0,t1,0x03); \ 173 | buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,2,3)); 174 | 175 | #define LOAD_MSG_7_3(buf) \ 176 | t0 = _mm_unpackhi_epi64(m0,m3); \ 177 | t1 = _mm_unpacklo_epi64(m1,m2); \ 178 | t2 = _mm_blend_epi16(t0,t1,0x3C); \ 179 | buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,2,3,1)); 180 | 181 | #define LOAD_MSG_7_4(buf) \ 182 | t0 = _mm_unpacklo_epi32(m0,m1); \ 183 | t1 = _mm_unpackhi_epi32(m1,m2); \ 184 | buf = _mm_unpacklo_epi64(t0,t1); 185 | 186 | #define LOAD_MSG_8_1(buf) \ 187 | t0 = _mm_unpackhi_epi32(m1,m3); \ 188 | t1 = _mm_unpacklo_epi64(t0,m0); \ 189 | t2 = _mm_blend_epi16(t1,m2,0xC0); \ 190 | buf = _mm_shufflehi_epi16(t2,_MM_SHUFFLE(1,0,3,2)); 191 | 192 | #define LOAD_MSG_8_2(buf) \ 193 | t0 = _mm_unpackhi_epi32(m0,m3); \ 194 | t1 = _mm_blend_epi16(m2,t0,0xF0); \ 195 | buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(0,2,1,3)); 196 | 197 | #define LOAD_MSG_8_3(buf) \ 198 | t0 = _mm_blend_epi16(m2,m0,0x0C); \ 199 | t1 = _mm_slli_si128(t0,4); \ 200 | buf = _mm_blend_epi16(t1,m3,0x0F); 201 | 202 | #define LOAD_MSG_8_4(buf) \ 203 | t0 = _mm_blend_epi16(m1,m0,0x30); \ 204 | buf = _mm_shuffle_epi32(t0,_MM_SHUFFLE(1,0,3,2)); 205 | 206 | #define LOAD_MSG_9_1(buf) \ 207 | t0 = _mm_blend_epi16(m0,m2,0x03); \ 208 | t1 = _mm_blend_epi16(m1,m2,0x30); \ 209 | t2 = _mm_blend_epi16(t1,t0,0x0F); \ 210 | buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(1,3,0,2)); 211 | 212 | #define LOAD_MSG_9_2(buf) \ 213 | t0 = _mm_slli_si128(m0,4); \ 214 | t1 = _mm_blend_epi16(m1,t0,0xC0); \ 215 | buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(1,2,0,3)); 216 | 217 | #define LOAD_MSG_9_3(buf) \ 218 | t0 = _mm_unpackhi_epi32(m0,m3); \ 219 | t1 = _mm_unpacklo_epi32(m2,m3); \ 220 | t2 = _mm_unpackhi_epi64(t0,t1); \ 221 | buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(3,0,2,1)); 222 | 223 | #define LOAD_MSG_9_4(buf) \ 224 | t0 = _mm_blend_epi16(m3,m2,0xC0); \ 225 | t1 = _mm_unpacklo_epi32(m0,m3); \ 226 | t2 = _mm_blend_epi16(t0,t1,0x0F); \ 227 | buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,1,2,3)); 228 | 229 | #endif 230 | -------------------------------------------------------------------------------- /include/sse/blake2s-load-xop.h: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - optimized C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | #ifndef BLAKE2S_LOAD_XOP_H 16 | #define BLAKE2S_LOAD_XOP_H 17 | 18 | #define TOB(x) ((x)*4*0x01010101 + 0x03020100) /* ..or not TOB */ 19 | 20 | #if 0 21 | /* Basic VPPERM emulation, for testing purposes */ 22 | static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel) 23 | { 24 | const __m128i sixteen = _mm_set1_epi8(16); 25 | const __m128i t0 = _mm_shuffle_epi8(src1, sel); 26 | const __m128i s1 = _mm_shuffle_epi8(src2, _mm_sub_epi8(sel, sixteen)); 27 | const __m128i mask = _mm_or_si128(_mm_cmpeq_epi8(sel, sixteen), 28 | _mm_cmpgt_epi8(sel, sixteen)); /* (>=16) = 0xff : 00 */ 29 | return _mm_blendv_epi8(t0, s1, mask); 30 | } 31 | #endif 32 | 33 | #define LOAD_MSG_0_1(buf) \ 34 | buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) ); 35 | 36 | #define LOAD_MSG_0_2(buf) \ 37 | buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) ); 38 | 39 | #define LOAD_MSG_0_3(buf) \ 40 | buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) ); 41 | 42 | #define LOAD_MSG_0_4(buf) \ 43 | buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) ); 44 | 45 | #define LOAD_MSG_1_1(buf) \ 46 | t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(5),TOB(0),TOB(0)) ); \ 47 | buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) ); 48 | 49 | #define LOAD_MSG_1_2(buf) \ 50 | t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(2),TOB(0),TOB(4),TOB(6)) ); \ 51 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); 52 | 53 | #define LOAD_MSG_1_3(buf) \ 54 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(0),TOB(0),TOB(1)) ); \ 55 | buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); 56 | 57 | #define LOAD_MSG_1_4(buf) \ 58 | t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(7),TOB(2),TOB(0)) ); \ 59 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) ); 60 | 61 | #define LOAD_MSG_2_1(buf) \ 62 | t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(1),TOB(0),TOB(7)) ); \ 63 | buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(4),TOB(0)) ); 64 | 65 | #define LOAD_MSG_2_2(buf) \ 66 | t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(2),TOB(0),TOB(4)) ); \ 67 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(0)) ); 68 | 69 | #define LOAD_MSG_2_3(buf) \ 70 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(7),TOB(3),TOB(0)) ); \ 71 | buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) ); 72 | 73 | #define LOAD_MSG_2_4(buf) \ 74 | t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(1),TOB(6),TOB(0)) ); \ 75 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) ); 76 | 77 | #define LOAD_MSG_3_1(buf) \ 78 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(3),TOB(7)) ); \ 79 | t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); \ 80 | buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(1),TOB(0)) ); 81 | 82 | #define LOAD_MSG_3_2(buf) \ 83 | t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(1),TOB(5)) ); \ 84 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(1),TOB(0)) ); 85 | 86 | #define LOAD_MSG_3_3(buf) \ 87 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(5),TOB(2)) ); \ 88 | buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); 89 | 90 | #define LOAD_MSG_3_4(buf) \ 91 | t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \ 92 | buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(6),TOB(0)) ); 93 | 94 | #define LOAD_MSG_4_1(buf) \ 95 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(5),TOB(0)) ); \ 96 | buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(5)) ); 97 | 98 | #define LOAD_MSG_4_2(buf) \ 99 | t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(7),TOB(0)) ); \ 100 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); 101 | 102 | #define LOAD_MSG_4_3(buf) \ 103 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(6),TOB(0),TOB(0)) ); \ 104 | t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); \ 105 | buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) ); 106 | 107 | #define LOAD_MSG_4_4(buf) \ 108 | t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(4),TOB(0),TOB(1)) ); \ 109 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(4),TOB(0)) ); 110 | 111 | #define LOAD_MSG_5_1(buf) \ 112 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(2)) ); \ 113 | buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(1),TOB(0)) ); 114 | 115 | #define LOAD_MSG_5_2(buf) \ 116 | t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(6),TOB(0)) ); \ 117 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) ); 118 | 119 | #define LOAD_MSG_5_3(buf) \ 120 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(0),TOB(7),TOB(4)) ); \ 121 | buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); 122 | 123 | #define LOAD_MSG_5_4(buf) \ 124 | t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(5),TOB(0),TOB(1),TOB(0)) ); \ 125 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(5)) ); 126 | 127 | #define LOAD_MSG_6_1(buf) \ 128 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(0),TOB(1),TOB(0)) ); \ 129 | buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(4)) ); 130 | 131 | #define LOAD_MSG_6_2(buf) \ 132 | t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(6),TOB(0),TOB(0),TOB(1)) ); \ 133 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(7),TOB(0)) ); 134 | 135 | #define LOAD_MSG_6_3(buf) \ 136 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(0)) ); \ 137 | buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(5),TOB(1),TOB(0)) ); 138 | 139 | #define LOAD_MSG_6_4(buf) \ 140 | t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(3),TOB(7)) ); \ 141 | buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); 142 | 143 | #define LOAD_MSG_7_1(buf) \ 144 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(0),TOB(7),TOB(0)) ); \ 145 | buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(5)) ); 146 | 147 | #define LOAD_MSG_7_2(buf) \ 148 | t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(5),TOB(1),TOB(0),TOB(7)) ); \ 149 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) ); 150 | 151 | #define LOAD_MSG_7_3(buf) \ 152 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(2),TOB(0),TOB(0),TOB(5)) ); \ 153 | t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(0)) ); \ 154 | buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); 155 | 156 | #define LOAD_MSG_7_4(buf) \ 157 | t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(6),TOB(4),TOB(0)) ); \ 158 | buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(0)) ); 159 | 160 | #define LOAD_MSG_8_1(buf) \ 161 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \ 162 | t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); \ 163 | buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) ); 164 | 165 | #define LOAD_MSG_8_2(buf) \ 166 | t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(4),TOB(3),TOB(5),TOB(0)) ); \ 167 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(7)) ); 168 | 169 | #define LOAD_MSG_8_3(buf) \ 170 | t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(6),TOB(1),TOB(0),TOB(0)) ); \ 171 | buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(5),TOB(4)) ); \ 172 | 173 | #define LOAD_MSG_8_4(buf) \ 174 | buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(4),TOB(7),TOB(2)) ); 175 | 176 | #define LOAD_MSG_9_1(buf) \ 177 | t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(7),TOB(0),TOB(0)) ); \ 178 | buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(4),TOB(6)) ); 179 | 180 | #define LOAD_MSG_9_2(buf) \ 181 | buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(6),TOB(4),TOB(2)) ); 182 | 183 | #define LOAD_MSG_9_3(buf) \ 184 | t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(3),TOB(5),TOB(0)) ); \ 185 | buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(7)) ); 186 | 187 | #define LOAD_MSG_9_4(buf) \ 188 | t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(7)) ); \ 189 | buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(6),TOB(0)) ); 190 | 191 | #endif 192 | -------------------------------------------------------------------------------- /include/sse/blake2s-round.h: -------------------------------------------------------------------------------- 1 | /* 2 | BLAKE2 reference source code package - optimized C implementations 3 | 4 | Copyright 2012, Samuel Neves . You may use this under the 5 | terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 | your option. The terms of these licenses can be found at: 7 | 8 | - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 | - OpenSSL license : https://www.openssl.org/source/license.html 10 | - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | More information about the BLAKE2 hash function can be found at 13 | https://blake2.net. 14 | */ 15 | #ifndef BLAKE2S_ROUND_H 16 | #define BLAKE2S_ROUND_H 17 | 18 | #define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) ) 19 | #define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) 20 | 21 | #define TOF(reg) _mm_castsi128_ps((reg)) 22 | #define TOI(reg) _mm_castps_si128((reg)) 23 | 24 | #define LIKELY(x) __builtin_expect((x),1) 25 | 26 | 27 | /* Microarchitecture-specific macros */ 28 | #ifndef HAVE_XOP 29 | #ifdef HAVE_SSSE3 30 | #define _mm_roti_epi32(r, c) ( \ 31 | (8==-(c)) ? _mm_shuffle_epi8(r,r8) \ 32 | : (16==-(c)) ? _mm_shuffle_epi8(r,r16) \ 33 | : _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) ) 34 | #else 35 | #define _mm_roti_epi32(r, c) _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) 36 | #endif 37 | #else 38 | /* ... */ 39 | #endif 40 | 41 | 42 | #define G1(row1,row2,row3,row4,buf) \ 43 | row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ 44 | row4 = _mm_xor_si128( row4, row1 ); \ 45 | row4 = _mm_roti_epi32(row4, -16); \ 46 | row3 = _mm_add_epi32( row3, row4 ); \ 47 | row2 = _mm_xor_si128( row2, row3 ); \ 48 | row2 = _mm_roti_epi32(row2, -12); 49 | 50 | #define G2(row1,row2,row3,row4,buf) \ 51 | row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ 52 | row4 = _mm_xor_si128( row4, row1 ); \ 53 | row4 = _mm_roti_epi32(row4, -8); \ 54 | row3 = _mm_add_epi32( row3, row4 ); \ 55 | row2 = _mm_xor_si128( row2, row3 ); \ 56 | row2 = _mm_roti_epi32(row2, -7); 57 | 58 | #define DIAGONALIZE(row1,row2,row3,row4) \ 59 | row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(2,1,0,3) ); \ 60 | row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \ 61 | row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(0,3,2,1) ); 62 | 63 | #define UNDIAGONALIZE(row1,row2,row3,row4) \ 64 | row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(0,3,2,1) ); \ 65 | row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \ 66 | row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(2,1,0,3) ); 67 | 68 | #if defined(HAVE_XOP) 69 | #include "blake2s-load-xop.h" 70 | #elif defined(HAVE_SSE41) 71 | #include "blake2s-load-sse41.h" 72 | #else 73 | #include "blake2s-load-sse2.h" 74 | #endif 75 | 76 | #define ROUND(r) \ 77 | LOAD_MSG_ ##r ##_1(buf1); \ 78 | G1(row1,row2,row3,row4,buf1); \ 79 | LOAD_MSG_ ##r ##_2(buf2); \ 80 | G2(row1,row2,row3,row4,buf2); \ 81 | DIAGONALIZE(row1,row2,row3,row4); \ 82 | LOAD_MSG_ ##r ##_3(buf3); \ 83 | G1(row1,row2,row3,row4,buf3); \ 84 | LOAD_MSG_ ##r ##_4(buf4); \ 85 | G2(row1,row2,row3,row4,buf4); \ 86 | UNDIAGONALIZE(row1,row2,row3,row4); \ 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /src/Crypto/Hash/BLAKE2/BLAKE2b.hsc: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------- 2 | -- | 3 | -- Module : Crypto.Hash.BLAKE2.BLAKE2b 4 | -- Maintainer : John Galt 5 | -- Stability : experimental 6 | -- Portability : POSIX 7 | 8 | module Crypto.Hash.BLAKE2.BLAKE2b 9 | ( -- * Types 10 | BLAKE2bState, 11 | -- * Functions 12 | initialize, 13 | initialize', 14 | update, 15 | finalize, 16 | hash 17 | ) where 18 | 19 | import Data.ByteString (ByteString) 20 | import Foreign.C.Types (CInt(..), CSize(..)) 21 | import Foreign.ForeignPtr (ForeignPtr) 22 | import Foreign.Storable (Storable(..)) 23 | 24 | import Crypto.Hash.BLAKE2.Internal 25 | 26 | #include "blake2.h" 27 | 28 | data BLAKE2bStruct 29 | 30 | instance Storable BLAKE2bStruct where 31 | sizeOf _ = #{size blake2b_state} 32 | alignment _ = #{alignment blake2b_state} 33 | peek = error "peek not implemented" 34 | poke = error "poke not implemented" 35 | 36 | #let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__) 37 | 38 | -- | The hash state. 39 | type BLAKE2bState = ForeignPtr BLAKE2bStruct 40 | 41 | -- | Create a new hashing state. 42 | initialize :: Int 43 | -- ^ Output length in bytes 44 | -> BLAKE2bState 45 | initialize = initializer c_blake2b_init 46 | {-# INLINE initialize #-} 47 | 48 | -- | Create a new keyed hashing state. 49 | initialize' :: Int 50 | -- ^ Output length in bytes 51 | -> ByteString 52 | -- ^ Key 53 | -> BLAKE2bState 54 | initialize' = initializer' c_blake2b_init_key 55 | {-# INLINE initialize' #-} 56 | 57 | -- | Add data to the hashing state. 58 | update :: ByteString 59 | -- ^ Data to hash 60 | -> BLAKE2bState 61 | -- ^ Hashing state 62 | -> BLAKE2bState 63 | update = updater c_blake2b_update 64 | {-# INLINE update #-} 65 | 66 | -- | Finalize the hashing state. 67 | finalize :: Int 68 | -- ^ Output length in bytes 69 | -> BLAKE2bState 70 | -- ^ Hashing state 71 | -> ByteString 72 | finalize = finalizer c_blake2b_final 73 | {-# INLINE finalize #-} 74 | 75 | -- | Perform hashing all in one step. A common way of calling this function 76 | -- is @hash 64 mempty dataToHash@ for applications which do not require 77 | -- keying. 78 | hash :: Int 79 | -- ^ Output length in bytes 80 | -> ByteString 81 | -- ^ Key 82 | -> ByteString 83 | -- ^ Data to hash 84 | -> ByteString 85 | hash = hasher c_blake2b 86 | {-# INLINE hash #-} 87 | 88 | foreign import ccall unsafe "blake2.h blake2b" 89 | c_blake2b :: HashFunc 90 | foreign import ccall unsafe "blake2.h blake2b_init" 91 | c_blake2b_init :: InitFunc BLAKE2bStruct 92 | foreign import ccall unsafe "blake2.h blake2b_init_key" 93 | c_blake2b_init_key :: InitKeyFunc BLAKE2bStruct 94 | foreign import ccall unsafe "blake2.h blake2b_update" 95 | c_blake2b_update :: UpdateFunc BLAKE2bStruct 96 | foreign import ccall unsafe "blake2.h blake2b_final" 97 | c_blake2b_final :: FinalFunc BLAKE2bStruct 98 | -------------------------------------------------------------------------------- /src/Crypto/Hash/BLAKE2/BLAKE2bp.hsc: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------- 2 | -- | 3 | -- Module : Crypto.Hash.BLAKE2.BLAKE2bp 4 | -- Maintainer : John Galt 5 | -- Stability : experimental 6 | -- Portability : POSIX 7 | 8 | module Crypto.Hash.BLAKE2.BLAKE2bp 9 | ( -- * Types 10 | BLAKE2bpState, 11 | -- * Functions 12 | initialize, 13 | initialize', 14 | update, 15 | finalize, 16 | hash 17 | ) where 18 | 19 | import Data.ByteString (ByteString) 20 | import Foreign.C.Types (CInt(..), CSize(..)) 21 | import Foreign.ForeignPtr (ForeignPtr) 22 | import Foreign.Storable (Storable(..)) 23 | 24 | import Crypto.Hash.BLAKE2.Internal 25 | 26 | #include "blake2.h" 27 | 28 | data BLAKE2bpStruct 29 | 30 | instance Storable BLAKE2bpStruct where 31 | sizeOf _ = #{size blake2bp_state} 32 | alignment _ = #{alignment blake2bp_state} 33 | peek = error "peek not implemented" 34 | poke = error "poke not implemented" 35 | 36 | #let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__) 37 | 38 | -- | The hash state. 39 | type BLAKE2bpState = ForeignPtr BLAKE2bpStruct 40 | 41 | -- | Create a new hashing state. 42 | initialize :: Int 43 | -- ^ Output length in bytes 44 | -> BLAKE2bpState 45 | initialize = initializer c_blake2bp_init 46 | {-# INLINE initialize #-} 47 | 48 | -- | Create a new keyed hashing state. 49 | initialize' :: Int 50 | -- ^ Output length in bytes 51 | -> ByteString 52 | -- ^ Key 53 | -> BLAKE2bpState 54 | initialize' = initializer' c_blake2bp_init_key 55 | {-# INLINE initialize' #-} 56 | 57 | -- | Add data to the hashing state. 58 | update :: ByteString 59 | -- ^ Data to hash 60 | -> BLAKE2bpState 61 | -- ^ Hashing state 62 | -> BLAKE2bpState 63 | update = updater c_blake2bp_update 64 | {-# INLINE update #-} 65 | 66 | -- | Finalize the hashing state. 67 | finalize :: Int 68 | -- ^ Output length in bytes 69 | -> BLAKE2bpState 70 | -- ^ Hashing state 71 | -> ByteString 72 | finalize = finalizer c_blake2bp_final 73 | {-# INLINE finalize #-} 74 | 75 | -- | Perform hashing all in one step. A common way of calling this function 76 | -- is @hash 64 mempty dataToHash@ for applications which do not require 77 | -- keying. 78 | hash :: Int 79 | -- ^ Output length in bytes 80 | -> ByteString 81 | -- ^ Key 82 | -> ByteString 83 | -- ^ Data to hash 84 | -> ByteString 85 | hash = hasher c_blake2bp 86 | {-# INLINE hash #-} 87 | 88 | foreign import ccall unsafe "blake2.h blake2bp" 89 | c_blake2bp :: HashFunc 90 | foreign import ccall unsafe "blake2.h blake2bp_init" 91 | c_blake2bp_init :: InitFunc BLAKE2bpStruct 92 | foreign import ccall unsafe "blake2.h blake2bp_init_key" 93 | c_blake2bp_init_key :: InitKeyFunc BLAKE2bpStruct 94 | foreign import ccall unsafe "blake2.h blake2bp_update" 95 | c_blake2bp_update :: UpdateFunc BLAKE2bpStruct 96 | foreign import ccall unsafe "blake2.h blake2bp_final" 97 | c_blake2bp_final :: FinalFunc BLAKE2bpStruct 98 | -------------------------------------------------------------------------------- /src/Crypto/Hash/BLAKE2/BLAKE2s.hsc: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------- 2 | -- | 3 | -- Module : Crypto.Hash.BLAKE2.BLAKE2s 4 | -- Maintainer : John Galt 5 | -- Stability : experimental 6 | -- Portability : POSIX 7 | 8 | module Crypto.Hash.BLAKE2.BLAKE2s 9 | ( -- * Types 10 | BLAKE2sState, 11 | -- * Functions 12 | initialize, 13 | initialize', 14 | update, 15 | finalize, 16 | hash 17 | ) where 18 | 19 | import Data.ByteString (ByteString) 20 | import Foreign.C.Types (CInt(..), CSize(..)) 21 | import Foreign.ForeignPtr (ForeignPtr) 22 | import Foreign.Storable (Storable(..)) 23 | 24 | import Crypto.Hash.BLAKE2.Internal 25 | 26 | #include "blake2.h" 27 | 28 | data BLAKE2sStruct 29 | 30 | instance Storable BLAKE2sStruct where 31 | sizeOf _ = #{size blake2s_state} 32 | alignment _ = #{alignment blake2s_state} 33 | peek = error "peek not implemented" 34 | poke = error "poke not implemented" 35 | 36 | #let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__) 37 | 38 | -- | The hash state. 39 | type BLAKE2sState = ForeignPtr BLAKE2sStruct 40 | 41 | -- | Create a new hashing state. 42 | initialize :: Int 43 | -- ^ Output length in bytes 44 | -> BLAKE2sState 45 | initialize = initializer c_blake2s_init 46 | {-# INLINE initialize #-} 47 | 48 | -- | Create a new keyed hashing state. 49 | initialize' :: Int 50 | -- ^ Output length in bytes 51 | -> ByteString 52 | -- ^ Key 53 | -> BLAKE2sState 54 | initialize' = initializer' c_blake2s_init_key 55 | {-# INLINE initialize' #-} 56 | 57 | -- | Add data to the hashing state. 58 | update :: ByteString 59 | -- ^ Data to hash 60 | -> BLAKE2sState 61 | -- ^ Hashing state 62 | -> BLAKE2sState 63 | update = updater c_blake2s_update 64 | {-# INLINE update #-} 65 | 66 | -- | Finalize the hashing state. 67 | finalize :: Int 68 | -- ^ Output length in bytes 69 | -> BLAKE2sState 70 | -- ^ Hashing state 71 | -> ByteString 72 | finalize = finalizer c_blake2s_final 73 | {-# INLINE finalize #-} 74 | 75 | -- | Perform hashing all in one step. A common way of calling this function 76 | -- is @hash 32 mempty dataToHash@ for applications which do not require 77 | -- keying. 78 | hash :: Int 79 | -- ^ Output length in bytes 80 | -> ByteString 81 | -- ^ Key 82 | -> ByteString 83 | -- ^ Data to hash 84 | -> ByteString 85 | hash = hasher c_blake2s 86 | {-# INLINE hash #-} 87 | 88 | foreign import ccall unsafe "blake2.h blake2s" 89 | c_blake2s :: HashFunc 90 | foreign import ccall unsafe "blake2.h blake2s_init" 91 | c_blake2s_init :: InitFunc BLAKE2sStruct 92 | foreign import ccall unsafe "blake2.h blake2s_init_key" 93 | c_blake2s_init_key :: InitKeyFunc BLAKE2sStruct 94 | foreign import ccall unsafe "blake2.h blake2s_update" 95 | c_blake2s_update :: UpdateFunc BLAKE2sStruct 96 | foreign import ccall unsafe "blake2.h blake2s_final" 97 | c_blake2s_final :: FinalFunc BLAKE2sStruct 98 | -------------------------------------------------------------------------------- /src/Crypto/Hash/BLAKE2/BLAKE2sp.hsc: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------- 2 | -- | 3 | -- Module : Crypto.Hash.BLAKE2.BLAKE2sp 4 | -- Maintainer : John Galt 5 | -- Stability : experimental 6 | -- Portability : POSIX 7 | 8 | module Crypto.Hash.BLAKE2.BLAKE2sp 9 | ( -- * Types 10 | BLAKE2spState, 11 | -- * Functions 12 | initialize, 13 | initialize', 14 | update, 15 | finalize, 16 | hash 17 | ) where 18 | 19 | import Data.ByteString (ByteString) 20 | import Foreign.C.Types (CInt(..), CSize(..)) 21 | import Foreign.ForeignPtr (ForeignPtr) 22 | import Foreign.Storable (Storable(..)) 23 | 24 | import Crypto.Hash.BLAKE2.Internal 25 | 26 | #include "blake2.h" 27 | 28 | data BLAKE2spStruct 29 | 30 | instance Storable BLAKE2spStruct where 31 | sizeOf _ = #{size blake2sp_state} 32 | alignment _ = #{alignment blake2sp_state} 33 | peek = error "peek not implemented" 34 | poke = error "poke not implemented" 35 | 36 | #let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__) 37 | 38 | -- | The hash state. 39 | type BLAKE2spState = ForeignPtr BLAKE2spStruct 40 | 41 | -- | Create a new hashing state. 42 | initialize :: Int 43 | -- ^ Output length in bytes 44 | -> BLAKE2spState 45 | initialize = initializer c_blake2sp_init 46 | {-# INLINE initialize #-} 47 | 48 | -- | Create a new keyed hashing state. 49 | initialize' :: Int 50 | -- ^ Output length in bytes 51 | -> ByteString 52 | -- ^ Key 53 | -> BLAKE2spState 54 | initialize' = initializer' c_blake2sp_init_key 55 | {-# INLINE initialize' #-} 56 | 57 | -- | Add data to the hashing state. 58 | update :: ByteString 59 | -- ^ Data to hash 60 | -> BLAKE2spState 61 | -- ^ Hashing state 62 | -> BLAKE2spState 63 | update = updater c_blake2sp_update 64 | {-# INLINE update #-} 65 | 66 | -- | Finalize the hashing state. 67 | finalize :: Int 68 | -- ^ Output length in bytes 69 | -> BLAKE2spState 70 | -- ^ Hashing state 71 | -> ByteString 72 | finalize = finalizer c_blake2sp_final 73 | {-# INLINE finalize #-} 74 | 75 | -- | Perform hashing all in one step. A common way of calling this function 76 | -- is @hash 32 mempty dataToHash@ for applications which do not require 77 | -- keying. 78 | hash :: Int 79 | -- ^ Output length in bytes 80 | -> ByteString 81 | -- ^ Key 82 | -> ByteString 83 | -- ^ Data to hash 84 | -> ByteString 85 | hash = hasher c_blake2sp 86 | {-# INLINE hash #-} 87 | 88 | foreign import ccall unsafe "blake2.h blake2sp" 89 | c_blake2sp :: HashFunc 90 | foreign import ccall unsafe "blake2.h blake2sp_init" 91 | c_blake2sp_init :: InitFunc BLAKE2spStruct 92 | foreign import ccall unsafe "blake2.h blake2sp_init_key" 93 | c_blake2sp_init_key :: InitKeyFunc BLAKE2spStruct 94 | foreign import ccall unsafe "blake2.h blake2sp_update" 95 | c_blake2sp_update :: UpdateFunc BLAKE2spStruct 96 | foreign import ccall unsafe "blake2.h blake2sp_final" 97 | c_blake2sp_final :: FinalFunc BLAKE2spStruct 98 | -------------------------------------------------------------------------------- /src/Crypto/Hash/BLAKE2/Internal.hs: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------- 2 | -- | 3 | -- Module : Crypto.Hash.BLAKE2.Internal 4 | -- Maintainer : John Galt 5 | -- Stability : experimental 6 | -- Portability : POSIX 7 | 8 | module Crypto.Hash.BLAKE2.Internal 9 | ( -- * Types 10 | InitFunc, 11 | InitKeyFunc, 12 | UpdateFunc, 13 | FinalFunc, 14 | HashFunc, 15 | -- * Functions 16 | initializer, 17 | initializer', 18 | updater, 19 | finalizer, 20 | hasher 21 | ) where 22 | 23 | import Control.Monad (void) 24 | import Data.ByteString (ByteString) 25 | import Data.ByteString.Internal (create, toForeignPtr) 26 | import Data.ByteString.Unsafe (unsafeUseAsCStringLen) 27 | import Foreign.C.Types (CInt, CSize) 28 | import Foreign.ForeignPtr (ForeignPtr, mallocForeignPtr, withForeignPtr) 29 | import Foreign.Marshal.Array (copyArray) 30 | import Foreign.Ptr (Ptr, castPtr) 31 | import Foreign.Storable (Storable) 32 | import System.IO.Unsafe (unsafePerformIO) 33 | 34 | -- int blake2X_init( blake2X_state *S, size_t outlen ); 35 | type InitFunc a = Ptr a -> CSize -> IO CInt 36 | 37 | -- int blake2X_init_key( blake2X_state *S, size_t outlen, const void *key, size_t keylen ); 38 | type InitKeyFunc a = Ptr a -> CSize -> Ptr () -> CSize -> IO CInt 39 | 40 | -- int blake2X_update( blake2X_state *S, const void *in, size_t inlen ); 41 | type UpdateFunc a = Ptr a -> Ptr () -> CSize -> IO CInt 42 | 43 | -- int blake2X_final( blake2X_state *S, void *out, size_t outlen ); 44 | type FinalFunc a = Ptr a -> Ptr () -> CSize -> IO CInt 45 | 46 | -- int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); 47 | type HashFunc = Ptr () 48 | -> CSize 49 | -> Ptr () 50 | -> CSize 51 | -> Ptr () 52 | -> CSize 53 | -> IO CInt 54 | 55 | initializer :: Storable a 56 | => InitFunc a 57 | -> Int 58 | -> ForeignPtr a 59 | initializer f outlen = unsafePerformIO $ do 60 | fptr <- mallocForeignPtr 61 | withForeignPtr fptr $ \ptr -> do 62 | ret <- f (castPtr ptr) (fromIntegral outlen) 63 | if ret == 0 64 | then return fptr 65 | else error "initialization failure" 66 | 67 | initializer' :: Storable a 68 | => InitKeyFunc a 69 | -> Int 70 | -> ByteString 71 | -> ForeignPtr a 72 | initializer' f outlen key = unsafePerformIO $ do 73 | fptr <- mallocForeignPtr 74 | withForeignPtr fptr $ \ptr -> 75 | unsafeUseAsCStringLen key $ \(kptr, klen) -> do 76 | let klen' = fromIntegral klen 77 | outlen' = fromIntegral outlen 78 | ret <- f ptr outlen' (castPtr kptr) klen' 79 | if ret == 0 80 | then return fptr 81 | else error "initialization failure" 82 | 83 | updater :: Storable a 84 | => UpdateFunc a 85 | -> ByteString 86 | -> ForeignPtr a 87 | -> ForeignPtr a 88 | updater f d state = unsafePerformIO $ do 89 | newState <- mallocForeignPtr 90 | withForeignPtr newState $ \nsptr -> do 91 | let (dfp, _, dlen) = toForeignPtr d 92 | dlen' = fromIntegral dlen 93 | withForeignPtr dfp $ \dptr -> 94 | withForeignPtr state $ \sptr -> do 95 | copyArray nsptr sptr 1 96 | void $ f (castPtr nsptr) (castPtr dptr) dlen' 97 | return newState 98 | 99 | finalizer :: Storable a 100 | => FinalFunc a 101 | -> Int 102 | -> ForeignPtr a 103 | -> ByteString 104 | finalizer f outlen state = unsafePerformIO $ do 105 | newState <- mallocForeignPtr 106 | withForeignPtr newState $ \nsptr -> 107 | create outlen $ \optr -> 108 | withForeignPtr state $ \sptr -> do 109 | let outlen' = fromIntegral outlen 110 | copyArray nsptr sptr 1 111 | void $ f (castPtr nsptr) (castPtr optr) outlen' 112 | 113 | hasher :: HashFunc 114 | -> Int 115 | -> ByteString 116 | -> ByteString 117 | -> ByteString 118 | hasher h olen key input = 119 | unsafePerformIO . create olen $ \ostr -> 120 | unsafeUseAsCStringLen key $ \(kstr, klen) -> 121 | unsafeUseAsCStringLen input $ \(istr, ilen) -> 122 | let olen' = fromIntegral olen 123 | ilen' = fromIntegral ilen 124 | klen' = fromIntegral klen 125 | in void $ h (castPtr ostr) olen' 126 | (castPtr istr) ilen' 127 | (castPtr kstr) klen' 128 | {-# INLINE hasher #-} 129 | -------------------------------------------------------------------------------- /stack.yaml: -------------------------------------------------------------------------------- 1 | resolver: lts-20.12 2 | packages: 3 | - . 4 | -------------------------------------------------------------------------------- /stack.yaml.lock: -------------------------------------------------------------------------------- 1 | # This file was autogenerated by Stack. 2 | # You should not edit this file by hand. 3 | # For more information, please see the documentation at: 4 | # https://docs.haskellstack.org/en/stable/lock_files 5 | 6 | packages: [] 7 | snapshots: 8 | - completed: 9 | sha256: af5d667f6096e535b9c725a72cffe0f6c060e0568d9f9eeda04caee70d0d9d2d 10 | size: 649133 11 | url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/12.yaml 12 | original: lts-20.12 13 | -------------------------------------------------------------------------------- /tests/Imports.hs: -------------------------------------------------------------------------------- 1 | module Imports 2 | ( 3 | module X 4 | ) where 5 | 6 | import Test.Tasty as X 7 | import Test.Tasty.QuickCheck as X 8 | -------------------------------------------------------------------------------- /tests/hlint.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Control.Monad 4 | import Language.Haskell.HLint 5 | import System.Environment 6 | import System.Exit 7 | 8 | main :: IO () 9 | main = do 10 | args <- getArgs 11 | hints <- hlint $ [ "src" 12 | , "benchmarks" 13 | , "tests" 14 | , "--cpp-define=HLINT" 15 | ] `mappend` args 16 | unless (null hints) exitFailure 17 | -------------------------------------------------------------------------------- /tests/properties.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | module Main where 3 | 4 | import Data.ByteString (ByteString) 5 | import qualified Data.ByteString.Base16 as Hex 6 | import Prelude hiding (compare) 7 | 8 | import qualified Crypto.Hash.BLAKE2.BLAKE2b as B2b 9 | import qualified Crypto.Hash.BLAKE2.BLAKE2bp as B2bp 10 | import qualified Crypto.Hash.BLAKE2.BLAKE2s as B2s 11 | import qualified Crypto.Hash.BLAKE2.BLAKE2sp as B2sp 12 | 13 | import Imports 14 | 15 | hexDecode :: 16 | ByteString -- ^ Assumed to be valid hexadecimal 17 | -> ByteString 18 | hexDecode x = case Hex.decode x of 19 | Left e -> error e 20 | Right y -> y 21 | 22 | key32 :: ByteString 23 | key32 = hexDecode "000102030405060708090a0b0c0d0e0f\ 24 | \101112131415161718191a1b1c1d1e1f" 25 | 26 | key64 :: ByteString 27 | key64 = hexDecode "000102030405060708090a0b0c0d0e0f\ 28 | \101112131415161718191a1b1c1d1e1f\ 29 | \202122232425262728292a2b2c2d2e2f\ 30 | \303132333435363738393a3b3c3d3e3f" 31 | 32 | compare :: (ByteString -> ByteString) 33 | -> ByteString 34 | -> ByteString 35 | -> Property 36 | compare f input expectation = property $ result === expectation 37 | where 38 | result = Hex.encode . f . hexDecode $ input 39 | 40 | test0s :: Property 41 | test0s = compare (B2s.hash 32 key32) "" "48a8997da407876b3d79c0d92325ad3b89cbb754d86ab71aee047ad345fd2c49" 42 | 43 | test1s :: Property 44 | test1s = compare (B2s.hash 32 key32) "00" "40d15fee7c328830166ac3f918650f807e7e01e177258cdc0a39b11f598066f1" 45 | 46 | test2s :: Property 47 | test2s = compare (B2s.hash 32 key32) "0001" "6bb71300644cd3991b26ccd4d274acd1adeab8b1d7914546c1198bbe9fc9d803" 48 | 49 | test3s :: Property 50 | test3s = compare (B2s.hash 32 key32) "000102" "1d220dbe2ee134661fdf6d9e74b41704710556f2f6e5a091b227697445dbea6b" 51 | 52 | test0sp :: Property 53 | test0sp = compare (B2sp.hash 32 key32) "" "715cb13895aeb678f6124160bff21465b30f4f6874193fc851b4621043f09cc6" 54 | 55 | test1sp :: Property 56 | test1sp = compare (B2sp.hash 32 key32) "00" "40578ffa52bf51ae1866f4284d3a157fc1bcd36ac13cbdcb0377e4d0cd0b6603" 57 | 58 | test2sp :: Property 59 | test2sp = compare (B2sp.hash 32 key32) "0001" "67e3097545bad7e852d74d4eb548eca7c219c202a7d088db0efeac0eac304249" 60 | 61 | test3sp :: Property 62 | test3sp = compare (B2sp.hash 32 key32) "000102" "8dbcc0589a3d17296a7a58e2f1eff0e2aa4210b58d1f88b86d7ba5f29dd3b583" 63 | 64 | test0b :: Property 65 | test0b = compare (B2b.hash 64 key64) "" "10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568" 66 | 67 | test1b :: Property 68 | test1b = compare (B2b.hash 64 key64) "00" "961f6dd1e4dd30f63901690c512e78e4b45e4742ed197c3c5e45c549fd25f2e4187b0bc9fe30492b16b0d0bc4ef9b0f34c7003fac09a5ef1532e69430234cebd" 69 | 70 | test2b :: Property 71 | test2b = compare (B2b.hash 64 key64) "0001" "da2cfbe2d8409a0f38026113884f84b50156371ae304c4430173d08a99d9fb1b983164a3770706d537f49e0c916d9f32b95cc37a95b99d857436f0232c88a965" 72 | 73 | test3b :: Property 74 | test3b = compare (B2b.hash 64 key64) "000102" "33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1" 75 | 76 | test0bp :: Property 77 | test0bp = compare (B2bp.hash 64 key64) "" "9d9461073e4eb640a255357b839f394b838c6ff57c9b686a3f76107c1066728f3c9956bd785cbc3bf79dc2ab578c5a0c063b9d9c405848de1dbe821cd05c940a" 78 | 79 | test1bp :: Property 80 | test1bp = compare (B2bp.hash 64 key64) "00" "ff8e90a37b94623932c59f7559f26035029c376732cb14d41602001cbb73adb79293a2dbda5f60703025144d158e2735529596251c73c0345ca6fccb1fb1e97e" 81 | 82 | test2bp :: Property 83 | test2bp = compare (B2bp.hash 64 key64) "0001" "d6220ca195a0f356a4795e071cee1f5412ecd95d8a5e01d7c2b86750ca53d7f64c29cbb3d289c6f4ecc6c01e3ca9338971170388e3e40228479006d1bbebad51" 84 | 85 | test3bp :: Property 86 | test3bp = compare (B2bp.hash 64 key64) "000102" "30302c3fc999065d10dc982c8feef41bbb6642718f624af6e3eabea083e7fe785340db4b0897efff39cee1dc1eb737cd1eea0fe75384984e7d8f446faa683b80" 87 | 88 | main :: IO () 89 | main = defaultMain $ testGroup "blake2" 90 | [ testGroup "blake2s" [ testProperty "0" test0s 91 | , testProperty "1" test1s 92 | , testProperty "2" test2s 93 | , testProperty "3" test3s 94 | ] 95 | , testGroup "blake2sp" [ testProperty "0" test0sp 96 | , testProperty "1" test1sp 97 | , testProperty "2" test2sp 98 | , testProperty "3" test3sp 99 | ] 100 | , testGroup "blake2b" [ testProperty "0" test0b 101 | , testProperty "1" test1b 102 | , testProperty "2" test2b 103 | , testProperty "3" test3b 104 | ] 105 | , testGroup "blake2bp" [ testProperty "0" test0bp 106 | , testProperty "1" test1bp 107 | , testProperty "2" test2bp 108 | , testProperty "3" test3bp 109 | ] 110 | ] 111 | --------------------------------------------------------------------------------