mirror of
https://github.com/BLAKE2/BLAKE2
synced 2024-09-07 07:10:35 +02:00
Release 2013-01-31
This commit is contained in:
commit
fb714d2c83
121
COPYING
Normal file
121
COPYING
Normal file
@ -0,0 +1,121 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
19
README
Normal file
19
README
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
this is the reference source code package of BLAKE2, which includes
|
||||
|
||||
ref/
|
||||
C implementations of blake2b, blake2bp, blake2s, blake2sp, aimed at
|
||||
portability and simplicity
|
||||
|
||||
sse/
|
||||
C implementations of blake2b, blake2bp, blake2s, blake2sp, optimized
|
||||
for speed on CPUs supporting SSE2, SSSE3, SSE4.1, AVX, or XOP
|
||||
|
||||
csharp/
|
||||
C# implementation of blake2b
|
||||
|
||||
b2sum/
|
||||
command line tool to hash files, based on the sse/ implementations
|
||||
|
||||
bench/
|
||||
benchmark tool to measure cycles-per-byte speeds and produce graphs
|
312
b2sum/b2sum.c
Normal file
312
b2sum/b2sum.c
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - b2sum tool
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "blake2.h"
|
||||
|
||||
/* This will help compatibility with coreutils */
|
||||
int blake2s_stream( FILE *stream, void *resstream )
|
||||
{
|
||||
int ret = -1;
|
||||
size_t sum, n;
|
||||
blake2s_state S[1];
|
||||
static const size_t buffer_length = 32768;
|
||||
uint8_t *buffer = ( uint8_t * )malloc( buffer_length );
|
||||
|
||||
if( !buffer ) return -1;
|
||||
|
||||
blake2s_init( S, BLAKE2S_OUTBYTES );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
sum = 0;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
n = fread( buffer + sum, 1, buffer_length - sum, stream );
|
||||
sum += n;
|
||||
|
||||
if( buffer_length == sum )
|
||||
break;
|
||||
|
||||
if( 0 == n )
|
||||
{
|
||||
if( ferror( stream ) )
|
||||
goto cleanup_buffer;
|
||||
|
||||
goto final_process;
|
||||
}
|
||||
|
||||
if( feof( stream ) )
|
||||
goto final_process;
|
||||
}
|
||||
|
||||
blake2s_update( S, buffer, buffer_length );
|
||||
}
|
||||
|
||||
final_process:;
|
||||
|
||||
if( sum > 0 ) blake2s_update( S, buffer, sum );
|
||||
|
||||
blake2s_final( S, resstream, BLAKE2S_OUTBYTES );
|
||||
ret = 0;
|
||||
cleanup_buffer:
|
||||
free( buffer );
|
||||
return ret;
|
||||
}
|
||||
|
||||
int blake2b_stream( FILE *stream, void *resstream )
|
||||
{
|
||||
int ret = -1;
|
||||
size_t sum, n;
|
||||
blake2b_state S[1];
|
||||
static const size_t buffer_length = 32768;
|
||||
uint8_t *buffer = ( uint8_t * )malloc( buffer_length );
|
||||
|
||||
if( !buffer ) return -1;
|
||||
|
||||
blake2b_init( S, BLAKE2B_OUTBYTES );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
sum = 0;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
n = fread( buffer + sum, 1, buffer_length - sum, stream );
|
||||
sum += n;
|
||||
|
||||
if( buffer_length == sum )
|
||||
break;
|
||||
|
||||
if( 0 == n )
|
||||
{
|
||||
if( ferror( stream ) )
|
||||
goto cleanup_buffer;
|
||||
|
||||
goto final_process;
|
||||
}
|
||||
|
||||
if( feof( stream ) )
|
||||
goto final_process;
|
||||
}
|
||||
|
||||
blake2b_update( S, buffer, buffer_length );
|
||||
}
|
||||
|
||||
final_process:;
|
||||
|
||||
if( sum > 0 ) blake2b_update( S, buffer, sum );
|
||||
|
||||
blake2b_final( S, resstream, BLAKE2B_OUTBYTES );
|
||||
ret = 0;
|
||||
cleanup_buffer:
|
||||
free( buffer );
|
||||
return ret;
|
||||
}
|
||||
|
||||
int blake2sp_stream( FILE *stream, void *resstream )
|
||||
{
|
||||
int ret = -1;
|
||||
size_t sum, n;
|
||||
blake2sp_state S[1];
|
||||
static const size_t buffer_length = 16 * ( 1UL << 20 );
|
||||
uint8_t *buffer = ( uint8_t * )malloc( buffer_length );
|
||||
|
||||
if( !buffer ) return -1;
|
||||
|
||||
blake2sp_init( S, BLAKE2S_OUTBYTES );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
sum = 0;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
n = fread( buffer + sum, 1, buffer_length - sum, stream );
|
||||
sum += n;
|
||||
|
||||
if( buffer_length == sum )
|
||||
break;
|
||||
|
||||
if( 0 == n )
|
||||
{
|
||||
if( ferror( stream ) )
|
||||
goto cleanup_buffer;
|
||||
|
||||
goto final_process;
|
||||
}
|
||||
|
||||
if( feof( stream ) )
|
||||
goto final_process;
|
||||
}
|
||||
|
||||
blake2sp_update( S, buffer, buffer_length );
|
||||
}
|
||||
|
||||
final_process:;
|
||||
|
||||
if( sum > 0 ) blake2sp_update( S, buffer, sum );
|
||||
|
||||
blake2sp_final( S, resstream, BLAKE2S_OUTBYTES );
|
||||
ret = 0;
|
||||
cleanup_buffer:
|
||||
free( buffer );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int blake2bp_stream( FILE *stream, void *resstream )
|
||||
{
|
||||
int ret = -1;
|
||||
size_t sum, n;
|
||||
blake2bp_state S[1];
|
||||
static const size_t buffer_length = 16 * ( 1UL << 20 );
|
||||
uint8_t *buffer = ( uint8_t * )malloc( buffer_length );
|
||||
|
||||
if( !buffer ) return -1;
|
||||
|
||||
blake2bp_init( S, BLAKE2B_OUTBYTES );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
sum = 0;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
n = fread( buffer + sum, 1, buffer_length - sum, stream );
|
||||
sum += n;
|
||||
|
||||
if( buffer_length == sum )
|
||||
break;
|
||||
|
||||
if( 0 == n )
|
||||
{
|
||||
if( ferror( stream ) )
|
||||
goto cleanup_buffer;
|
||||
|
||||
goto final_process;
|
||||
}
|
||||
|
||||
if( feof( stream ) )
|
||||
goto final_process;
|
||||
}
|
||||
|
||||
blake2bp_update( S, buffer, buffer_length );
|
||||
}
|
||||
|
||||
final_process:;
|
||||
|
||||
if( sum > 0 ) blake2bp_update( S, buffer, sum );
|
||||
|
||||
blake2bp_final( S, resstream, BLAKE2B_OUTBYTES );
|
||||
ret = 0;
|
||||
cleanup_buffer:
|
||||
free( buffer );
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef int ( *blake2fn )( FILE *, void * );
|
||||
|
||||
|
||||
static void usage( char **argv )
|
||||
{
|
||||
fprintf( stderr, "Usage: %s [-a HASH] [FILE]...\n", argv[0] );
|
||||
fprintf( stderr, "\tHASH in blake2b blake2s blake2bp blake2sp\n" );
|
||||
exit( 111 );
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
blake2fn blake2_stream = blake2b_stream;
|
||||
size_t outlen = BLAKE2B_OUTBYTES;
|
||||
unsigned char hash[BLAKE2B_OUTBYTES] = {0};
|
||||
int c;
|
||||
opterr = 1;
|
||||
|
||||
if ( argc == 1 ) usage( argv ); /* show usage upon no-argument */
|
||||
|
||||
while( ( c = getopt( argc, argv, "a:" ) ) != -1 )
|
||||
{
|
||||
switch( c )
|
||||
{
|
||||
case 'a':
|
||||
if( 0 == strcmp( optarg, "blake2b" ) )
|
||||
{
|
||||
blake2_stream = blake2b_stream;
|
||||
outlen = BLAKE2B_OUTBYTES;
|
||||
}
|
||||
else if ( 0 == strcmp( optarg, "blake2s" ) )
|
||||
{
|
||||
blake2_stream = blake2s_stream;
|
||||
outlen = BLAKE2S_OUTBYTES;
|
||||
}
|
||||
else if ( 0 == strcmp( optarg, "blake2bp" ) )
|
||||
{
|
||||
blake2_stream = blake2bp_stream;
|
||||
outlen = BLAKE2B_OUTBYTES;
|
||||
}
|
||||
else if ( 0 == strcmp( optarg, "blake2sp" ) )
|
||||
{
|
||||
blake2_stream = blake2sp_stream;
|
||||
outlen = BLAKE2S_OUTBYTES;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Invalid function name: `%s'\n", optarg );
|
||||
usage( argv );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( int i = optind; i < argc; ++i )
|
||||
{
|
||||
FILE *f = NULL;
|
||||
f = fopen( argv[i], "rb" );
|
||||
|
||||
if( !f )
|
||||
{
|
||||
fprintf( stderr, "Could not open `%s': %s\n", argv[i], strerror( errno ) );
|
||||
goto end0;
|
||||
}
|
||||
|
||||
if( blake2_stream( f, hash ) < 0 )
|
||||
{
|
||||
fprintf( stderr, "Failed to hash `%s'\n", argv[i] );
|
||||
goto end1;
|
||||
}
|
||||
|
||||
for( int j = 0; j < outlen; ++j )
|
||||
printf( "%02x", hash[j] );
|
||||
|
||||
printf( " %s\n", argv[i] );
|
||||
end1:
|
||||
fclose( f );
|
||||
end0: ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
10
b2sum/makefile
Normal file
10
b2sum/makefile
Normal file
@ -0,0 +1,10 @@
|
||||
CC=gcc
|
||||
CFLAGS=-std=c99 -O3 -march=native -I../sse -static -fopenmp
|
||||
LIBS=
|
||||
#FILES=blake2sum.c ../ref/blake2b-ref.c ../ref/blake2s-ref.c ../ref/blake2bp-ref.c ../ref/blake2sp-ref.c
|
||||
FILES=b2sum.c ../sse/blake2b.c ../sse/blake2s.c ../sse/blake2bp.c ../sse/blake2sp.c
|
||||
all: $(FILES)
|
||||
$(CC) $(FILES) $(CFLAGS) $(LIBS) -o b2sum
|
||||
|
||||
clean:
|
||||
rm -f b2sum
|
20
bench/amd64cpuinfo.c
Normal file
20
bench/amd64cpuinfo.c
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - benchmark tool
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
unsigned long long cpucycles( void )
|
||||
{
|
||||
unsigned long long result;
|
||||
asm volatile( ".byte 15;.byte 49;shlq $32,%%rdx;orq %%rdx,%%rax"
|
||||
: "=a" ( result ) :: "%rdx" );
|
||||
return result;
|
||||
}
|
68
bench/bench.c
Normal file
68
bench/bench.c
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - benchmark tool
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int crypto_hash( unsigned char *out, const unsigned char *in, unsigned long long inlen );
|
||||
|
||||
static int bench_cmp( const void *x, const void *y )
|
||||
{
|
||||
const int64_t *ix = ( const int64_t * )x;
|
||||
const int64_t *iy = ( const int64_t * )y;
|
||||
return *ix - *iy;
|
||||
}
|
||||
|
||||
unsigned long long cpucycles( void );
|
||||
|
||||
void bench()
|
||||
{
|
||||
#define BENCH_TRIALS 32
|
||||
#define BENCH_MAXLEN 1536
|
||||
static unsigned char in[4096];
|
||||
static unsigned long long median[4096 + 1];
|
||||
int i, j;
|
||||
printf( "#bytes median per byte\n" );
|
||||
|
||||
/* 1 ... BENCH_MAXLEN */
|
||||
for( j = 0; j <= 4096; ++j )
|
||||
{
|
||||
uint64_t cycles[BENCH_TRIALS + 1];
|
||||
|
||||
for( i = 0; i <= BENCH_TRIALS; ++i )
|
||||
{
|
||||
cycles[i] = cpucycles();
|
||||
crypto_hash( in, in, j );
|
||||
}
|
||||
|
||||
for( i = 0; i < BENCH_TRIALS; ++i )
|
||||
cycles[i] = cycles[i + 1] - cycles[i];
|
||||
|
||||
qsort( cycles, BENCH_TRIALS, sizeof( uint64_t ), bench_cmp );
|
||||
median[j] = cycles[BENCH_TRIALS / 2];
|
||||
}
|
||||
|
||||
for( j = 0; j <= BENCH_MAXLEN; j += 8 )
|
||||
printf( "%5d, %7.2f\n", j, ( double )median[j] / j );
|
||||
|
||||
printf( "#2048 %6llu %7.2f\n", median[2048], ( double )median[2048] / 2048.0 );
|
||||
printf( "#4096 %6llu %7.2f\n", median[4096], ( double )median[4096] / 4096.0 );
|
||||
printf( "#long long %7.2f\n", ( double )( median[4096] - median[2048] ) / 2048.0 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
bench();
|
||||
return 0;
|
||||
}
|
16
bench/do.gplot
Normal file
16
bench/do.gplot
Normal file
@ -0,0 +1,16 @@
|
||||
maxx = 256
|
||||
set xrange [1:maxx]
|
||||
set xlabel "bytes "
|
||||
set ylabel "cycles"
|
||||
set xtics 0,32,maxx
|
||||
set grid
|
||||
set key left
|
||||
plot "blake2b.data" using 1:2 with lines title "BLAKE2b"
|
||||
replot "blake2s.data" using 1:2 with lines title "BLAKE2s"
|
||||
replot "md5.data" using 1:2 with lines title "MD5"
|
||||
#pause -1 "hit return to continue"
|
||||
#set terminal png
|
||||
#set output "plotcycles.png"
|
||||
set terminal pdfcairo
|
||||
set output "plotcycles.pdf"
|
||||
replot
|
16
bench/makefile
Normal file
16
bench/makefile
Normal file
@ -0,0 +1,16 @@
|
||||
CC=gcc
|
||||
# std to gnu99 to support inline asm
|
||||
CFLAGS=-std=gnu99 -O3 -march=native -DSUPERCOP # -DHAVE_XOP # uncomment on XOP-enabled CPUs
|
||||
FILES=amd64cpuinfo.c bench.c
|
||||
|
||||
all:
|
||||
$(CC) $(FILES) $(CFLAGS) ../sse/blake2b.c -o blake2b
|
||||
$(CC) $(FILES) $(CFLAGS) ../sse/blake2s.c -o blake2s
|
||||
$(CC) $(FILES) $(CFLAGS) md5.c -o md5 -lcrypto -lz
|
||||
./blake2b > blake2b.data
|
||||
./blake2s > blake2s.data
|
||||
./md5 > md5.data
|
||||
gnuplot do.gplot
|
||||
|
||||
clean:
|
||||
rm -f blake2b blake2s md5 plotcycles.pdf blake2b.data blake2s.data md5.data
|
21
bench/md5.c
Normal file
21
bench/md5.c
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - benchmark tool
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <openssl/md5.h>
|
||||
//#include "crypto_hash.h"
|
||||
|
||||
int crypto_hash( unsigned char *out, const unsigned char *in, unsigned long long inlen )
|
||||
{
|
||||
MD5( in, inlen, out );
|
||||
return 0;
|
||||
}
|
19
bench/x86cpuinfo.c
Normal file
19
bench/x86cpuinfo.c
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - benchmark tool
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
unsigned long long cpucycles( void )
|
||||
{
|
||||
unsigned long long result;
|
||||
asm volatile( ".byte 15;.byte 49" : "=A" ( result ) );
|
||||
return result;
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{17466328-5736-4EA1-A88D-CE016CCA2E80}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Blake2Sharp.CompressionCodeGen</RootNamespace>
|
||||
<AssemblyName>Blake2Sharp.CompressionCodeGen</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
93
csharp/Blake2Sharp.CompressionCodeGen/Program.cs
Normal file
93
csharp/Blake2Sharp.CompressionCodeGen/Program.cs
Normal file
@ -0,0 +1,93 @@
|
||||
|
||||
/// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
/// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
/// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
/// and related and neighboring rights to this software to the public domain
|
||||
/// worldwide. This software is distributed without any warranty.
|
||||
|
||||
/// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
/// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Blake2Sharp.CompressionCodeGen
|
||||
{
|
||||
class Program
|
||||
{
|
||||
private const int NumberOfRounds = 12;
|
||||
|
||||
private static readonly int[] Sigma = new int[NumberOfRounds * 16] {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
|
||||
11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
|
||||
7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
|
||||
9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
|
||||
2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
|
||||
12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
|
||||
13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
|
||||
6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
|
||||
10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3
|
||||
};
|
||||
|
||||
static void Round(int r)
|
||||
{
|
||||
Console.WriteLine("// ##### Round({0}) #####", r);
|
||||
G(r, 0, 0, 4, 8, 12);
|
||||
G(r, 1, 1, 5, 9, 13);
|
||||
G(r, 2, 2, 6, 10, 14);
|
||||
G(r, 3, 3, 7, 11, 15);
|
||||
G(r, 4, 0, 5, 10, 15);
|
||||
G(r, 5, 1, 6, 11, 12);
|
||||
G(r, 6, 2, 7, 8, 13);
|
||||
G(r, 7, 3, 4, 9, 14);
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
static void G(int r, int i, int a, int b, int c, int d)
|
||||
{
|
||||
int p = (r << 4) + 2 * i;
|
||||
int p0 = Sigma[p];
|
||||
int p1 = Sigma[p + 1];
|
||||
|
||||
string s = @"// G(r, i, a, b, c, d)
|
||||
a = a + b + m[" + p0 + @"];
|
||||
d ^= a;
|
||||
d = " + RotateRight("d", 32) + @";
|
||||
c = c + d;
|
||||
b ^= c;
|
||||
b = " + RotateRight("b", 24) + @";
|
||||
a = a + b + m[" + p1 + @"];
|
||||
d ^= a;
|
||||
d = " + RotateRight("d", 16) + @";
|
||||
c = c + d;
|
||||
b ^= c;
|
||||
b = " + RotateRight("b", 63) + @";";
|
||||
s = s.Replace("a", "v" + a);
|
||||
s = s.Replace("b", "v" + b);
|
||||
s = s.Replace("c", "v" + c);
|
||||
s = s.Replace("d", "v" + d);
|
||||
s = s.Replace("r", r.ToString());
|
||||
s = s.Replace("i", i.ToString());
|
||||
s = s.Replace("\t", "");
|
||||
Console.WriteLine(s);
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
static string RotateRight(string name, int offset)
|
||||
{
|
||||
return "((" + name + " >>" + offset + ")|(" + name + " << (64-" + offset + ")))";
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
for (int r = 0; r < NumberOfRounds; r++)
|
||||
Round(r);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
|
||||
/// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
/// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
/// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
/// and related and neighboring rights to this software to the public domain
|
||||
/// worldwide. This software is distributed without any warranty.
|
||||
|
||||
/// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
/// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Blake2Sharp.CompressionCodeGen")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Blake2Sharp.CompressionCodeGen")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2012")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("4af5636c-d52d-464f-a707-94464397988a")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
94
csharp/Blake2Sharp.Tests/Blake2Sharp.Tests.csproj
Normal file
94
csharp/Blake2Sharp.Tests/Blake2Sharp.Tests.csproj
Normal file
@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{A32451B3-03A3-4CB3-AD9F-1408143D6AB7}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Blake2Sharp.Tests</RootNamespace>
|
||||
<AssemblyName>Blake2Sharp.Tests</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||
<IsCodedUITest>False</IsCodedUITest>
|
||||
<TestProjectType>UnitTest</TestProjectType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<Choose>
|
||||
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
</ItemGroup>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
|
||||
</ItemGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<ItemGroup>
|
||||
<Compile Include="DebugNodeHasher.cs" />
|
||||
<Compile Include="SequentialTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TestVectors.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Blake2Sharp\Blake2Sharp.csproj">
|
||||
<Project>{e21ab364-9130-4f14-abe1-18fa0c089130}</Project>
|
||||
<Name>Blake2Sharp</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Choose>
|
||||
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
39
csharp/Blake2Sharp.Tests/DebugNodeHasher.cs
Normal file
39
csharp/Blake2Sharp.Tests/DebugNodeHasher.cs
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
/// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
/// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
/// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
/// and related and neighboring rights to this software to the public domain
|
||||
/// worldwide. This software is distributed without any warranty.
|
||||
|
||||
/// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
/// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Blake2Sharp.Tests
|
||||
{
|
||||
/*class DebugNodeHasher : NodeHasher
|
||||
{
|
||||
StringBuilder data = new StringBuilder();
|
||||
|
||||
public override void Init(int depth, long nodeOffset)
|
||||
{
|
||||
data.AppendFormat("({0}-{1}", depth, nodeOffset);
|
||||
}
|
||||
|
||||
public override byte[] Finish(bool isEndOfLayer)
|
||||
{
|
||||
data.Append(")");
|
||||
return Encoding.ASCII.GetBytes(data.ToString());
|
||||
}
|
||||
|
||||
public override void Update(byte[] data, int start, int count)
|
||||
{
|
||||
data.Append(Encoding.ASCII.GetString(data, start, count));
|
||||
}
|
||||
}*/
|
||||
}
|
47
csharp/Blake2Sharp.Tests/Properties/AssemblyInfo.cs
Normal file
47
csharp/Blake2Sharp.Tests/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
/// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
/// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
/// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
/// and related and neighboring rights to this software to the public domain
|
||||
/// worldwide. This software is distributed without any warranty.
|
||||
|
||||
/// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
/// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Blake2Sharp.Tests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Blake2Sharp.Tests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2012")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("4e74ef44-28bc-4b91-9ae9-355e132081ad")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
76
csharp/Blake2Sharp.Tests/SequentialTests.cs
Normal file
76
csharp/Blake2Sharp.Tests/SequentialTests.cs
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
/// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
/// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
/// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
/// and related and neighboring rights to this software to the public domain
|
||||
/// worldwide. This software is distributed without any warranty.
|
||||
|
||||
/// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
/// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace Blake2Sharp.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class SequentialTests
|
||||
{
|
||||
byte[] input = Enumerable.Range(0, 256).Select(i => (byte)i).ToArray();
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void CheckTestVectors()
|
||||
{
|
||||
for (int len = 0; len < TestVectors.UnkeyedBlake2B.Length; len++)
|
||||
{
|
||||
var input = Enumerable.Range(0, len).Select(i => (byte)i).ToArray();
|
||||
var hash = Blake2B.ComputeHash(input);
|
||||
string actual = BitConverter.ToString(hash).Replace("-", "");
|
||||
string expected = TestVectors.UnkeyedBlake2B[len];
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CheckKeyedTestVectors()
|
||||
{
|
||||
var key = Enumerable.Range(0, 64).Select(i => (byte)i).ToArray();
|
||||
for (int len = 0; len < TestVectors.KeyedBlake2B.Length; len++)
|
||||
{
|
||||
var input = Enumerable.Range(0, len).Select(i => (byte)i).ToArray();
|
||||
var hash = Blake2B.ComputeHash(input, new Blake2BConfig { Key = key });
|
||||
string actual = BitConverter.ToString(hash).Replace("-", "");
|
||||
string expected = TestVectors.KeyedBlake2B[len];
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Splits()
|
||||
{
|
||||
var hasher = Blake2B.Create();
|
||||
for (int len = 0; len <= 256; len++)
|
||||
{
|
||||
hasher.Init();
|
||||
hasher.Update(input, 0, len);
|
||||
string hash0 = BitConverter.ToString(hasher.Finish());
|
||||
|
||||
for (int split1 = 0; split1 <= len; split1++)
|
||||
{
|
||||
for (int split2 = split1; split2 <= len; split2++)
|
||||
{
|
||||
hasher.Init();
|
||||
hasher.Update(input, 0, split1);
|
||||
hasher.Update(input, split1, split2 - split1);
|
||||
hasher.Update(input, split2, len - split2);
|
||||
string hash1 = BitConverter.ToString(hasher.Finish());
|
||||
Assert.AreEqual(hash0, hash1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
539
csharp/Blake2Sharp.Tests/TestVectors.cs
Normal file
539
csharp/Blake2Sharp.Tests/TestVectors.cs
Normal file
@ -0,0 +1,539 @@
|
||||
|
||||
/// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
/// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
/// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
/// and related and neighboring rights to this software to the public domain
|
||||
/// worldwide. This software is distributed without any warranty.
|
||||
|
||||
/// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
/// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Blake2Sharp.Tests
|
||||
{
|
||||
internal static class TestVectors
|
||||
{
|
||||
public static string[] UnkeyedBlake2B = new string[]{
|
||||
"786A02F742015903C6C6FD852552D272912F4740E15847618A86E217F71F5419D25E1031AFEE585313896444934EB04B903A685B1448B755D56F701AFE9BE2CE",
|
||||
"2FA3F686DF876995167E7C2E5D74C4C7B6E48F8068FE0E44208344D480F7904C36963E44115FE3EB2A3AC8694C28BCB4F5A0F3276F2E79487D8219057A506E4B",
|
||||
"1C08798DC641ABA9DEE435E22519A4729A09B2BFE0FF00EF2DCD8ED6F8A07D15EAF4AEE52BBF18AB5608A6190F70B90486C8A7D4873710B1115D3DEBBB4327B5",
|
||||
"40A374727302D9A4769C17B5F409FF32F58AA24FF122D7603E4FDA1509E919D4107A52C57570A6D94E50967AEA573B11F86F473F537565C66F7039830A85D186",
|
||||
"77DDF4B14425EB3D053C1E84E3469D92C4CD910ED20F92035E0C99D8A7A86CECAF69F9663C20A7AA230BC82F60D22FB4A00B09D3EB8FC65EF547FE63C8D3DDCE",
|
||||
"CBAA0BA7D482B1F301109AE41051991A3289BC1198005AF226C5E4F103B66579F461361044C8BA3439FF12C515FB29C52161B7EB9C2837B76A5DC33F7CB2E2E8",
|
||||
"F95D45CF69AF5C2023BDB505821E62E85D7CAEDF7BEDA12C0248775B0C88205EEB35AF3A90816F6608CE7DD44EC28DB1140614E1DDEBF3AA9CD1843E0FAD2C36",
|
||||
"8F945BA700F2530E5C2A7DF7D5DCE0F83F9EFC78C073FE71AE1F88204A4FD1CF70A073F5D1F942ED623AA16E90A871246C90C45B621B3401A5DDBD9DF6264165",
|
||||
"E998E0DC03EC30EB99BB6BFAAF6618ACC620320D7220B3AF2B23D112D8E9CB1262F3C0D60D183B1EE7F096D12DAE42C958418600214D04F5ED6F5E718BE35566",
|
||||
"6A9A090C61B3410AEDE7EC9138146CEB2C69662F460C3DA53C6515C1EB31F41CA3D280E567882F95CF664A94147D78F42CFC714A40D22EF19470E053493508A2",
|
||||
"29102511D749DB3CC9B4E335FA1F5E8FACA8421D558F6A3F3321D50D044A248BA595CFC3EFD3D2ADC97334DA732413F5CBF4751C362BA1D53862AC1E8DABEEE8",
|
||||
"C97A4779D47E6F77729B5917D0138ABB35980AB641BD73A8859EB1AC98C05362ED7D608F2E9587D6BA9E271D343125D40D933A8ED04EC1FE75EC407C7A53C34E",
|
||||
"10F0DC91B9F845FB95FAD6860E6CE1ADFA002C7FC327116D44D047CD7D5870D772BB12B5FAC00E02B08AC2A0174D0446C36AB35F14CA31894CD61C78C849B48A",
|
||||
"DEA9101CAC62B8F6A3C650F90EEA5BFAE2653A4EAFD63A6D1F0F132DB9E4F2B1B662432EC85B17BCAC41E775637881F6AAB38DD66DCBD080F0990A7A6E9854FE",
|
||||
"441FFAA08CD79DFF4AFC9B9E5B5620EEC086730C25F661B1D6FBFBD1CEC3148DD72258C65641F2FCA5EB155FADBCABB13C6E21DC11FAF72C2A281B7D56145F19",
|
||||
"444B240FE3ED86D0E2EF4CE7D851EDDE22155582AA0914797B726CD058B6F45932E0E129516876527B1DD88FC66D7119F4AB3BED93A61A0E2D2D2AEAC336D958",
|
||||
"BFBABBEF45554CCFA0DC83752A19CC35D5920956B301D558D772282BC867009168E9E98606BB5BA73A385DE5749228C925A85019B71F72FE29B3CD37CA52EFE6",
|
||||
"9C4D0C3E1CDBBF485BEC86F41CEC7C98373F0E09F392849AAA229EBFBF397B22085529CB7EF39F9C7C2222A514182B1EFFAA178CC3687B1B2B6CBCB6FDEB96F8",
|
||||
"477176B3BFCBADD7657C23C24625E4D0D674D1868F006006398AF97AA41877C8E70D3D14C3BBC9BBCDCEA801BD0E1599AF1F3EEC67405170F4E26C964A57A8B7",
|
||||
"A78C490EDA3173BB3F10DEE52F110FB1C08E0302230B85DDD7C11257D92DE148785EF00C039C0BB8EB9808A35B2D8C080F572859714C9D4069C5BCAF090E898E",
|
||||
"58D023397BEB5B4145CB2255B07D74290B36D9FD1E594AFBD8EEA47C205B2EFBFE6F46190FAF95AF504AB072E36F6C85D767A321BFD7F22687A4ABBF494A689C",
|
||||
"4001EC74D5A46FD29C2C3CDBE5D1B9F20E51A941BE98D2A4E1E2FBF866A672121DB6F81A514CFD10E7358D571BDBA48E4CE708B9D124894BC0B5ED554935F73A",
|
||||
"CCD1B22DAB6511225D2401EA2D8625D206A12473CC732B615E5640CEFFF0A4ADF971B0E827A619E0A80F5DB9CCD0962329010D07E34A2064E731C520817B2183",
|
||||
"B4A0A9E3574EDB9E1E72AA31E39CC5F30DBF943F8CABC408449654A39131E66D718A18819143E3EA96B4A1895988A1C0056CF2B6E04F9AC19D657383C2910C44",
|
||||
"447BECAB16630608D39F4F058B16F7AF95B85A76AA0FA7CEA2B80755FB76E9C804F2CA78F02643C915FBF2FCE5E19DE86000DE03B18861815A83126071F8A37B",
|
||||
"54E6DAB9977380A5665822DB93374EDA528D9BEB626F9B94027071CB26675E112B4A7FEC941EE60A81E4D2EA3FF7BC52CFC45DFBFE735A1C646B2CF6D6A49B62",
|
||||
"3EA62625949E3646704D7E3C906F82F6C028F540F5F72A794B0C57BF97B7649BFEB90B01D3CA3E829DE21B3826E6F87014D3C77350CB5A15FF5D468A81BEC160",
|
||||
"213CFE145C54A33691569980E5938C8883A46D84D149C8FF1A67CD287B4D49C6DA69D3A035443DB085983D0EFE63706BD5B6F15A7DA459E8D50A19093DB55E80",
|
||||
"5716C4A38F38DB104E494A0A27CBE89A26A6BB6F499EC01C8C01AA7CB88497E75148CD6EEE12A7168B6F78AB74E4BE749251A1A74C38C86D6129177E2889E0B6",
|
||||
"030460A98BDF9FF17CD96404F28FC304F2B7C04EAADE53677FD28F788CA22186B8BC80DD21D17F8549C711AFF0E514E19D4E15F5990252A03E082F28DC2052F6",
|
||||
"19E7F1CCEE88A10672333E390CF22013A8C734C6CB9EAB41F17C3C8032A2E4ACA0569EA36F0860C7A1AF28FA476840D66011168859334A9E4EF9CC2E61A0E29E",
|
||||
"29F8B8C78C80F2FCB4BDF7825ED90A70D625FF785D262677E250C04F3720C888D03F8045E4EDF3F5285BD39D928A10A7D0A5DF00B8484AC2868142A1E8BEA351",
|
||||
"5C52920A7263E39D57920CA0CB752AC6D79A04FEF8A7A216A1ECB7115CE06D89FD7D735BD6F4272555DBA22C2D1C96E6352322C62C5630FDE0F4777A76C3DE2C",
|
||||
"83B098F262251BF660064A9D3511CE7687A09E6DFBB878299C30E93DFB43A9314DB9A600337DB26EBEEDAF2256A96DABE9B29E7573AD11C3523D874DDE5BE7ED",
|
||||
"9447D98AA5C9331352F43D3E56D0A9A9F9581865998E2885CC56DD0A0BD5A7B50595BD10F7529BCD31F37DC16A1465D594079667DA2A3FCB70401498837CEDEB",
|
||||
"867732F2FEEB23893097561AC710A4BFF453BE9CFBEDBA8BA324F9D312A82D732E1B83B829FDCD177B882CA0C1BF544B223BE529924A246A63CF059BFDC50A1B",
|
||||
"F15AB26D4CDFCF56E196BB6BA170A8FCCC414DE9285AFD98A3D3CF2FB88FCBC0F19832AC433A5B2CC2392A4CE34332987D8D2C2BEF6C3466138DB0C6E42FA47B",
|
||||
"2813516D68ED4A08B39D648AA6AACD81E9D655ECD5F0C13556C60FDF0D333EA38464B36C02BACCD746E9575E96C63014F074AE34A0A25B320F0FBEDD6ACF7665",
|
||||
"D3259AFCA8A48962FA892E145ACF547F26923AE8D4924C8A531581526B04B44C7AF83C643EF5A0BC282D36F3FB04C84E28B351F40C74B69DC7840BC717B6F15F",
|
||||
"F14B061AE359FA31B989E30332BFE8DE8CC8CDB568E14BE214A2223B84CAAB7419549ECFCC96CE2ACEC119485D87D157D3A8734FC426597D64F36570CEAF224D",
|
||||
"55E70B01D1FBF8B23B57FB62E26C2CE54F13F8FA2464E6EB98D16A6117026D8B90819012496D4071EBE2E59557ECE3519A7AA45802F9615374877332B73490B3",
|
||||
"25261EB296971D6E4A71B2928E64839C67D422872BF9F3C31993615222DE9F8F0B2C4BE8548559B4B354E736416E3218D4E8A1E219A4A6D43E1A9A521D0E75FC",
|
||||
"08307F347C41294E34BB54CB42B1522D22F824F7B6E5DB50FDA096798E181A8F026FA27B4AE45D52A62CAF9D5198E24A4913C6671775B2D723C1239BFBF016D7",
|
||||
"1E5C62E7E9BFA1B118747A2DE08B3CA10112AF96A46E4B22C3FC06F9BFEE4EB5C49E057A4A4886234324572576BB9B5ECFDE0D99B0DE4F98EC16E4D1B85FA947",
|
||||
"C74A77395FB8BC126447454838E561E962853DC7EB49A1E3CB67C3D0851F3E39517BE8C350AC910903D49CD2BFDF545C99316D0346170B739F0ADD5D533C2CFC",
|
||||
"0DD57B423CC01EB2861391EB886A0D17079B933FC76EB3FC08A19F8A74952CB68F6BCDC644F77370966E4D13E80560BCF082EF0479D48FBBAB4DF03B53A4E178",
|
||||
"4D8DC3923EDCCDFCE70072398B8A3DA5C31FCB3EE3B645C85F717CBAEB4B673A19394425A585BFB464D92F1597D0B754D163F97CED343B25DB5A70EF48EBB34F",
|
||||
"F0A50553E4DFB0C4E3E3D3BA82034857E3B1E50918F5B8A7D698E10D242B0FB544AF6C92D0C3AAF9932220416117B4E78ECB8A8F430E13B82A5915290A5819C5",
|
||||
"B15543F3F736086627CC5365E7E8988C2EF155C0FD4F428961B00D1526F04D6D6A658B4B8ED32C5D8621E7F4F8E8A933D9ECC9DD1B8333CBE28CFC37D9719E1C",
|
||||
"7B4FA158E415FEF023247264CBBE15D16D91A44424A8DB707EB1E2033C30E9E1E7C8C0864595D2CB8C580EB47E9D16ABBD7E44E824F7CEDB7DEF57130E52CFE9",
|
||||
"60424FF23234C34DC9687AD502869372CC31A59380186BC2361C835D972F49666EB1AC69629DE646F03F9B4DB9E2ACE093FBFDF8F20AB5F98541978BE8EF549F",
|
||||
"7406018CE704D84F5EB9C79FEA97DA345699468A350EE0B2D0F3A4BF2070304EA862D72A51C57D3064947286F531E0EAF7563702262E6C724ABF5ED8C8398D17",
|
||||
"14EF5C6D647B3BD1E6E32006C231199810DE5C4DC88E70240273B0EA18E651A3EB4F5CA3114B8A56716969C7CDA27E0C8DB832AD5E89A2DC6CB0ADBE7D93ABD1",
|
||||
"38CF6C24E3E08BCF1F6CF3D1B1F65B905239A3118033249E448113EC632EA6DC346FEEB2571C38BD9A7398B2221280328002B23E1A45ADAFFE66D93F6564EAA2",
|
||||
"6CD7208A4BC7E7E56201BBBA02A0F489CD384ABE40AFD4222F158B3D986EE72A54C50FB64FD4ED2530EDA2C8AF2928A0DA6D4F830AE1C9DB469DFD970F12A56F",
|
||||
"659858F0B5C9EDAB5B94FD732F6E6B17C51CC096104F09BEB3AFC3AA467C2ECF885C4C6541EFFA9023D3B5738AE5A14D867E15DB06FE1F9D1127B77E1AABB516",
|
||||
"26CCA0126F5D1A813C62E5C71001C046F9C92095704550BE5873A495A999AD010A4F79491F24F286500ADCE1A137BC2084E4949F5B7294CEFE51ECAFF8E95CBA",
|
||||
"4147C1F55172788C5567C561FEEF876F621FFF1CE87786B8467637E70DFBCD0DBDB6415CB600954AB9C04C0E457E625B407222C0FE1AE21B2143688ADA94DC58",
|
||||
"5B1BF154C62A8AF6E93D35F18F7F90ABB16A6EF0E8D1AECD118BF70167BAB2AF08935C6FDC0663CE74482D17A8E54B546D1C296631C65F3B522A515839D43D71",
|
||||
"9F600419A4E8F4FB834C24B0F7FC13BF4E279D98E8A3C765EE934917403E3A66097182EA21453CB63EBBE8B73A9C2167596446438C57627F330BADD4F569F7D6",
|
||||
"457EF6466A8924FD8011A34471A5A1AC8CCD9BD0D07A97414AC943021CE4B9E4B9C8DB0A28F016ED43B1542481990022147B313E194671131E708DD43A3ED7DC",
|
||||
"9997B2194D9AF6DFCB9143F41C0ED83D3A3F4388361103D38C2A49B280A581212715FD908D41C651F5C715CA38C0CE2830A37E00E508CED1BCDC320E5E4D1E2E",
|
||||
"5C6BBF16BAA180F986BD40A1287ED4C549770E7284858FC47BC21AB95EBBF3374B4EE3FD9F2AF60F3395221B2ACC76F2D34C132954049F8A3A996F1E32EC84E5",
|
||||
"D10BF9A15B1C9FC8D41F89BB140BF0BE08D2F3666176D13BAAC4D381358AD074C9D4748C300520EB026DAEAEA7C5B158892FDE4E8EC17DC998DCD507DF26EB63",
|
||||
"2FC6E69FA26A89A5ED269092CB9B2A449A4409A7A44011EECAD13D7C4B0456602D402FA5844F1A7A758136CE3D5D8D0E8B86921FFFF4F692DD95BDC8E5FF0052",
|
||||
"FCBE8BE7DCB49A32DBDF239459E26308B84DFF1EA480DF8D104EEFF34B46FAE98627B450C2267D48C0946A697C5B59531452AC0484F1C84E3A33D0C339BB2E28",
|
||||
"A19093A6E3BCF5952F850F2030F69B9606F147F90B8BAEE3362DA71D9F35B44EF9D8F0A7712BA1877FDDCD2D8EA8F1E5A773D0B745D4725605983A2DE901F803",
|
||||
"3C2006423F73E268FA59D2920377EB29A4F9A8B462BE15983EE3B85AE8A78E992633581A9099893B63DB30241C34F643027DC878279AF5850D7E2D4A2653073A",
|
||||
"D0F2F2E3787653F77CCE2FA24835785BBD0C433FC779465A115149905A9DD1CB827A628506D457FCF124A0C2AEF9CE2D2A0A0F63545570D8667FF9E2EBA07334",
|
||||
"78A9FC048E25C6DCB5DE45667DE8FFDD3A93711141D594E9FA62A959475DA6075EA8F0916E84E45AD911B75467077EE52D2C9AEBF4D58F20CE4A3A00458B05D4",
|
||||
"45813F441769AB6ED37D349FF6E72267D76AE6BB3E3C612EC05C6E02A12AF5A37C918B52BF74267C3F6A3F183A8064FF84C07B193D08066789A01ACCDB6F9340",
|
||||
"956DA1C68D83A7B881E01B9A966C3C0BF27F68606A8B71D457BD016D4C41DD8A380C709A296CB4C6544792920FD788835771A07D4A16FB52ED48050331DC4C8B",
|
||||
"DF186C2DC09CAA48E14E942F75DE5AC1B7A21E4F9F072A5B371E09E07345B0740C76177B01278808FEC025EDED9822C122AFD1C63E6F0CE2E32631041063145C",
|
||||
"87475640966A9FDCD6D3A3B5A2CCA5C08F0D882B10243C0EC1BF3C6B1C37F2CD3212F19A057864477D5EAF8FAED73F2937C768A0AF415E84BBCE6BD7DE23B660",
|
||||
"C3B573BBE10949A0FBD4FF884C446F2229B76902F9DFDBB8A0353DA5C83CA14E8151BBAAC82FD1576A009ADC6F1935CF26EDD4F1FB8DA483E6C5CD9D8923ADC3",
|
||||
"B09D8D0BBA8A7286E43568F7907550E42036D674E3C8FC34D8CA46F771D6466B70FB605875F6A863C877D12F07063FDC2E90CCD459B1910DCD52D8F10B2B0A15",
|
||||
"AF3A22BF75B21ABFB0ACD54422BA1B7300A952EFF02EBEB65B5C234471A98DF32F4F9643CE1904108A168767924280BD76C83F8C82D9A79D9259B195362A2A04",
|
||||
"BF4FF2221B7E6957A724CD964AA3D5D0D9941F540413752F4699D8101B3E537508BF09F8508B317736FFD265F2847AA7D84BD2D97569C49D632AED9945E5FA5E",
|
||||
"9C6B6B78199B1BDACB4300E31479FA622A6B5BC80D4678A6078F88A8268CD7206A2799E8D4621A464EF6B43DD8ADFFE97CAF221B22B6B8778B149A822AEFBB09",
|
||||
"890656F09C99D280B5ECB381F56427B813751BC652C7828078B23A4AF83B4E3A61FDBAC61F89BEE84EA6BEE760C047F25C6B0A201C69A38FD6FD971AF18588BB",
|
||||
"31A046F7882FFE6F83CE472E9A0701832EC7B3F76FBCFD1DF60FE3EA48FDE1651254247C3FD95E100F9172731E17FD5297C11F4BB328363CA361624A81AF797C",
|
||||
"27A60B2D00E7A671D47D0AEC2A686A0AC04B52F40AB6629028EB7D13F4BAA99AC0FE46EE6C814944F2F4B4D20E9378E4847EA44C13178091E277B87EA7A55711",
|
||||
"8B5CCEF194162C1F19D68F91E0B0928F289EC5283720840C2F73D253111238DCFE94AF2B59C2C1CA2591901A7BC060E7459B6C47DF0F71701A35CC0AA831B5B6",
|
||||
"57AB6C4B2229AEB3B70476D803CD63812F107CE6DA17FED9B17875E8F86C724F49E024CBF3A1B8B119C50357652B81879D2ADE2D588B9E4F7CEDBA0E4644C9EE",
|
||||
"0190A8DAC320A739F322E15731AA140DDAF5BED294D5C82E54FEF29F214E18AAFAA84F8BE99AF62950266B8F901F15DD4C5D35516FC35B4CAB2E96E4695BBE1C",
|
||||
"D14D7C4C415EEB0E10B159224BEA127EBD84F9591C702A330F5BB7BB7AA44EA39DE6ED01F18DA7ADF40CFB97C5D152C27528824B21E239526AF8F36B214E0CFB",
|
||||
"BE28C4BE706970488FAC7D29C3BD5C4E986085C4C3332F1F3FD30973DB614164BA2F31A78875FFDC150325C88327A9443ED04FDFE5BE93876D1628560C764A80",
|
||||
"031DA1069E3A2E9C3382E436FFD79DF74B1CA6A8ADB2DEABE676AB45994CBC054F037D2F0EACE858D32C14E2D1C8B46077308E3BDC2C1B53172ECF7A8C14E349",
|
||||
"4665CEF8BA4DB4D0ACB118F2987F0BB09F8F86AA445AA3D5FC9A8B346864787489E8FCECC125D17E9B56E12988EAC5ECC7286883DB0661B8FF05DA2AFFF30FE4",
|
||||
"63B7032E5F930CC9939517F9E986816CFBEC2BE59B9568B13F2EAD05BAE7777CAB620C6659404F7409E4199A3BE5F7865AA7CBDF8C4253F7E8219B1BD5F46FEA",
|
||||
"9F09BF093A2B0FF8C2634B49E37F1B2135B447AA9144C9787DBFD92129316C99E88AAB8A21FDEF2372D1189AEC500F95775F1F92BFB45545E4259FB9B7B02D14",
|
||||
"F9F8493C68088807DF7F6A2693D64EA59F03E9E05A223E68524CA32195A4734B654FCEA4D2734C866CF95C889FB10C49159BE2F5043DC98BB55E02EF7BDCB082",
|
||||
"3C9A7359AB4FEBCE07B20AC447B06A240B7FE1DAE5439C49B60B5819F7812E4C172406C1AAC316713CF0DDED1038077258E2EFF5B33913D9D95CAEB4E6C6B970",
|
||||
"AD6AAB8084510E822CFCE8625D62CF4DE655F4763884C71E80BAB9AC9D5318DBA4A6033ED29084E65216C031606CA17615DCFE3BA11D26851AE0999CA6E232CF",
|
||||
"156E9E6261374C9DC884F36E70F0FE1AB9297997B836FA7D170A9C9EBF575B881E7BCEA44D6C0248D35597907154828955BE19135852F9228815ECA024A8ADFB",
|
||||
"4215407633F4CCA9B6788BE93E6AA3D963C7D6CE4B147247099F46A3ACB500A30038CB3E788C3D29F132AD844E80E9E99251F6DB96ACD8A091CFC770AF53847B",
|
||||
"1C077E279DE6548523502B6DF800FFDAB5E2C3E9442EB838F58C295F3B147CEF9D701C41C321283F00C71AFFA0619310399126295B78DD4D1A74572EF9ED5135",
|
||||
"F07A555F49FE481CF4CD0A87B71B82E4A95064D06677FDD90A0EB598877BA1C83D4677B393C3A3B6661C421F5B12CB99D20376BA7275C2F3A8F5A9B7821720DA",
|
||||
"B5911B380D20C7B04323E4026B38E200F534259233B581E02C1E3E2D8438D6C66D5A4EB201D5A8B75072C4EC29106334DA70BC79521B0CED2CFD533F5FF84F95",
|
||||
"01F070A09BAE911296361F91AA0E8E0D09A7725478536D9D48C5FE1E5E7C3C5B9B9D6EB07796F6DA57AE562A7D70E882E37ADFDE83F0C433C2CD363536BB22C8",
|
||||
"6F793EB4374A48B0775ACAF9ADCF8E45E54270C9475F004AD8D5973E2ACA52747FF4ED04AE967275B9F9EB0E1FF75FB4F794FA8BE9ADD7A41304868D103FAB10",
|
||||
"965F20F139765FCC4CE4BA3794675863CAC24DB472CD2B799D035BCE3DBEA502DA7B524865F6B811D8C5828D3A889646FE64A380DA1AA7C7044E9F245DCED128",
|
||||
"EC295B5783601244C30E4641E3B45BE222C4DCE77A58700F53BC8EC52A941690B4D0B087FB6FCB3F39832B9DE8F75EC20BD43079811749CDC907EDB94157D180",
|
||||
"61C72F8CCC91DBB54CA6750BC489672DE09FAEDB8FDD4F94FF2320909A303F5D5A98481C0BC1A625419FB4DEBFBF7F8A53BB07EC3D985E8EA11E72D559940780",
|
||||
"AFD8145B259EEFC8D12620C3C5B03E1ED8FD2CCEFE0365078C80FD42C1770E28B44948F27E65A1886690110DB814397B68E43D80D1BA16DFA358E739C898CFA3",
|
||||
"552FC7893CF1CE933ADA35C0DA98844E41545E244C3157A1428D7B4C21F9CD7E4071AED77B7CA9F1C38FBA32237412EF21A342742EC8324378F21E507FAFDD88",
|
||||
"467A33FBADF5EBC52596EF86AAAEFC6FABA8EE651B1CE04DE368A03A5A9040EF2835E00ADB09ABB3FBD2BCE818A2413D0B0253B5BDA4FC5B2F6F85F3FD5B55F2",
|
||||
"22EFF8E6DD5236F5F57D94EDE874D6C9428E8F5D566F17CD6D1848CD752FE13C655CB10FBAAFF76872F2BF2DA99E15DC624075E1EC2F58A3F64072121838569E",
|
||||
"9CEC6BBF62C4BCE4138ABAE1CBEC8DAD31950444E90321B1347196834C114B864AF3F3CC3508F83751FFB4EDA7C84D140734BB4263C3625C00F04F4C8068981B",
|
||||
"A8B60FA4FC2442F6F1514AD7402626920CC7C2C9F72124B8CBA8EE2CB7C4586F658A4410CFFCC0AB88343955E094C6AF0D20D0C714FB0A988F543F300F58D389",
|
||||
"8271CC45DFA5E4170E847E8630B952CF9C2AA777D06F26A7585B8381F188DACC7337391CFCC94B053DC4EC29CC17F077870428F1AC23FDDDA165EF5A3F155F39",
|
||||
"BF23C0C25C8060E4F6995F1623A3BEBECAA96E308680000A8AA3CD56BB1A6DA099E10D9231B37F4519B2EFD2C24DE72F31A5F19535241B4A59FA3C03CEB790E7",
|
||||
"877FD652C05281009C0A5250E7A3A671F8B18C108817FE4A874DE22DA8E45DB11958A600C5F62E67D36CBF84474CF244A9C2B03A9FB9DC711CD1A2CAB6F3FAE0",
|
||||
"29DF4D87EA444BAF5BCDF5F4E41579E28A67DE84149F06C03F110EA84F572A9F676ADDD04C4878F49C5C00ACCDA441B1A387CACEB2E993BB7A10CD8C2D6717E1",
|
||||
"710DACB166844639CD7B637C274209424E2449DC35D790BBFA4F76177054A36B3B76FAC0CA6E61DF1E687000678AC0746DF75D0A3954897681FD393A155A1BB4",
|
||||
"C1D5F93B8DEA1F2571BABCCBC01764541A0CDA87E444D673C50966CA559C33354B3ACB26E5D5781FFB28847A4B4754D77008C62A835835F500DEA7C3B58BDAE2",
|
||||
"A41E41271CDAB8AF4D72B104BFB2AD041AC4DF14677DA671D85640C4B187F50C2B66513C4619FBD5D5DC4FE65DD37B9042E9848DDA556A504CAA2B1C6AFE4730",
|
||||
"E7BCBACDC379C43D81EBADCB37781552FC1D753E8CF310D968392D06C91F1D64CC9E90CE1D22C32D277FC6CDA433A4D442C762E9EACF2C259F32D64CF9DA3A22",
|
||||
"51755B4AC5456B13218A19C5B9242F57C4A981E4D4ECDCE09A3193362B808A579345D4881C2607A56534DD7F21956AFF72C2F4173A6E7B6CC2212BA0E3DAEE1F",
|
||||
"DCC2C4BEB9C1F2607B786C20C631972347034C1CC02FCC7D02FF01099CFE1C6989840AC213923629113AA8BAD713CCF0FE4CE13264FB32B8B0FE372DA382544A",
|
||||
"3D55176ACEA4A7E3A65FFA9FB10A7A1767199CF077CEE9F71532D67CD7C73C9F93CFC37CCDCC1FDEF50AAD46A504A650D298D597A3A9FA95C6C40CB71FA5E725",
|
||||
"D07713C005DE96DD21D2EB8BBECA66746EA51A31AE922A3E74864889540A48DB27D7E4C90311638B224BF0201B501891754848113C266108D0ADB13DB71909C7",
|
||||
"58983C21433D950CAA23E4BC18543B8E601C204318532152DAF5E159A0CD1480183D29285C05F129CB0CC3164687928086FFE380158DF1D394C6AC0D4288BCA8",
|
||||
"8100A8DC528D2B682AB4250801BA33F02A3E94C54DAC0AE1482AA21F51EF3A82F3807E6FACB0AEB05947BF7AA2ADCB034356F90FA4560EDE02201A37E411EC1A",
|
||||
"07025F1BB6C784F3FE49DE5C14B936A5ACACACAAB33F6AC4D0E00AB6A12483D6BEC00B4FE67C7CA5CC508C2A53EFB5BFA5398769D843FF0D9E8B14D36A01A77F",
|
||||
"BA6AEFD972B6186E027A76273A4A723321A3F580CFA894DA5A9CE8E721C828552C64DACEE3A7FD2D743B5C35AD0C8EFA71F8CE99BF96334710E2C2346E8F3C52",
|
||||
"E0721E02517AEDFA4E7E9BA503E025FD46E714566DC889A84CBFE56A55DFBE2FC4938AC4120588335DEAC8EF3FA229ADC9647F54AD2E3472234F9B34EFC46543",
|
||||
"B6292669CCD38D5F01CAAE96BA272C76A879A45743AFA0725D83B9EBB26665B731F1848C52F11972B6644F554C064FA90780DBBBF3A89D4FC31F67DF3E5857EF",
|
||||
"2319E3789C47E2DAA5FE807F61BEC2A1A6537FA03F19FF32E87EECBFD64B7E0E8CCFF439AC333B040F19B0C4DDD11A61E24AC1FE0F10A039806C5DCC0DA3D115",
|
||||
"F59711D44A031D5F97A9413C065D1E614C417EDE998590325F49BAD2FD444D3E4418BE19AEC4E11449AC1A57207898BC57D76A1BCF3566292C20C683A5C4648F",
|
||||
"DF0A9D0C212843A6A934E3902B2DD30D17FBA5F969D2030B12A546D8A6A45E80CF5635F071F0452E9C919275DA99BED51EB1173C1AF0518726B75B0EC3BAE2B5",
|
||||
"A3EB6E6C7BF2FB8B28BFE8B15E15BB500F781ECC86F778C3A4E655FC5869BF2846A245D4E33B7B14436A17E63BE79B36655C226A50FFBC7124207B0202342DB5",
|
||||
"56D4CBCD070563426A017069425C2CD2AE540668287A5FB9DAC432EB8AB1A353A30F2FE1F40D83333AFE696A267795408A92FE7DA07A0C1814CF77F36E105EE8",
|
||||
"E59B9987D428B3EDA37D80ABDB16CD2B0AEF674C2B1DDA4432EA91EE6C935C684B48B4428A8CC740E579A30DEFF35A803013820DD23F14AE1D8413B5C8672AEC",
|
||||
"CD9FCC99F99D4CC16D031900B2A736E1508DB4B586814E6345857F354A70CCECB1DF3B50A19ADAF43C278EFA423FF4BB6C523EC7FD7859B97B168A7EBFF8467C",
|
||||
"0602185D8C3A78738B99164B8BC6FFB21C7DEBEBBF806372E0DA44D121545597B9C662A255DC31542CF995ECBE6A50FB5E6E0EE4EF240FE557EDED1188087E86",
|
||||
"C08AFA5B927BF08097AFC5FFF9CA4E7800125C1F52F2AF3553FA2B89E1E3015C4F87D5E0A48956AD31450B083DAD147FFB5EC03434A26830CF37D103AB50C5DA",
|
||||
"36F1E1C11D6EF6BC3B536D505D544A871522C5C2A253067EC9933B6EC25464DAF985525F5B9560A16D890259AC1BB5CC67C0C469CDE133DEF000EA1D686F4F5D",
|
||||
"BF2AB2E2470F5438C3B689E66E7686FFFA0CB1E1798AD3A86FF99075BF6138E33D9C0CE59AFB24AC67A02AF34428191A9A0A6041C07471B7C3B1A752D6FC0B8B",
|
||||
"D400601F9728CCC4C92342D9787D8D28AB323AF375CA5624B4BB91D17271FBAE862E413BE73F1F68E615B8C5C391BE0DBD9144746EB339AD541547BA9C468A17",
|
||||
"79FE2FE157EB85A038ABB8EBBC647731D2C83F51B0AC6EE14AA284CB6A3549A4DCCEB300740A825F52F5FB30B03B8C4D8B0F4AA67A63F4A94E3303C4EDA4C02B",
|
||||
"75351313B52A8529298D8C186B1768666DCCA8595317D7A4816EB88C062020C0C8EFC554BB341B64688DB5CCAFC35F3C3CD09D6564B36D7B04A248E146980D4B",
|
||||
"E3128B1D311D02179D7F25F97A5A8BEE2CC8C86303644FCD664E157D1FEF00F23E46F9A5E8E5C890CE565BB6ABD4302CE06469D52A5BD53E1C5A54D04649DC03",
|
||||
"C2382A72D2D3ACE9D5933D00B60827ED380CDA08D0BA5F6DD41E29EE6DBE8ECB9235F06BE95D83B6816A2FB7A5AD47035E8A4B69A4884B99E4BECE58CAB25D44",
|
||||
"6B1C69460BBD50AC2ED6F32E6E887CFED407D47DCF0AAA60387FE320D780BD03EAB6D7BAEB2A07D10CD552A300341354EA9A5F03183A623F92A2D4D9F00926AF",
|
||||
"6CDA206C80CDC9C44BA990E0328C314F819B142D00630404C48C05DC76D1B00CE4D72FC6A48E1469DDEF609412C364820854214B4869AF090F00D3C1BA443E1B",
|
||||
"7FFC8C26FBD6A0F7A609E6E1939F6A9EDF1B0B066641FB76C4F9602ED748D11602496B35355B1AA255850A509D2F8EE18C8F3E1D7DCBC37A136598F56A59ED17",
|
||||
"70DE1F08DD4E09D5FC151F17FC991A23ABFC05104290D50468882EFAF582B6EC2F14F577C0D68C3AD06626916E3C86E6DAAB6C53E5163E82B6BD0CE49FC0D8DF",
|
||||
"4F81935756ED35EE2058EE0C6A6110D6FAC5CB6A4F46AA9411603F99965823B6DA4838276C5C06BC7880E376D92758369EE7305BCEC8D3CFD28CCABB7B4F0579",
|
||||
"ABCB61CB3683D18F27AD527908ED2D32A0426CB7BB4BF18061903A7DC42E7E76F982382304D18AF8C80D91DD58DD47AF76F8E2C36E28AF2476B4BCCF82E89FDF",
|
||||
"02D261AD56A526331B643DD2186DE9A82E72A58223CD1E723686C53D869B83B94632B7B647AB2AFC0D522E29DA3A5615B741D82852E0DF41B66007DBCBA90543",
|
||||
"C5832741FA30C5436823015383D297FF4C4A5D7276C3F902122066E04BE5431B1A85FAF73B918434F9300963D1DEA9E8AC3924EF490226EDEEA5F743E410669F",
|
||||
"CFAEAB268CD075A5A6AED515023A032D54F2F2FF733CE0CBC78DB51DB4504D675923F82746D6594606AD5D67734B11A67CC6A468C2032E43CA1A94C6273A985E",
|
||||
"860850F92EB268272B67D133609BD64E34F61BF03F4C1738645C17FEC818465D7ECD2BE2907641130025FDA79470AB731646E7F69440E8367EA76AC4CEE8A1DF",
|
||||
"84B154ED29BBEDEFA648286839046F4B5AA34430E2D67F7496E4C39F2C7EA78995F69E1292200016F16AC3B37700E6C7E7861AFC396B64A59A1DBF47A55C4BBC",
|
||||
"AEEEC260A5D8EFF5CCAB8B95DA435A63ED7A21EA7FC7559413FD617E33609F8C290E64BBACC528F6C080262288B0F0A3219BE223C991BEE92E72349593E67638",
|
||||
"8AD78A9F26601D127E8D2F2F976E63D19A054A17DCF59E0F013AB54A6887BBDFFDE7AAAE117E0FBF3271016595B9D9C712C01B2C53E9655A382BC4522E616645",
|
||||
"8934159DADE1AC74147DFA282C75954FCEF443EF25F80DFE9FB6EA633B8545111D08B34EF43FFF17026C7964F5DEAC6D2B3C29DACF2747F022DF5967DFDC1A0A",
|
||||
"CD36DD0B240614CF2FA2B9E959679DCDD72EC0CD58A43DA3790A92F6CDEB9E1E795E478A0A47D371100D340C5CEDCDBBC9E68B3F460818E5BDFF7B4CDA4C2744",
|
||||
"00DF4E099B807137A85990F49D3A94315E5A5F7F7A6076B303E96B056FB93800111F479628E2F8DB59AEB6AC70C3B61F51F9B46E80FFDEAE25EBDDB4AF6CB4EE",
|
||||
"2B9C955E6CAED4B7C9E246B86F9A1726E810C59D126CEE66ED71BF015B83558A4B6D84D18DC3FF4620C2FFB722359FDEF85BA0D4E2D22ECBE0ED784F99AFE587",
|
||||
"181DF0A261A2F7D29EA5A15772715105D450A4B6C236F699F462D60CA76487FEEDFC9F5EB92DF838E8FB5DC3694E84C5E0F4A10B761F506762BE052C745A6EE8",
|
||||
"21FB203458BF3A7E9A80439F9A902899CD5DE0139DFD56F7110C9DEC8437B26BDA63DE2F565926D85EDB1D6C6825669743DD9992653D13979544D5DC8228BFAA",
|
||||
"EF021F29C5FFB830E64B9AA9058DD660FD2FCB81C497A7E698BCFBF59DE5AD4A86FF93C10A4B9D1AE5774725F9072DCDE9E1F199BAB91F8BFF921864AA502EEE",
|
||||
"B3CFDA40526B7F1D37569BDFCDF911E5A6EFE6B2EC90A0454C47B2C046BF130FC3B352B34DF4813D48D33AB8E269B69B075676CB6D00A8DCF9E1F967EC191B2C",
|
||||
"B4C6C3B267071EEFB9C8C72E0E2B941293641F8673CB70C1CC26AD1E73CF141755860AD19B34C2F34ED35BB52EC4507CC1FE59047743A5F0C6FEBDE625E26091",
|
||||
"57A34F2BCCA60D4B85103B830C9D7952A416BE5263AE429C9E5E53FE8590A8F78EC65A51109EA85DCDF7B6223F9F2B340539FAD81923DBF8EDABF95129E4DFF6",
|
||||
"9CF46662FCD61A232277B685663B8B5DA832DFD9A3B8CCFEEC993EC6AC415AD07E048ADFE414DF272770DBA867DA5C1224C6FD0AA0C2187D426AC647E9887361",
|
||||
"5CE1042AB4D542C2F9EE9D17262AF8164098935BEF173D0E18489B04841746CD2F2DF866BD7DA6E5EF9024C648023EC723AB9C62FD80285739D84F15D2AB515A",
|
||||
"8488396BD4A8729B7A473178F232DADF3F0F8E22678BA5A43E041E72DA1E2CF82194C307207A54CB8156293339EAEC693FF66BFCD5EFC65E95E4ECAF54530ABD",
|
||||
"F598DA901C3835BCA560779037DFDE9F0C51DC61C0B760FC1522D7B470EE63F5BDC6498476E86049AD86E4E21AF2854A984CC905427D2F17F66B1F41C3DA6F61",
|
||||
"5F93269798CF02132107337660A8D7A177354C0212EB93E555E7C37A08AEF3D8DCE01217011CD965C04DD2C105F2E2B6CAE5E4E6BCAF09DFBEE3E0A6A6357C37",
|
||||
"0ECF581D47BAC9230986FAABD70C2F5B80E91066F0EC55A842937882286D2CA007BB4E973B0B091D52167FF7C4009C7AB4AD38FFF1DCEACDB7BE81EF4A452952",
|
||||
"5AECA8ABE1528582B2A307B4009585498A3D467CA6101CB0C5126F9976056E9FFC123CC20C302B2A737F492C75D21F01512C90CA0541DFA56E950A321DCB28D8",
|
||||
"732FBF8F1CB2B8329263EDE27858FE46F8D3354D376BCDA0548E7CE1FA9DD11F85EB661FE950B543AA635CA4D3F04EDE5B32D6B656E5CE1C44D35C4A6C56CFF8",
|
||||
"D5E938735D63788C80100AEFD18648D18CF272F69F20FF24CFE2895C088AD08B0104DA1672A4EB26FC52545CC7D7A01B266CF546C403C45BD129EB41BDD9200B",
|
||||
"65A245B49352EE297D91AF8C8BE00528AC6E046DD83AC7BD465A98816DD68F3E00E1AE8F895327A7E9A8C9326598379A29C9FC91EC0C6EEF08F3E2B216C11008",
|
||||
"C95654B63019130AB45DD0FB4941B98AEB3AF2A123913ECA2CE99B3E97410A7BF8661CC7FBAA2BC1CF2B13113B1ED40A0118B88E5FFFC3542759EA007ED4C58D",
|
||||
"1EB262F38FA494431F017DAD44C0DFB69324AC032F04B657FC91A88647BB74760F24E7C956514F0CF002990B182C1642B9B2426E96A61187E4E012F00E217D84",
|
||||
"3B955AEEBFA5151AC1AB8E3F5CC1E3767084C842A575D36269836E97353D41622B731DDDCD5F269550A3A5B87BE1E90326340B6E0E62555815D9600597AC6EF9",
|
||||
"68289F6605473BA0E4F241BAF7477A9885426A858F19EF2A18B0D40EF8E41282ED5526B519799E270F13881327918278755711071D8511FE963E3B5606AA3716",
|
||||
"80A33787542612C38F6BCD7CD86CAB460227509B1CBAD5EC408A91413D51155A0476DADBF3A2518E4A6E77CC346622E347A469BF8BAA5F04EB2D98705355D063",
|
||||
"34629BC6D831391C4CDF8AF1B4B7B6B8E8EE17CF98C70E5DD586CD99F14B11DF945166236A9571E6D591BB83EE4D164D46F6B9D8EF86FF865A81BFB91B00424B",
|
||||
"8B7CC339163863BB4383E542B0EF0E7CF36B84AD932CDF5A80419EC9AD692E7A7E784D2C7CB3796A18B8F800035F3AA06C824100611120A7BDEB35618CCB81B7",
|
||||
"4F084E4939DD5A7F5A658FAD58A18A15C25C32EC1C7FD5C5C6C3E892B3971AEAAC308304EF17B1C47239EA4BB398B3FD6D4528D8DE8E768AE0F1A5A5C6B5C297",
|
||||
"48F407A1AF5B8009B2051742E8CF5CD5656669E7D722EE8E7BD202060849442168D8FACC117C012BFB7BF449D99BEFFF6A34AEA203F1D8D352722BE5014EC818",
|
||||
"A6AA82CD1E426F9A73BFA39A29037876114655B8C22D6D3FF8B638AE7DEA6B17843E09E52EB66FA1E475E4A8A3DE429B7D0F4A776FCB8BDC9B9FEDE7D52E815F",
|
||||
"5817027D6BDD00C5DD10AC593CD560372270775A18526D7E6F13872A2E20EAB664625BE7168AC4BD7C9E0CE7FC4099E0F48442E2C767191C6E1284E9B2CCEA8C",
|
||||
"08E41028340A45C74E4052B3A8D6389E22E043A1ADAB5E28D97619450D723469B620CAA519B81C14523854F619FD3027E3847BD03276E60604A80DDB4DE876D6",
|
||||
"130B8420537EB07D72ABDA07C85ACBD8B9A44F16321DD0422145F809673D30F2B5321326E2BFF317EF3FEF983C51C4F8AB24A325D298E34AFCE569A82555774C",
|
||||
"AC49B844AFAA012E31C474CA263648844FD2F6307992C2F752ACA02C3828965175794DEEE2D2EE95C61CD284F6B5A2D75E2EF2B29EE8149E77FB81447B2FD04B",
|
||||
"B9D7CA81CC60BB9578E44024E5A0A0BE80F27336A6A9F4E53DF3999CB191280B090E2AC2D29C5BAAD9D71415BDC129E69AA2667AF6A7FD5E189FCCDCEE817340",
|
||||
"A755E113386572C75CED61D719706070B9146048E42A9F8CD35667A088B42F08808ABDF77E618ABD959AFC757379CA2C00BCC1A48390FA2BFF618B1E0078A613",
|
||||
"A73C7DEBED326F1C0DB0795EE7D6E3946894B826B1F8101C56C823BA17168312E7F53FC7DBE52C3E11E69852C40485E2EF182477862EA6A34EC136E2DFEEA6F4",
|
||||
"6CB8F9D52C56D82CAC28F39EA1593E8BB2506293AC0D68376A1709B62A46DF14A4AE64B2D8FAB76733A1CED2D548E3F3C6FCB49D40C3D5808E449CD83D1C2AA2",
|
||||
"683FA2B2369A10162C1C1C7B24BC970EE67DA220564F32203F625696C0352A0B9AD96624362D952D84463C1106A2DBA7A092599884B35A0B89C8F1B6A9B5A61E",
|
||||
"AAD9AD44610118B77D508AEB1BBCD1C1B7D0171397FB510A401BBC0EC34623670D86A2DC3C8F3AB5A2044DF730256727545F0860CE21A1EAC717DFC48F5D228E",
|
||||
"C42578DE23B4C987D5E1AC4D689ED5DE4B0417F9704BC6BCE969FA13471585D62C2CB1212A944F397FC9CA2C3747C3BEB694EC4C5BE68828DDA53EF43FAEC6C0",
|
||||
"470F00841EE8244E63ED2C7EA30E2E419897C197462ECCCECF713B42A5065FFF5914BC9B79AFFE8F6B657875E789AE213BD914CD35BD174D46E9D18BD843773D",
|
||||
"34FC4213730F47A5E9A3580F643E12945CFCB31BF206F6AD450CE528DA3FA432E005D6B0ECCE10DCA7C5995F6AACC5150E1B009E19751E8309F8859531844374",
|
||||
"FB3C1F0F56A56F8E316FDF5D853C8C872C39635D083634C3904FC3AC07D1B578E85FF0E480E92D44ADE33B62E893EE32343E79DDF6EF292E89B582D312502314",
|
||||
"C7C97FC65DD2B9E3D3D607D31598D3F84261E9919251E9C8E57BB5F829377D5F73EABBED55C6C381180F29AD02E5BE797FFEC7E57BDECBC50AD3D062F0993AB0",
|
||||
"A57A49CDBE67AE7D9F797BB5CC7EFC2DF07F4E1B15955F85DAE74B76E2ECB85AFB6CD9EEED8888D5CA3EC5AB65D27A7B19E578475760A045AC3C92E13A938E77",
|
||||
"C7143FCE9614A17FD653AEB140726DC9C3DBB1DE6CC581B2726897EC24B7A50359AD492243BE66D9EDD8C933B5B80E0B91BB61EA98056006516976FAE8D99A35",
|
||||
"65BB58D07F937E2D3C7E65385F9C54730B704105CCDB691F6E146D4EE8F6C086F49511035110A9AD6031FDCEB943E0F9613BCB276DD40F0624EF0F924F809783",
|
||||
"E540277F683B1186DD3B5B3F61433396581A35FEB12002BE8C6A6231FC40FFA70F08081BC58B2D94F7649543614A435FAA2D62110E13DABC7B86629B63AF9C24",
|
||||
"418500878C5FBCB584C432F4285E05E49F2E3E075399A0DBFCF874EBF8C03D02BF16BC6989D161C77CA0786B05053C6C709433712319192128835CF0B660595B",
|
||||
"889090DBB1944BDC9433EE5EF1010C7A4A24A8E71ECEA8E12A31318CE49DCAB0ACA5C3802334AAB2CC84B14C6B9321FE586BF3F876F19CD406EB1127FB944801",
|
||||
"53B6A28910AA92E27E536FB549CF9B9918791060898E0B9FE183577FF43B5E9C7689C745B32E412269837C31B89E6CC12BF76E13CAD366B74ECE48BB85FD09E9",
|
||||
"7C092080C6A80D672409D081D3D177106BCD63567785140719490950AE07AE8FCAABBAAAB330CFBCF7374482C220AF2EADEEB73DCBB35ED823344E144E7D4899",
|
||||
"9CCDE566D2400509181111F32DDE4CD63209FE59A30C114546AD2776D889A41BAD8FA1BB468CB2F9D42CA9928A7770FEF8E8BA4D0C812D9A1E75C3D8D2CCD75A",
|
||||
"6E293BF5D03FE43977CFE3F57CCDB3AE282A85455DCA33F37F4B74F8398CC612433D755CBEC412F8F82A3BD3BC4A278F7ECD0DFA9BBDC40BE7A787C8F159B2DF",
|
||||
"C56546FB2178456F336164C18B90DEFFC83AE2B5A3ACA77B6884D36D2C1DB39501B3E65E36C758C66E3188451FDB3515EE162C001F06C3E8CB573ADF30F7A101",
|
||||
"6F82F89F299EBCA2FE014B59BFFE1AA84E88B1915FE256AFB646FD8448AF2B8891A7FAB37A4EA6F9A50E6C317039D8CF878F4C8E1A0DD464F0B4D6FF1C7EA853",
|
||||
"2B8599FF9C3D6198637AD51E57D1998B0D75313FE2DD61A533C964A6DD9607C6F723E9452CE46E014B1C1D6DE77BA5B88C914D1C597BF1EAE13474B4290E89B2",
|
||||
"08BF346D38E1DF06C8260EDB1DA75579275948D5C0A0AA9ED2886F8856DE5417A156998758F5B17E52F101CA957A71137473DFD18D7D209C4C10D9233C93691D",
|
||||
"6DF2156D773114D310B63DB9EE5350D77E6BCF25B05FCD910F9B31BC42BB13FE8225EBCB2A23A62280777B6BF74E2CD0917C7640B43DEFE468CD1E18C943C66A",
|
||||
"7C7038BC13A91151828A5BA82B4A96040F258A4DFB1B1373F0D359168AFB0517A20B28A12D3644046BE66B8D08D8AE7F6A923EA1C00187C6D11DC502BAC71305",
|
||||
"BCD1B30D808FB739B987CBF154BEA00DA9D40380B861D4C1D6377122DADD61C0E59018B71941CFB62E00DCD70AEB9ABF0473E80F0A7ECA6B6DEA246AB229DD2B",
|
||||
"7ED4468D968530FE7AB2C33540B26D8C3BD3ED44B34FBE8C2A9D7F805B5ADA0EA252EEADE4FCE97F89728AD85BC8BB2430B1BEF2CDDD32C8446E59B8E8BA3C67",
|
||||
"6D30B7C6CE8A3236C0CA2F8D728B1088CA06983A8043E621D5DCF0C537D13B08791EDEB01A3CF0943EC1C890AB6E29B146A236CD46BCB9D93BF516FB67C63FE5",
|
||||
"97FE03CEF31438508911BDED975980A66029305DC5E3FA8AD1B4FB22FCDF5A19A733320327D8F71CCF496CB3A44A77AF56E3DDE73D3A5F176896CC57C9A5AD99",
|
||||
"785A9D0FBD21136DBCE8FA7EAFD63C9DAD220052978416B31D9753EAA149097847ED9B30A65C70507EFF01879149ED5CF0471D37798EDC05ABD56AD4A2CCCB1D",
|
||||
"AD408D2ABDDFD37B3BF34794C1A3371D928ED7FC8D966225333584C5665817832A37C07F0DC7CB5AA874CD7D20FE8FAB8EABCB9B33D2E0841F6E200960899D95",
|
||||
"97668F745B6032FC815D9579322769DCCD9501A5080029B8AE826BEFB6742331BD9F76EFEB3E2B8E81A9786B282F5068A3A2424697A77C41876B7E753F4C7767",
|
||||
"26BB985F47E7FEE0CFD252D4EF96BED42B9C370C1C6A3E8C9EB04EF7F7818B833A0D1F043EBAFB911DC779E02740A02A44D3A1EA45ED4AD55E686C927CAFE97E",
|
||||
"5BFE2B1DCF7FE9B95088ACEDB575C19016C743B2E763BF5851AC407C9EDA43715EDFA48B4825492C5179593FFF21351B76E8B7E034E4C53C79F61F29C479BD08",
|
||||
"C76509EF72F4A6F9C9C40618ED52B2084F83502232E0AC8BDAF3264368E4D0180F6854C4ABF4F6509C79CAAFC44CF3194AFC57BD077BD7B3C9BDA3D4B8775816",
|
||||
"D66F2BEAB990E354CCB910E4E9C7AC618C7B63EF292A96B552341DE78DC46D3EC8CFABC699B50AF41FDA39CF1B0173660923510AD67FAEDEF5207CFFE8641D20",
|
||||
"7D8F0672992B79BE3A364D8E5904F4AB713BBC8AB01B4F309AD8CCF223CE1034A860DCB0B00550612CC2FA17F2969E18F22E1427D254B4A82B3A03A3EB394ADF",
|
||||
"A56D6725BFB3DE47C1414ADF25FC8F0FC9846F6987722BC06366D5CA4E89722925EBBC881418844075397A0CA89842C7B9E9E07E1D9D183EBEB39E120B483BF7",
|
||||
"AF5E03D7FE60C67E10313344434E79485A03A758D6DCE985574745763C1C5C77D4FB3E6FB12230368370993BF90FEED0C5D1607524562D7C09C0C210ED393D7C",
|
||||
"7A20540CC07BF72B582421FC342E82F52134B69841EC28ED189E2EA6A29DD2F82A640352D222B52F2911DC72A7DAB31CAADD80C6118F13C56B2A1E4373BE0EA3",
|
||||
"486F02C63E5467EA1FDDE7E82BFACC2C1BA5D636D9F3D08B210DA3F372F706EC218CC17FF60AEF703BBE0C15C38AE55D286A684F864C78211CCAB4178C92ADBA",
|
||||
"1C7A5C1DEDCD04A921788F7EB23361CA1953B04B9C7AEC35D65EA3E4996DB26F281278EA4AE666AD81027D98AF57262CDBFA4C085F4210568C7E15EEC7805114",
|
||||
"9CE3FA9A860BDBD5378FD6D7B8B671C6CB7692910CE8F9B6CB4122CBCBE6AC06CA0422CEF1225935053B7D193A81B9E972EB85A1D3074F14CBB5EC9F0573892D",
|
||||
"A91187BE5C371C4265C174FD4653B8AB708551F83D1FEE1CC1479581BC006D6FB78FCC9A5DEE1DB3666F508F9780A37593EBCCCF5FBED39667DC6361E921F779",
|
||||
"4625767D7B1D3D3ED2FBC674AF14E0244152F2A4021FCF3311505D89BD81E2F9F9A500C3B199914DB49500B3C98D03EA93286751A686A3B875DAAB0CCD63B44F",
|
||||
"43DFDFE1B014FED3A2ACABB7F3E9A182F2AA18019D27E3E6CDCF31A15B428E91E7B08CF5E5C376FCE2D8A28FF85AB0A0A1656EDB4A0A91532620096D9A5A652D",
|
||||
"279E3202BE3989BA3112772585177487E4FE3EE3EAB49C2F7FA7FE87CFE7B80D3E0355EDFF6D031E6C96C795DB1C6F041880EC3824DEFACF9263820A8E7327DE",
|
||||
"EA2D066AC229D4D4B616A8BEDEC734325224E4B4E58F1AE6DAD7E40C2DA29196C3B1EA9571DACC81E87328CAA0211E09027B0524AA3F4A849917B3586747EBBB",
|
||||
"49F014F5C61822C899AB5CAE51BE4044A4495E777DEB7DA9B6D8490EFBB87530ADF293DAF079F94C33B7044EF62E2E5BB3EB11E17304F8453EE6CE24F033DDB0",
|
||||
"9233490344E5B0DC5912671B7AE54CEE7730DBE1F4C7D92A4D3E3AAB50571708DB51DCF9C2944591DB651DB32D22935B86944969BE77D5B5FEAE6C3840A8DB26",
|
||||
"B6E75E6F4C7F453B7465D25B5AC8C7196902EAA953875228C8634E16E2AE1F38BC3275304335F5989ECCC1E34167D4E68D7719968FBA8E2FE67947C35C48E806",
|
||||
"CC14CA665AF1483EFBC3AF80080E650D5046A3932F4F51F3FE90A0705EC25104ADF07839265DC51D43401411246E474F0D5E5637AF94767283D53E0617E981F4",
|
||||
"230A1C857CB2E7852E41B647E90E4585D2D881E1734DC38955356E8DD7BFF39053092C6B38E236E1899525647073DDDF6895D64206325E7647F275567B255909",
|
||||
"CBB65321AC436E2FFDAB2936359CE49023F7DEE7614EF28D173C3D27C5D1BFFA51553D433F8EE3C9E49C05A2B883CCE954C9A8093B80612A0CDD4732E041F995",
|
||||
"3E7E570074337275EFB51315588034C3CF0DDDCA20B4612E0BD5B881E7E5476D319CE4FE9F19186E4C0826F44F131EB048E65BE242B1172C63BADB123AB0CBE8",
|
||||
"D32E9EC02D38D4E1B8249DF8DCB00C5B9C68EB8922672E3505393B6A210BA56F9496E5EE0490EF387C3CDEC061F06BC0382D9304CAFBB8E0CD33D57029E62DF2",
|
||||
"8C1512466089F05B3775C262B62D22B83854A83218130B4EC91B3CCBD293D2A54302CECAAB9B100C68D1E6DDC8F07CDDBDFE6FDAAAF099CC09D6B725879C6369",
|
||||
"91A7F61C97C2911E4C812EF71D780AD8FA788794561D08303FD1C1CB608A46A12563086EC5B39D471AED94FB0F6C678A43B8792932F9028D772A22768EA23A9B",
|
||||
"4F6BB222A395E8B18F6BA155477AED3F0729AC9E83E16D31A2A8BC655422B837C891C6199E6F0D75799E3B691525C581953517F252C4B9E3A27A28FBAF49644C",
|
||||
"5D06C07E7A646C413A501C3F4BB2FC38127DE7509B7077C4D9B5613201C1AA02FD5F79D2745915DD57FBCB4CE08695F6EFC0CB3D2D330E19B4B0E6004EA6471E",
|
||||
"B96756E57909968F14B796A5D30F4C9D671472CF82C8CFB2CACA7AC7A44CA0A14C9842D00C82E337502C94D5960ACA4C492EA7B0DF919DDF1AADA2A275BB10D4",
|
||||
"FF0A015E98DB9C99F03977710AAC3E658C0D896F6D71D618BA79DC6CF72AC75B7C038EB6862DEDE4543E145413A6368D69F5722C827BA3EF25B6AE6440D39276",
|
||||
"5B21C5FD8868367612474FA2E70E9CFA2201FFEEE8FAFAB5797AD58FEFA17C9B5B107DA4A3DB6320BAAF2C8617D5A51DF914AE88DA3867C2D41F0CC14FA67928"
|
||||
};
|
||||
|
||||
public static string[] KeyedBlake2B = new string[]{
|
||||
"10EBB67700B1868EFB4417987ACF4690AE9D972FB7A590C2F02871799AAA4786B5E996E8F0F4EB981FC214B005F42D2FF4233499391653DF7AEFCBC13FC51568",
|
||||
"961F6DD1E4DD30F63901690C512E78E4B45E4742ED197C3C5E45C549FD25F2E4187B0BC9FE30492B16B0D0BC4EF9B0F34C7003FAC09A5EF1532E69430234CEBD",
|
||||
"DA2CFBE2D8409A0F38026113884F84B50156371AE304C4430173D08A99D9FB1B983164A3770706D537F49E0C916D9F32B95CC37A95B99D857436F0232C88A965",
|
||||
"33D0825DDDF7ADA99B0E7E307104AD07CA9CFD9692214F1561356315E784F3E5A17E364AE9DBB14CB2036DF932B77F4B292761365FB328DE7AFDC6D8998F5FC1",
|
||||
"BEAA5A3D08F3807143CF621D95CD690514D0B49EFFF9C91D24B59241EC0EEFA5F60196D407048BBA8D2146828EBCB0488D8842FD56BB4F6DF8E19C4B4DAAB8AC",
|
||||
"098084B51FD13DEAE5F4320DE94A688EE07BAEA2800486689A8636117B46C1F4C1F6AF7F74AE7C857600456A58A3AF251DC4723A64CC7C0A5AB6D9CAC91C20BB",
|
||||
"6044540D560853EB1C57DF0077DD381094781CDB9073E5B1B3D3F6C7829E12066BBACA96D989A690DE72CA3133A83652BA284A6D62942B271FFA2620C9E75B1F",
|
||||
"7A8CFE9B90F75F7ECB3ACC053AAED6193112B6F6A4AEEB3F65D3DE541942DEB9E2228152A3C4BBBE72FC3B12629528CFBB09FE630F0474339F54ABF453E2ED52",
|
||||
"380BEAF6EA7CC9365E270EF0E6F3A64FB902ACAE51DD5512F84259AD2C91F4BC4108DB73192A5BBFB0CBCF71E46C3E21AEE1C5E860DC96E8EB0B7B8426E6ABE9",
|
||||
"60FE3C4535E1B59D9A61EA8500BFAC41A69DFFB1CEADD9ACA323E9A625B64DA5763BAD7226DA02B9C8C4F1A5DE140AC5A6C1124E4F718CE0B28EA47393AA6637",
|
||||
"4FE181F54AD63A2983FEAAF77D1E7235C2BEB17FA328B6D9505BDA327DF19FC37F02C4B6F0368CE23147313A8E5738B5FA2A95B29DE1C7F8264EB77B69F585CD",
|
||||
"F228773CE3F3A42B5F144D63237A72D99693ADB8837D0E112A8A0F8FFFF2C362857AC49C11EC740D1500749DAC9B1F4548108BF3155794DCC9E4082849E2B85B",
|
||||
"962452A8455CC56C8511317E3B1F3B2C37DF75F588E94325FDD77070359CF63A9AE6E930936FDF8E1E08FFCA440CFB72C28F06D89A2151D1C46CD5B268EF8563",
|
||||
"43D44BFA18768C59896BF7ED1765CB2D14AF8C260266039099B25A603E4DDC5039D6EF3A91847D1088D401C0C7E847781A8A590D33A3C6CB4DF0FAB1C2F22355",
|
||||
"DCFFA9D58C2A4CA2CDBB0C7AA4C4C1D45165190089F4E983BB1C2CAB4AAEFF1FA2B5EE516FECD780540240BF37E56C8BCCA7FAB980E1E61C9400D8A9A5B14AC6",
|
||||
"6FBF31B45AB0C0B8DAD1C0F5F4061379912DDE5AA922099A030B725C73346C524291ADEF89D2F6FD8DFCDA6D07DAD811A9314536C2915ED45DA34947E83DE34E",
|
||||
"A0C65BDDDE8ADEF57282B04B11E7BC8AAB105B99231B750C021F4A735CB1BCFAB87553BBA3ABB0C3E64A0B6955285185A0BD35FB8CFDE557329BEBB1F629EE93",
|
||||
"F99D815550558E81ECA2F96718AED10D86F3F1CFB675CCE06B0EFF02F617C5A42C5AA760270F2679DA2677C5AEB94F1142277F21C7F79F3C4F0CCE4ED8EE62B1",
|
||||
"95391DA8FC7B917A2044B3D6F5374E1CA072B41454D572C7356C05FD4BC1E0F40B8BB8B4A9F6BCE9BE2C4623C399B0DCA0DAB05CB7281B71A21B0EBCD9E55670",
|
||||
"04B9CD3D20D221C09AC86913D3DC63041989A9A1E694F1E639A3BA7E451840F750C2FC191D56AD61F2E7936BC0AC8E094B60CAEED878C18799045402D61CEAF9",
|
||||
"EC0E0EF707E4ED6C0C66F9E089E4954B058030D2DD86398FE84059631F9EE591D9D77375355149178C0CF8F8E7C49ED2A5E4F95488A2247067C208510FADC44C",
|
||||
"9A37CCE273B79C09913677510EAF7688E89B3314D3532FD2764C39DE022A2945B5710D13517AF8DDC0316624E73BEC1CE67DF15228302036F330AB0CB4D218DD",
|
||||
"4CF9BB8FB3D4DE8B38B2F262D3C40F46DFE747E8FC0A414C193D9FCF753106CE47A18F172F12E8A2F1C26726545358E5EE28C9E2213A8787AAFBC516D2343152",
|
||||
"64E0C63AF9C808FD893137129867FD91939D53F2AF04BE4FA268006100069B2D69DAA5C5D8ED7FDDCB2A70EEECDF2B105DD46A1E3B7311728F639AB489326BC9",
|
||||
"5E9C93158D659B2DEF06B0C3C7565045542662D6EEE8A96A89B78ADE09FE8B3DCC096D4FE48815D88D8F82620156602AF541955E1F6CA30DCE14E254C326B88F",
|
||||
"7775DFF889458DD11AEF417276853E21335EB88E4DEC9CFB4E9EDB49820088551A2CA60339F12066101169F0DFE84B098FDDB148D9DA6B3D613DF263889AD64B",
|
||||
"F0D2805AFBB91F743951351A6D024F9353A23C7CE1FC2B051B3A8B968C233F46F50F806ECB1568FFAA0B60661E334B21DDE04F8FA155AC740EEB42E20B60D764",
|
||||
"86A2AF316E7D7754201B942E275364AC12EA8962AB5BD8D7FB276DC5FBFFC8F9A28CAE4E4867DF6780D9B72524160927C855DA5B6078E0B554AA91E31CB9CA1D",
|
||||
"10BDF0CAA0802705E706369BAF8A3F79D72C0A03A80675A7BBB00BE3A45E516424D1EE88EFB56F6D5777545AE6E27765C3A8F5E493FC308915638933A1DFEE55",
|
||||
"B01781092B1748459E2E4EC178696627BF4EBAFEBBA774ECF018B79A68AEB84917BF0B84BB79D17B743151144CD66B7B33A4B9E52C76C4E112050FF5385B7F0B",
|
||||
"C6DBC61DEC6EAEAC81E3D5F755203C8E220551534A0B2FD105A91889945A638550204F44093DD998C076205DFFAD703A0E5CD3C7F438A7E634CD59FEDEDB539E",
|
||||
"EBA51ACFFB4CEA31DB4B8D87E9BF7DD48FE97B0253AE67AA580F9AC4A9D941F2BEA518EE286818CC9F633F2A3B9FB68E594B48CDD6D515BF1D52BA6C85A203A7",
|
||||
"86221F3ADA52037B72224F105D7999231C5E5534D03DA9D9C0A12ACB68460CD375DAF8E24386286F9668F72326DBF99BA094392437D398E95BB8161D717F8991",
|
||||
"5595E05C13A7EC4DC8F41FB70CB50A71BCE17C024FF6DE7AF618D0CC4E9C32D9570D6D3EA45B86525491030C0D8F2B1836D5778C1CE735C17707DF364D054347",
|
||||
"CE0F4F6ACA89590A37FE034DD74DD5FA65EB1CBD0A41508AADDC09351A3CEA6D18CB2189C54B700C009F4CBF0521C7EA01BE61C5AE09CB54F27BC1B44D658C82",
|
||||
"7EE80B06A215A3BCA970C77CDA8761822BC103D44FA4B33F4D07DCB997E36D55298BCEAE12241B3FA07FA63BE5576068DA387B8D5859AEAB701369848B176D42",
|
||||
"940A84B6A84D109AAB208C024C6CE9647676BA0AAA11F86DBB7018F9FD2220A6D901A9027F9ABCF935372727CBF09EBD61A2A2EEB87653E8ECAD1BAB85DC8327",
|
||||
"2020B78264A82D9F4151141ADBA8D44BF20C5EC062EEE9B595A11F9E84901BF148F298E0C9F8777DCDBC7CC4670AAC356CC2AD8CCB1629F16F6A76BCEFBEE760",
|
||||
"D1B897B0E075BA68AB572ADF9D9C436663E43EB3D8E62D92FC49C9BE214E6F27873FE215A65170E6BEA902408A25B49506F47BABD07CECF7113EC10C5DD31252",
|
||||
"B14D0C62ABFA469A357177E594C10C194243ED2025AB8AA5AD2FA41AD318E0FF48CD5E60BEC07B13634A711D2326E488A985F31E31153399E73088EFC86A5C55",
|
||||
"4169C5CC808D2697DC2A82430DC23E3CD356DC70A94566810502B8D655B39ABF9E7F902FE717E0389219859E1945DF1AF6ADA42E4CCDA55A197B7100A30C30A1",
|
||||
"258A4EDB113D66C839C8B1C91F15F35ADE609F11CD7F8681A4045B9FEF7B0B24C82CDA06A5F2067B368825E3914E53D6948EDE92EFD6E8387FA2E537239B5BEE",
|
||||
"79D2D8696D30F30FB34657761171A11E6C3F1E64CBE7BEBEE159CB95BFAF812B4F411E2F26D9C421DC2C284A3342D823EC293849E42D1E46B0A4AC1E3C86ABAA",
|
||||
"8B9436010DC5DEE992AE38AEA97F2CD63B946D94FEDD2EC9671DCDE3BD4CE9564D555C66C15BB2B900DF72EDB6B891EBCADFEFF63C9EA4036A998BE7973981E7",
|
||||
"C8F68E696ED28242BF997F5B3B34959508E42D613810F1E2A435C96ED2FF560C7022F361A9234B9837FEEE90BF47922EE0FD5F8DDF823718D86D1E16C6090071",
|
||||
"B02D3EEE4860D5868B2C39CE39BFE81011290564DD678C85E8783F29302DFC1399BA95B6B53CD9EBBF400CCA1DB0AB67E19A325F2D115812D25D00978AD1BCA4",
|
||||
"7693EA73AF3AC4DAD21CA0D8DA85B3118A7D1C6024CFAF557699868217BC0C2F44A199BC6C0EDD519798BA05BD5B1B4484346A47C2CADF6BF30B785CC88B2BAF",
|
||||
"A0E5C1C0031C02E48B7F09A5E896EE9AEF2F17FC9E18E997D7F6CAC7AE316422C2B1E77984E5F3A73CB45DEED5D3F84600105E6EE38F2D090C7D0442EA34C46D",
|
||||
"41DAA6ADCFDB69F1440C37B596440165C15ADA596813E2E22F060FCD551F24DEE8E04BA6890387886CEEC4A7A0D7FC6B44506392EC3822C0D8C1ACFC7D5AEBE8",
|
||||
"14D4D40D5984D84C5CF7523B7798B254E275A3A8CC0A1BD06EBC0BEE726856ACC3CBF516FF667CDA2058AD5C3412254460A82C92187041363CC77A4DC215E487",
|
||||
"D0E7A1E2B9A447FEE83E2277E9FF8010C2F375AE12FA7AAA8CA5A6317868A26A367A0B69FBC1CF32A55D34EB370663016F3D2110230EBA754028A56F54ACF57C",
|
||||
"E771AA8DB5A3E043E8178F39A0857BA04A3F18E4AA05743CF8D222B0B095825350BA422F63382A23D92E4149074E816A36C1CD28284D146267940B31F8818EA2",
|
||||
"FEB4FD6F9E87A56BEF398B3284D2BDA5B5B0E166583A66B61E538457FF0584872C21A32962B9928FFAB58DE4AF2EDD4E15D8B35570523207FF4E2A5AA7754CAA",
|
||||
"462F17BF005FB1C1B9E671779F665209EC2873E3E411F98DABF240A1D5EC3F95CE6796B6FC23FE171903B502023467DEC7273FF74879B92967A2A43A5A183D33",
|
||||
"D3338193B64553DBD38D144BEA71C5915BB110E2D88180DBC5DB364FD6171DF317FC7268831B5AEF75E4342B2FAD8797BA39EDDCEF80E6EC08159350B1AD696D",
|
||||
"E1590D585A3D39F7CB599ABD479070966409A6846D4377ACF4471D065D5DB94129CC9BE92573B05ED226BE1E9B7CB0CABE87918589F80DADD4EF5EF25A93D28E",
|
||||
"F8F3726AC5A26CC80132493A6FEDCB0E60760C09CFC84CAD178175986819665E76842D7B9FEDF76DDDEBF5D3F56FAAAD4477587AF21606D396AE570D8E719AF2",
|
||||
"30186055C07949948183C850E9A756CC09937E247D9D928E869E20BAFC3CD9721719D34E04A0899B92C736084550186886EFBA2E790D8BE6EBF040B209C439A4",
|
||||
"F3C4276CB863637712C241C444C5CC1E3554E0FDDB174D035819DD83EB700B4CE88DF3AB3841BA02085E1A99B4E17310C5341075C0458BA376C95A6818FBB3E2",
|
||||
"0AA007C4DD9D5832393040A1583C930BCA7DC5E77EA53ADD7E2B3F7C8E231368043520D4A3EF53C969B6BBFD025946F632BD7F765D53C21003B8F983F75E2A6A",
|
||||
"08E9464720533B23A04EC24F7AE8C103145F765387D738777D3D343477FD1C58DB052142CAB754EA674378E18766C53542F71970171CC4F81694246B717D7564",
|
||||
"D37FF7AD297993E7EC21E0F1B4B5AE719CDC83C5DB687527F27516CBFFA822888A6810EE5C1CA7BFE3321119BE1AB7BFA0A502671C8329494DF7AD6F522D440F",
|
||||
"DD9042F6E464DCF86B1262F6ACCFAFBD8CFD902ED3ED89ABF78FFA482DBDEEB6969842394C9A1168AE3D481A017842F660002D42447C6B22F7B72F21AAE021C9",
|
||||
"BD965BF31E87D70327536F2A341CEBC4768ECA275FA05EF98F7F1B71A0351298DE006FBA73FE6733ED01D75801B4A928E54231B38E38C562B2E33EA1284992FA",
|
||||
"65676D800617972FBD87E4B9514E1C67402B7A331096D3BFAC22F1ABB95374ABC942F16E9AB0EAD33B87C91968A6E509E119FF07787B3EF483E1DCDCCF6E3022",
|
||||
"939FA189699C5D2C81DDD1FFC1FA207C970B6A3685BB29CE1D3E99D42F2F7442DA53E95A72907314F4588399A3FF5B0A92BEB3F6BE2694F9F86ECF2952D5B41C",
|
||||
"C516541701863F91005F314108CEECE3C643E04FC8C42FD2FF556220E616AAA6A48AEB97A84BAD74782E8DFF96A1A2FA949339D722EDCAA32B57067041DF88CC",
|
||||
"987FD6E0D6857C553EAEBB3D34970A2C2F6E89A3548F492521722B80A1C21A153892346D2CBA6444212D56DA9A26E324DCCBC0DCDE85D4D2EE4399EEC5A64E8F",
|
||||
"AE56DEB1C2328D9C4017706BCE6E99D41349053BA9D336D677C4C27D9FD50AE6AEE17E853154E1F4FE7672346DA2EAA31EEA53FCF24A22804F11D03DA6ABFC2B",
|
||||
"49D6A608C9BDE4491870498572AC31AAC3FA40938B38A7818F72383EB040AD39532BC06571E13D767E6945AB77C0BDC3B0284253343F9F6C1244EBF2FF0DF866",
|
||||
"DA582AD8C5370B4469AF862AA6467A2293B2B28BD80AE0E91F425AD3D47249FDF98825CC86F14028C3308C9804C78BFEEEEE461444CE243687E1A50522456A1D",
|
||||
"D5266AA3331194AEF852EED86D7B5B2633A0AF1C735906F2E13279F14931A9FC3B0EAC5CE9245273BD1AA92905ABE16278EF7EFD47694789A7283B77DA3C70F8",
|
||||
"2962734C28252186A9A1111C732AD4DE4506D4B4480916303EB7991D659CCDA07A9911914BC75C418AB7A4541757AD054796E26797FEAF36E9F6AD43F14B35A4",
|
||||
"E8B79EC5D06E111BDFAFD71E9F5760F00AC8AC5D8BF768F9FF6F08B8F026096B1CC3A4C973333019F1E3553E77DA3F98CB9F542E0A90E5F8A940CC58E59844B3",
|
||||
"DFB320C44F9D41D1EFDCC015F08DD5539E526E39C87D509AE6812A969E5431BF4FA7D91FFD03B981E0D544CF72D7B1C0374F8801482E6DEA2EF903877EBA675E",
|
||||
"D88675118FDB55A5FB365AC2AF1D217BF526CE1EE9C94B2F0090B2C58A06CA58187D7FE57C7BED9D26FCA067B4110EEFCD9A0A345DE872ABE20DE368001B0745",
|
||||
"B893F2FC41F7B0DD6E2F6AA2E0370C0CFF7DF09E3ACFCC0E920B6E6FAD0EF747C40668417D342B80D2351E8C175F20897A062E9765E6C67B539B6BA8B9170545",
|
||||
"6C67EC5697ACCD235C59B486D7B70BAEEDCBD4AA64EBD4EEF3C7EAC189561A726250AEC4D48CADCAFBBE2CE3C16CE2D691A8CCE06E8879556D4483ED7165C063",
|
||||
"F1AA2B044F8F0C638A3F362E677B5D891D6FD2AB0765F6EE1E4987DE057EAD357883D9B405B9D609EEA1B869D97FB16D9B51017C553F3B93C0A1E0F1296FEDCD",
|
||||
"CBAA259572D4AEBFC1917ACDDC582B9F8DFAA928A198CA7ACD0F2AA76A134A90252E6298A65B08186A350D5B7626699F8CB721A3EA5921B753AE3A2DCE24BA3A",
|
||||
"FA1549C9796CD4D303DCF452C1FBD5744FD9B9B47003D920B92DE34839D07EF2A29DED68F6FC9E6C45E071A2E48BD50C5084E96B657DD0404045A1DDEFE282ED",
|
||||
"5CF2AC897AB444DCB5C8D87C495DBDB34E1838B6B629427CAA51702AD0F9688525F13BEC503A3C3A2C80A65E0B5715E8AFAB00FFA56EC455A49A1AD30AA24FCD",
|
||||
"9AAF80207BACE17BB7AB145757D5696BDE32406EF22B44292EF65D4519C3BB2AD41A59B62CC3E94B6FA96D32A7FAADAE28AF7D35097219AA3FD8CDA31E40C275",
|
||||
"AF88B163402C86745CB650C2988FB95211B94B03EF290EED9662034241FD51CF398F8073E369354C43EAE1052F9B63B08191CAA138AA54FEA889CC7024236897",
|
||||
"48FA7D64E1CEEE27B9864DB5ADA4B53D00C9BC7626555813D3CD6730AB3CC06FF342D727905E33171BDE6E8476E77FB1720861E94B73A2C538D254746285F430",
|
||||
"0E6FD97A85E904F87BFE85BBEB34F69E1F18105CF4ED4F87AEC36C6E8B5F68BD2A6F3DC8A9ECB2B61DB4EEDB6B2EA10BF9CB0251FB0F8B344ABF7F366B6DE5AB",
|
||||
"06622DA5787176287FDC8FED440BAD187D830099C94E6D04C8E9C954CDA70C8BB9E1FC4A6D0BAA831B9B78EF6648681A4867A11DA93EE36E5E6A37D87FC63F6F",
|
||||
"1DA6772B58FABF9C61F68D412C82F182C0236D7D575EF0B58DD22458D643CD1DFC93B03871C316D8430D312995D4197F0874C99172BA004A01EE295ABAC24E46",
|
||||
"3CD2D9320B7B1D5FB9AAB951A76023FA667BE14A9124E394513918A3F44096AE4904BA0FFC150B63BC7AB1EEB9A6E257E5C8F000A70394A5AFD842715DE15F29",
|
||||
"04CDC14F7434E0B4BE70CB41DB4C779A88EAEF6ACCEBCB41F2D42FFFE7F32A8E281B5C103A27021D0D08362250753CDF70292195A53A48728CEB5844C2D98BAB",
|
||||
"9071B7A8A075D0095B8FB3AE5113785735AB98E2B52FAF91D5B89E44AAC5B5D4EBBF91223B0FF4C71905DA55342E64655D6EF8C89A4768C3F93A6DC0366B5BC8",
|
||||
"EBB30240DD96C7BC8D0ABE49AA4EDCBB4AFDC51FF9AAF720D3F9E7FBB0F9C6D6571350501769FC4EBD0B2141247FF400D4FD4BE414EDF37757BB90A32AC5C65A",
|
||||
"8532C58BF3C8015D9D1CBE00EEF1F5082F8F3632FBE9F1ED4F9DFB1FA79E8283066D77C44C4AF943D76B300364AECBD0648C8A8939BD204123F4B56260422DEC",
|
||||
"FE9846D64F7C7708696F840E2D76CB4408B6595C2F81EC6A28A7F2F20CB88CFE6AC0B9E9B8244F08BD7095C350C1D0842F64FB01BB7F532DFCD47371B0AEEB79",
|
||||
"28F17EA6FB6C42092DC264257E29746321FB5BDAEA9873C2A7FA9D8F53818E899E161BC77DFE8090AFD82BF2266C5C1BC930A8D1547624439E662EF695F26F24",
|
||||
"EC6B7D7F030D4850ACAE3CB615C21DD25206D63E84D1DB8D957370737BA0E98467EA0CE274C66199901EAEC18A08525715F53BFDB0AACB613D342EBDCEEDDC3B",
|
||||
"B403D3691C03B0D3418DF327D5860D34BBFCC4519BFBCE36BF33B208385FADB9186BC78A76C489D89FD57E7DC75412D23BCD1DAE8470CE9274754BB8585B13C5",
|
||||
"31FC79738B8772B3F55CD8178813B3B52D0DB5A419D30BA9495C4B9DA0219FAC6DF8E7C23A811551A62B827F256ECDB8124AC8A6792CCFECC3B3012722E94463",
|
||||
"BB2039EC287091BCC9642FC90049E73732E02E577E2862B32216AE9BEDCD730C4C284EF3968C368B7D37584F97BD4B4DC6EF6127ACFE2E6AE2509124E66C8AF4",
|
||||
"F53D68D13F45EDFCB9BD415E2831E938350D5380D3432278FC1C0C381FCB7C65C82DAFE051D8C8B0D44E0974A0E59EC7BF7ED0459F86E96F329FC79752510FD3",
|
||||
"8D568C7984F0ECDF7640FBC483B5D8C9F86634F6F43291841B309A350AB9C1137D24066B09DA9944BAC54D5BB6580D836047AAC74AB724B887EBF93D4B32ECA9",
|
||||
"C0B65CE5A96FF774C456CAC3B5F2C4CD359B4FF53EF93A3DA0778BE4900D1E8DA1601E769E8F1B02D2A2F8C5B9FA10B44F1C186985468FEEB008730283A6657D",
|
||||
"4900BBA6F5FB103ECE8EC96ADA13A5C3C85488E05551DA6B6B33D988E611EC0FE2E3C2AA48EA6AE8986A3A231B223C5D27CEC2EADDE91CE07981EE652862D1E4",
|
||||
"C7F5C37C7285F927F76443414D4357FF789647D7A005A5A787E03C346B57F49F21B64FA9CF4B7E45573E23049017567121A9C3D4B2B73EC5E9413577525DB45A",
|
||||
"EC7096330736FDB2D64B5653E7475DA746C23A4613A82687A28062D3236364284AC01720FFB406CFE265C0DF626A188C9E5963ACE5D3D5BB363E32C38C2190A6",
|
||||
"82E744C75F4649EC52B80771A77D475A3BC091989556960E276A5F9EAD92A03F718742CDCFEAEE5CB85C44AF198ADC43A4A428F5F0C2DDB0BE36059F06D7DF73",
|
||||
"2834B7A7170F1F5B68559AB78C1050EC21C919740B784A9072F6E5D69F828D70C919C5039FB148E39E2C8A52118378B064CA8D5001CD10A5478387B966715ED6",
|
||||
"16B4ADA883F72F853BB7EF253EFCAB0C3E2161687AD61543A0D2824F91C1F81347D86BE709B16996E17F2DD486927B0288AD38D13063C4A9672C39397D3789B6",
|
||||
"78D048F3A69D8B54AE0ED63A573AE350D89F7C6CF1F3688930DE899AFA037697629B314E5CD303AA62FEEA72A25BF42B304B6C6BCB27FAE21C16D925E1FBDAC3",
|
||||
"0F746A48749287ADA77A82961F05A4DA4ABDB7D77B1220F836D09EC814359C0EC0239B8C7B9FF9E02F569D1B301EF67C4612D1DE4F730F81C12C40CC063C5CAA",
|
||||
"F0FC859D3BD195FBDC2D591E4CDAC15179EC0F1DC821C11DF1F0C1D26E6260AAA65B79FAFACAFD7D3AD61E600F250905F5878C87452897647A35B995BCADC3A3",
|
||||
"2620F687E8625F6A412460B42E2CEF67634208CE10A0CBD4DFF7044A41B7880077E9F8DC3B8D1216D3376A21E015B58FB279B521D83F9388C7382C8505590B9B",
|
||||
"227E3AED8D2CB10B918FCB04F9DE3E6D0A57E08476D93759CD7B2ED54A1CBF0239C528FB04BBF288253E601D3BC38B21794AFEF90B17094A182CAC557745E75F",
|
||||
"1A929901B09C25F27D6B35BE7B2F1C4745131FDEBCA7F3E2451926720434E0DB6E74FD693AD29B777DC3355C592A361C4873B01133A57C2E3B7075CBDB86F4FC",
|
||||
"5FD7968BC2FE34F220B5E3DC5AF9571742D73B7D60819F2888B629072B96A9D8AB2D91B82D0A9AABA61BBD39958132FCC4257023D1ECA591B3054E2DC81C8200",
|
||||
"DFCCE8CF32870CC6A503EADAFC87FD6F78918B9B4D0737DB6810BE996B5497E7E5CC80E312F61E71FF3E9624436073156403F735F56B0B01845C18F6CAF772E6",
|
||||
"02F7EF3A9CE0FFF960F67032B296EFCA3061F4934D690749F2D01C35C81C14F39A67FA350BC8A0359BF1724BFFC3BCA6D7C7BBA4791FD522A3AD353C02EC5AA8",
|
||||
"64BE5C6ABA65D594844AE78BB022E5BEBE127FD6B6FFA5A13703855AB63B624DCD1A363F99203F632EC386F3EA767FC992E8ED9686586AA27555A8599D5B808F",
|
||||
"F78585505C4EAA54A8B5BE70A61E735E0FF97AF944DDB3001E35D86C4E2199D976104B6AE31750A36A726ED285064F5981B503889FEF822FCDC2898DDDB7889A",
|
||||
"E4B5566033869572EDFD87479A5BB73C80E8759B91232879D96B1DDA36C012076EE5A2ED7AE2DE63EF8406A06AEA82C188031B560BEAFB583FB3DE9E57952A7E",
|
||||
"E1B3E7ED867F6C9484A2A97F7715F25E25294E992E41F6A7C161FFC2ADC6DAAEB7113102D5E6090287FE6AD94CE5D6B739C6CA240B05C76FB73F25DD024BF935",
|
||||
"85FD085FDC12A080983DF07BD7012B0D402A0F4043FCB2775ADF0BAD174F9B08D1676E476985785C0A5DCC41DBFF6D95EF4D66A3FBDC4A74B82BA52DA0512B74",
|
||||
"AED8FA764B0FBFF821E05233D2F7B0900EC44D826F95E93C343C1BC3BA5A24374B1D616E7E7ABA453A0ADA5E4FAB5382409E0D42CE9C2BC7FB39A99C340C20F0",
|
||||
"7BA3B2E297233522EEB343BD3EBCFD835A04007735E87F0CA300CBEE6D416565162171581E4020FF4CF176450F1291EA2285CB9EBFFE4C56660627685145051C",
|
||||
"DE748BCF89EC88084721E16B85F30ADB1A6134D664B5843569BABC5BBD1A15CA9B61803C901A4FEF32965A1749C9F3A4E243E173939DC5A8DC495C671AB52145",
|
||||
"AAF4D2BDF200A919706D9842DCE16C98140D34BC433DF320ABA9BD429E549AA7A3397652A4D768277786CF993CDE2338673ED2E6B66C961FEFB82CD20C93338F",
|
||||
"C408218968B788BF864F0997E6BC4C3DBA68B276E2125A4843296052FF93BF5767B8CDCE7131F0876430C1165FEC6C4F47ADAA4FD8BCFACEF463B5D3D0FA61A0",
|
||||
"76D2D819C92BCE55FA8E092AB1BF9B9EAB237A25267986CACF2B8EE14D214D730DC9A5AA2D7B596E86A1FD8FA0804C77402D2FCD45083688B218B1CDFA0DCBCB",
|
||||
"72065EE4DD91C2D8509FA1FC28A37C7FC9FA7D5B3F8AD3D0D7A25626B57B1B44788D4CAF806290425F9890A3A2A35A905AB4B37ACFD0DA6E4517B2525C9651E4",
|
||||
"64475DFE7600D7171BEA0B394E27C9B00D8E74DD1E416A79473682AD3DFDBB706631558055CFC8A40E07BD015A4540DCDEA15883CBBF31412DF1DE1CD4152B91",
|
||||
"12CD1674A4488A5D7C2B3160D2E2C4B58371BEDAD793418D6F19C6EE385D70B3E06739369D4DF910EDB0B0A54CBFF43D54544CD37AB3A06CFA0A3DDAC8B66C89",
|
||||
"60756966479DEDC6DD4BCFF8EA7D1D4CE4D4AF2E7B097E32E3763518441147CC12B3C0EE6D2ECABF1198CEC92E86A3616FBA4F4E872F5825330ADBB4C1DEE444",
|
||||
"A7803BCB71BC1D0F4383DDE1E0612E04F872B715AD30815C2249CF34ABB8B024915CB2FC9F4E7CC4C8CFD45BE2D5A91EAB0941C7D270E2DA4CA4A9F7AC68663A",
|
||||
"B84EF6A7229A34A750D9A98EE2529871816B87FBE3BC45B45FA5AE82D5141540211165C3C5D7A7476BA5A4AA06D66476F0D9DC49A3F1EE72C3ACABD498967414",
|
||||
"FAE4B6D8EFC3F8C8E64D001DABEC3A21F544E82714745251B2B4B393F2F43E0DA3D403C64DB95A2CB6E23EBB7B9E94CDD5DDAC54F07C4A61BD3CB10AA6F93B49",
|
||||
"34F7286605A122369540141DED79B8957255DA2D4155ABBF5A8DBB89C8EB7EDE8EEEF1DAA46DC29D751D045DC3B1D658BB64B80FF8589EDDB3824B13DA235A6B",
|
||||
"3B3B48434BE27B9EABABBA43BF6B35F14B30F6A88DC2E750C358470D6B3AA3C18E47DB4017FA55106D8252F016371A00F5F8B070B74BA5F23CFFC5511C9F09F0",
|
||||
"BA289EBD6562C48C3E10A8AD6CE02E73433D1E93D7C9279D4D60A7E879EE11F441A000F48ED9F7C4ED87A45136D7DCCDCA482109C78A51062B3BA4044ADA2469",
|
||||
"022939E2386C5A37049856C850A2BB10A13DFEA4212B4C732A8840A9FFA5FAF54875C5448816B2785A007DA8A8D2BC7D71A54E4E6571F10B600CBDB25D13EDE3",
|
||||
"E6FEC19D89CE8717B1A087024670FE026F6C7CBDA11CAEF959BB2D351BF856F8055D1C0EBDAAA9D1B17886FC2C562B5E99642FC064710C0D3488A02B5ED7F6FD",
|
||||
"94C96F02A8F576ACA32BA61C2B206F907285D9299B83AC175C209A8D43D53BFE683DD1D83E7549CB906C28F59AB7C46F8751366A28C39DD5FE2693C9019666C8",
|
||||
"31A0CD215EBD2CB61DE5B9EDC91E6195E31C59A5648D5C9F737E125B2605708F2E325AB3381C8DCE1A3E958886F1ECDC60318F882CFE20A24191352E617B0F21",
|
||||
"91AB504A522DCE78779F4C6C6BA2E6B6DB5565C76D3E7E7C920CAF7F757EF9DB7C8FCF10E57F03379EA9BF75EB59895D96E149800B6AAE01DB778BB90AFBC989",
|
||||
"D85CABC6BD5B1A01A5AFD8C6734740DA9FD1C1ACC6DB29BFC8A2E5B668B028B6B3154BFB8703FA3180251D589AD38040CEB707C4BAD1B5343CB426B61EAA49C1",
|
||||
"D62EFBEC2CA9C1F8BD66CE8B3F6A898CB3F7566BA6568C618AD1FEB2B65B76C3CE1DD20F7395372FAF28427F61C9278049CF0140DF434F5633048C86B81E0399",
|
||||
"7C8FDC6175439E2C3DB15BAFA7FB06143A6A23BC90F449E79DEEF73C3D492A671715C193B6FEA9F036050B946069856B897E08C00768F5EE5DDCF70B7CD6D0E0",
|
||||
"58602EE7468E6BC9DF21BD51B23C005F72D6CB013F0A1B48CBEC5ECA299299F97F09F54A9A01483EAEB315A6478BAD37BA47CA1347C7C8FC9E6695592C91D723",
|
||||
"27F5B79ED256B050993D793496EDF4807C1D85A7B0A67C9C4FA99860750B0AE66989670A8FFD7856D7CE411599E58C4D77B232A62BEF64D15275BE46A68235FF",
|
||||
"3957A976B9F1887BF004A8DCA942C92D2B37EA52600F25E0C9BC5707D0279C00C6E85A839B0D2D8EB59C51D94788EBE62474A791CADF52CCCF20F5070B6573FC",
|
||||
"EAA2376D55380BF772ECCA9CB0AA4668C95C707162FA86D518C8CE0CA9BF7362B9F2A0ADC3FF59922DF921B94567E81E452F6C1A07FC817CEBE99604B3505D38",
|
||||
"C1E2C78B6B2734E2480EC550434CB5D613111ADCC21D475545C3B1B7E6FF12444476E5C055132E2229DC0F807044BB919B1A5662DD38A9EE65E243A3911AED1A",
|
||||
"8AB48713389DD0FCF9F965D3CE66B1E559A1F8C58741D67683CD971354F452E62D0207A65E436C5D5D8F8EE71C6ABFE50E669004C302B31A7EA8311D4A916051",
|
||||
"24CE0ADDAA4C65038BD1B1C0F1452A0B128777AABC94A29DF2FD6C7E2F85F8AB9AC7EFF516B0E0A825C84A24CFE492EAAD0A6308E46DD42FE8333AB971BB30CA",
|
||||
"5154F929EE03045B6B0C0004FA778EDEE1D139893267CC84825AD7B36C63DE32798E4A166D24686561354F63B00709A1364B3C241DE3FEBF0754045897467CD4",
|
||||
"E74E907920FD87BD5AD636DD11085E50EE70459C443E1CE5809AF2BC2EBA39F9E6D7128E0E3712C316DA06F4705D78A4838E28121D4344A2C79C5E0DB307A677",
|
||||
"BF91A22334BAC20F3FD80663B3CD06C4E8802F30E6B59F90D3035CC9798A217ED5A31ABBDA7FA6842827BDF2A7A1C21F6FCFCCBB54C6C52926F32DA816269BE1",
|
||||
"D9D5C74BE5121B0BD742F26BFFB8C89F89171F3F934913492B0903C271BBE2B3395EF259669BEF43B57F7FCC3027DB01823F6BAEE66E4F9FEAD4D6726C741FCE",
|
||||
"50C8B8CF34CD879F80E2FAAB3230B0C0E1CC3E9DCADEB1B9D97AB923415DD9A1FE38ADDD5C11756C67990B256E95AD6D8F9FEDCE10BF1C90679CDE0ECF1BE347",
|
||||
"0A386E7CD5DD9B77A035E09FE6FEE2C8CE61B5383C87EA43205059C5E4CD4F4408319BB0A82360F6A58E6C9CE3F487C446063BF813BC6BA535E17FC1826CFC91",
|
||||
"1F1459CB6B61CBAC5F0EFE8FC487538F42548987FCD56221CFA7BEB22504769E792C45ADFB1D6B3D60D7B749C8A75B0BDF14E8EA721B95DCA538CA6E25711209",
|
||||
"E58B3836B7D8FEDBB50CA5725C6571E74C0785E97821DAB8B6298C10E4C079D4A6CDF22F0FEDB55032925C16748115F01A105E77E00CEE3D07924DC0D8F90659",
|
||||
"B929CC6505F020158672DEDA56D0DB081A2EE34C00C1100029BDF8EA98034FA4BF3E8655EC697FE36F40553C5BB46801644A627D3342F4FC92B61F03290FB381",
|
||||
"72D353994B49D3E03153929A1E4D4F188EE58AB9E72EE8E512F29BC773913819CE057DDD7002C0433EE0A16114E3D156DD2C4A7E80EE53378B8670F23E33EF56",
|
||||
"C70EF9BFD775D408176737A0736D68517CE1AAAD7E81A93C8C1ED967EA214F56C8A377B1763E676615B60F3988241EAE6EAB9685A5124929D28188F29EAB06F7",
|
||||
"C230F0802679CB33822EF8B3B21BF7A9A28942092901D7DAC3760300831026CF354C9232DF3E084D9903130C601F63C1F4A4A4B8106E468CD443BBE5A734F45F",
|
||||
"6F43094CAFB5EBF1F7A4937EC50F56A4C9DA303CBB55AC1F27F1F1976CD96BEDA9464F0E7B9C54620B8A9FBA983164B8BE3578425A024F5FE199C36356B88972",
|
||||
"3745273F4C38225DB2337381871A0C6AAFD3AF9B018C88AA02025850A5DC3A42A1A3E03E56CBF1B0876D63A441F1D2856A39B8801EB5AF325201C415D65E97FE",
|
||||
"C50C44CCA3EC3EDAAE779A7E179450EBDDA2F97067C690AA6C5A4AC7C30139BB27C0DF4DB3220E63CB110D64F37FFE078DB72653E2DAACF93AE3F0A2D1A7EB2E",
|
||||
"8AEF263E385CBC61E19B28914243262AF5AFE8726AF3CE39A79C27028CF3ECD3F8D2DFD9CFC9AD91B58F6F20778FD5F02894A3D91C7D57D1E4B866A7F364B6BE",
|
||||
"28696141DE6E2D9BCB3235578A66166C1448D3E905A1B482D423BE4BC5369BC8C74DAE0ACC9CC123E1D8DDCE9F97917E8C019C552DA32D39D2219B9ABF0FA8C8",
|
||||
"2FB9EB2085830181903A9DAFE3DB428EE15BE7662224EFD643371FB25646AEE716E531ECA69B2BDC8233F1A8081FA43DA1500302975A77F42FA592136710E9DC",
|
||||
"66F9A7143F7A3314A669BF2E24BBB35014261D639F495B6C9C1F104FE8E320ACA60D4550D69D52EDBD5A3CDEB4014AE65B1D87AA770B69AE5C15F4330B0B0AD8",
|
||||
"F4C4DD1D594C3565E3E25CA43DAD82F62ABEA4835ED4CD811BCD975E46279828D44D4C62C3679F1B7F7B9DD4571D7B49557347B8C5460CBDC1BEF690FB2A08C0",
|
||||
"8F1DC9649C3A84551F8F6E91CAC68242A43B1F8F328EE92280257387FA7559AA6DB12E4AEADC2D26099178749C6864B357F3F83B2FB3EFA8D2A8DB056BED6BCC",
|
||||
"3139C1A7F97AFD1675D460EBBC07F2728AA150DF849624511EE04B743BA0A833092F18C12DC91B4DD243F333402F59FE28ABDBBBAE301E7B659C7A26D5C0F979",
|
||||
"06F94A2996158A819FE34C40DE3CF0379FD9FB85B3E363BA3926A0E7D960E3F4C2E0C70C7CE0CCB2A64FC29869F6E7AB12BD4D3F14FCE943279027E785FB5C29",
|
||||
"C29C399EF3EEE8961E87565C1CE263925FC3D0CE267D13E48DD9E732EE67B0F69FAD56401B0F10FCAAC119201046CCA28C5B14ABDEA3212AE65562F7F138DB3D",
|
||||
"4CEC4C9DF52EEF05C3F6FAAA9791BC7445937183224ECC37A1E58D0132D35617531D7E795F52AF7B1EB9D147DE1292D345FE341823F8E6BC1E5BADCA5C656108",
|
||||
"898BFBAE93B3E18D00697EAB7D9704FA36EC339D076131CEFDF30EDBE8D9CC81C3A80B129659B163A323BAB9793D4FEED92D54DAE966C77529764A09BE88DB45",
|
||||
"EE9BD0469D3AAF4F14035BE48A2C3B84D9B4B1FFF1D945E1F1C1D38980A951BE197B25FE22C731F20AEACC930BA9C4A1F4762227617AD350FDABB4E80273A0F4",
|
||||
"3D4D3113300581CD96ACBF091C3D0F3C310138CD6979E6026CDE623E2DD1B24D4A8638BED1073344783AD0649CC6305CCEC04BEB49F31C633088A99B65130267",
|
||||
"95C0591AD91F921AC7BE6D9CE37E0663ED8011C1CFD6D0162A5572E94368BAC02024485E6A39854AA46FE38E97D6C6B1947CD272D86B06BB5B2F78B9B68D559D",
|
||||
"227B79DED368153BF46C0A3CA978BFDBEF31F3024A5665842468490B0FF748AE04E7832ED4C9F49DE9B1706709D623E5C8C15E3CAECAE8D5E433430FF72F20EB",
|
||||
"5D34F3952F0105EEF88AE8B64C6CE95EBFADE0E02C69B08762A8712D2E4911AD3F941FC4034DC9B2E479FDBCD279B902FAF5D838BB2E0C6495D372B5B7029813",
|
||||
"7F939BF8353ABCE49E77F14F3750AF20B7B03902E1A1E7FB6AAF76D0259CD401A83190F15640E74F3E6C5A90E839C7821F6474757F75C7BF9002084DDC7A62DC",
|
||||
"062B61A2F9A33A71D7D0A06119644C70B0716A504DE7E5E1BE49BD7B86E7ED6817714F9F0FC313D06129597E9A2235EC8521DE36F7290A90CCFC1FFA6D0AEE29",
|
||||
"F29E01EEAE64311EB7F1C6422F946BF7BEA36379523E7B2BBABA7D1D34A22D5EA5F1C5A09D5CE1FE682CCED9A4798D1A05B46CD72DFF5C1B355440B2A2D476BC",
|
||||
"EC38CD3BBAB3EF35D7CB6D5C914298351D8A9DC97FCEE051A8A02F58E3ED6184D0B7810A5615411AB1B95209C3C810114FDEB22452084E77F3F847C6DBAAFE16",
|
||||
"C2AEF5E0CA43E82641565B8CB943AA8BA53550CAEF793B6532FAFAD94B816082F0113A3EA2F63608AB40437ECC0F0229CB8FA224DCF1C478A67D9B64162B92D1",
|
||||
"15F534EFFF7105CD1C254D074E27D5898B89313B7D366DC2D7D87113FA7D53AAE13F6DBA487AD8103D5E854C91FDB6E1E74B2EF6D1431769C30767DDE067A35C",
|
||||
"89ACBCA0B169897A0A2714C2DF8C95B5B79CB69390142B7D6018BB3E3076B099B79A964152A9D912B1B86412B7E372E9CECAD7F25D4CBAB8A317BE36492A67D7",
|
||||
"E3C0739190ED849C9C962FD9DBB55E207E624FCAC1EB417691515499EEA8D8267B7E8F1287A63633AF5011FDE8C4DDF55BFDF722EDF88831414F2CFAED59CB9A",
|
||||
"8D6CF87C08380D2D1506EEE46FD4222D21D8C04E585FBFD08269C98F702833A156326A0724656400EE09351D57B440175E2A5DE93CC5F80DB6DAF83576CF75FA",
|
||||
"DA24BEDE383666D563EEED37F6319BAF20D5C75D1635A6BA5EF4CFA1AC95487E96F8C08AF600AAB87C986EBAD49FC70A58B4890B9C876E091016DAF49E1D322E",
|
||||
"F9D1D1B1E87EA7AE753A029750CC1CF3D0157D41805E245C5617BB934E732F0AE3180B78E05BFE76C7C3051E3E3AC78B9B50C05142657E1E03215D6EC7BFD0FC",
|
||||
"11B7BC1668032048AA43343DE476395E814BBBC223678DB951A1B03A021EFAC948CFBE215F97FE9A72A2F6BC039E3956BFA417C1A9F10D6D7BA5D3D32FF323E5",
|
||||
"B8D9000E4FC2B066EDB91AFEE8E7EB0F24E3A201DB8B6793C0608581E628ED0BCC4E5AA6787992A4BCC44E288093E63EE83ABD0BC3EC6D0934A674A4DA13838A",
|
||||
"CE325E294F9B6719D6B61278276AE06A2564C03BB0B783FAFE785BDF89C7D5ACD83E78756D301B445699024EAEB77B54D477336EC2A4F332F2B3F88765DDB0C3",
|
||||
"29ACC30E9603AE2FCCF90BF97E6CC463EBE28C1B2F9B4B765E70537C25C702A29DCBFBF14C99C54345BA2B51F17B77B5F15DB92BBAD8FA95C471F5D070A137CC",
|
||||
"3379CBAAE562A87B4C0425550FFDD6BFE1203F0D666CC7EA095BE407A5DFE61EE91441CD5154B3E53B4F5FB31AD4C7A9AD5C7AF4AE679AA51A54003A54CA6B2D",
|
||||
"3095A349D245708C7CF550118703D7302C27B60AF5D4E67FC978F8A4E60953C7A04F92FCF41AEE64321CCB707A895851552B1E37B00BC5E6B72FA5BCEF9E3FFF",
|
||||
"07262D738B09321F4DBCCEC4BB26F48CB0F0ED246CE0B31B9A6E7BC683049F1F3E5545F28CE932DD985C5AB0F43BD6DE0770560AF329065ED2E49D34624C2CBB",
|
||||
"B6405ECA8EE3316C87061CC6EC18DBA53E6C250C63BA1F3BAE9E55DD3498036AF08CD272AA24D713C6020D77AB2F3919AF1A32F307420618AB97E73953994FB4",
|
||||
"7EE682F63148EE45F6E5315DA81E5C6E557C2C34641FC509C7A5701088C38A74756168E2CD8D351E88FD1A451F360A01F5B2580F9B5A2E8CFC138F3DD59A3FFC",
|
||||
"1D263C179D6B268F6FA016F3A4F29E943891125ED8593C81256059F5A7B44AF2DCB2030D175C00E62ECAF7EE96682AA07AB20A611024A28532B1C25B86657902",
|
||||
"106D132CBDB4CD2597812846E2BC1BF732FEC5F0A5F65DBB39EC4E6DC64AB2CE6D24630D0F15A805C3540025D84AFA98E36703C3DBEE713E72DDE8465BC1BE7E",
|
||||
"0E79968226650667A8D862EA8DA4891AF56A4E3A8B6D1750E394F0DEA76D640D85077BCEC2CC86886E506751B4F6A5838F7F0B5FEF765D9DC90DCDCBAF079F08",
|
||||
"521156A82AB0C4E566E5844D5E31AD9AAF144BBD5A464FDCA34DBD5717E8FF711D3FFEBBFA085D67FE996A34F6D3E4E60B1396BF4B1610C263BDBB834D560816",
|
||||
"1ABA88BEFC55BC25EFBCE02DB8B9933E46F57661BAEABEB21CC2574D2A518A3CBA5DC5A38E49713440B25F9C744E75F6B85C9D8F4681F676160F6105357B8406",
|
||||
"5A9949FCB2C473CDA968AC1B5D08566DC2D816D960F57E63B898FA701CF8EBD3F59B124D95BFBBEDC5F1CF0E17D5EAED0C02C50B69D8A402CABCCA4433B51FD4",
|
||||
"B0CEAD09807C672AF2EB2B0F06DDE46CF5370E15A4096B1A7D7CBB36EC31C205FBEFCA00B7A4162FA89FB4FB3EB78D79770C23F44E7206664CE3CD931C291E5D",
|
||||
"BB6664931EC97044E45B2AE420AE1C551A8874BC937D08E969399C3964EBDBA8346CDD5D09CAAFE4C28BA7EC788191CECA65DDD6F95F18583E040D0F30D0364D",
|
||||
"65BC770A5FAA3792369803683E844B0BE7EE96F29F6D6A35568006BD5590F9A4EF639B7A8061C7B0424B66B60AC34AF3119905F33A9D8C3AE18382CA9B689900",
|
||||
"EA9B4DCA333336AAF839A45C6EAA48B8CB4C7DDABFFEA4F643D6357EA6628A480A5B45F2B052C1B07D1FEDCA918B6F1139D80F74C24510DCBAA4BE70EACC1B06",
|
||||
"E6342FB4A780AD975D0E24BCE149989B91D360557E87994F6B457B895575CC02D0C15BAD3CE7577F4C63927FF13F3E381FF7E72BDBE745324844A9D27E3F1C01",
|
||||
"3E209C9B33E8E461178AB46B1C64B49A07FB745F1C8BC95FBFB94C6B87C69516651B264EF980937FAD41238B91DDC011A5DD777C7EFD4494B4B6ECD3A9C22AC0",
|
||||
"FD6A3D5B1875D80486D6E69694A56DBB04A99A4D051F15DB2689776BA1C4882E6D462A603B7015DC9F4B7450F05394303B8652CFB404A266962C41BAE6E18A94",
|
||||
"951E27517E6BAD9E4195FC8671DEE3E7E9BE69CEE1422CB9FECFCE0DBA875F7B310B93EE3A3D558F941F635F668FF832D2C1D033C5E2F0997E4C66F147344E02",
|
||||
"8EBA2F874F1AE84041903C7C4253C82292530FC8509550BFDC34C95C7E2889D5650B0AD8CB988E5C4894CB87FBFBB19612EA93CCC4C5CAD17158B9763464B492",
|
||||
"16F712EAA1B7C6354719A8E7DBDFAF55E4063A4D277D947550019B38DFB564830911057D50506136E2394C3B28945CC964967D54E3000C2181626CFB9B73EFD2",
|
||||
"C39639E7D5C7FB8CDD0FD3E6A52096039437122F21C78F1679CEA9D78A734C56ECBEB28654B4F18E342C331F6F7229EC4B4BC281B2D80A6EB50043F31796C88C",
|
||||
"72D081AF99F8A173DCC9A0AC4EB3557405639A29084B54A40172912A2F8A395129D5536F0918E902F9E8FA6000995F4168DDC5F893011BE6A0DBC9B8A1A3F5BB",
|
||||
"C11AA81E5EFD24D5FC27EE586CFD8847FBB0E27601CCECE5ECCA0198E3C7765393BB74457C7E7A27EB9170350E1FB53857177506BE3E762CC0F14D8C3AFE9077",
|
||||
"C28F2150B452E6C0C424BCDE6F8D72007F9310FED7F2F87DE0DBB64F4479D6C1441BA66F44B2ACCEE61609177ED340128B407ECEC7C64BBE50D63D22D8627727",
|
||||
"F63D88122877EC30B8C8B00D22E89000A966426112BD44166E2F525B769CCBE9B286D437A0129130DDE1A86C43E04BEDB594E671D98283AFE64CE331DE9828FD",
|
||||
"348B0532880B88A6614A8D7408C3F913357FBB60E995C60205BE9139E74998AEDE7F4581E42F6B52698F7FA1219708C14498067FD1E09502DE83A77DD281150C",
|
||||
"5133DC8BEF725359DFF59792D85EAF75B7E1DCD1978B01C35B1B85FCEBC63388AD99A17B6346A217DC1A9622EBD122ECF6913C4D31A6B52A695B86AF00D741A0",
|
||||
"2753C4C0E98ECAD806E88780EC27FCCD0F5C1AB547F9E4BF1659D192C23AA2CC971B58B6802580BAEF8ADC3B776EF7086B2545C2987F348EE3719CDEF258C403",
|
||||
"B1663573CE4B9D8CAEFC865012F3E39714B9898A5DA6CE17C25A6A47931A9DDB9BBE98ADAA553BEED436E89578455416C2A52A525CF2862B8D1D49A2531B7391",
|
||||
"64F58BD6BFC856F5E873B2A2956EA0EDA0D6DB0DA39C8C7FC67C9F9FEEFCFF3072CDF9E6EA37F69A44F0C61AA0DA3693C2DB5B54960C0281A088151DB42B11E8",
|
||||
"0764C7BE28125D9065C4B98A69D60AEDE703547C66A12E17E1C618994132F5EF82482C1E3FE3146CC65376CC109F0138ED9A80E49F1F3C7D610D2F2432F20605",
|
||||
"F748784398A2FF03EBEB07E155E66116A839741A336E32DA71EC696001F0AD1B25CD48C69CFCA7265ECA1DD71904A0CE748AC4124F3571076DFA7116A9CF00E9",
|
||||
"3F0DBC0186BCEB6B785BA78D2A2A013C910BE157BDAFFAE81BB6663B1A73722F7F1228795F3ECADA87CF6EF0078474AF73F31ECA0CC200ED975B6893F761CB6D",
|
||||
"D4762CD4599876CA75B2B8FE249944DBD27ACE741FDAB93616CBC6E425460FEB51D4E7ADCC38180E7FC47C89024A7F56191ADB878DFDE4EAD62223F5A2610EFE",
|
||||
"CD36B3D5B4C91B90FCBBA79513CFEE1907D8645A162AFD0CD4CF4192D4A5F4C892183A8EACDB2B6B6A9D9AA8C11AC1B261B380DBEE24CA468F1BFD043C58EEFE",
|
||||
"98593452281661A53C48A9D8CD790826C1A1CE567738053D0BEE4A91A3D5BD92EEFDBABEBE3204F2031CA5F781BDA99EF5D8AE56E5B04A9E1ECD21B0EB05D3E1",
|
||||
"771F57DD2775CCDAB55921D3E8E30CCF484D61FE1C1B9C2AE819D0FB2A12FAB9BE70C4A7A138DA84E8280435DAADE5BBE66AF0836A154F817FB17F3397E725A3",
|
||||
"C60897C6F828E21F16FBB5F15B323F87B6C8955EABF1D38061F707F608ABDD993FAC3070633E286CF8339CE295DD352DF4B4B40B2F29DA1DD50B3A05D079E6BB",
|
||||
"8210CD2C2D3B135C2CF07FA0D1433CD771F325D075C6469D9C7F1BA0943CD4AB09808CABF4ACB9CE5BB88B498929B4B847F681AD2C490D042DB2AEC94214B06B",
|
||||
"1D4EDFFFD8FD80F7E4107840FA3AA31E32598491E4AF7013C197A65B7F36DD3AC4B478456111CD4309D9243510782FA31B7C4C95FA951520D020EB7E5C36E4EF",
|
||||
"AF8E6E91FAB46CE4873E1A50A8EF448CC29121F7F74DEEF34A71EF89CC00D9274BC6C2454BBB3230D8B2EC94C62B1DEC85F3593BFA30EA6F7A44D7C09465A253",
|
||||
"29FD384ED4906F2D13AA9FE7AF905990938BED807F1832454A372AB412EEA1F5625A1FCC9AC8343B7C67C5ABA6E0B1CC4644654913692C6B39EB9187CEACD3EC",
|
||||
"A268C7885D9874A51C44DFFED8EA53E94F78456E0B2ED99FF5A3924760813826D960A15EDBEDBB5DE5226BA4B074E71B05C55B9756BB79E55C02754C2C7B6C8A",
|
||||
"0CF8545488D56A86817CD7ECB10F7116B7EA530A45B6EA497B6C72C997E09E3D0DA8698F46BB006FC977C2CD3D1177463AC9057FDD1662C85D0C126443C10473",
|
||||
"B39614268FDD8781515E2CFEBF89B4D5402BAB10C226E6344E6B9AE000FB0D6C79CB2F3EC80E80EAEB1980D2F8698916BD2E9F747236655116649CD3CA23A837",
|
||||
"74BEF092FC6F1E5DBA3663A3FB003B2A5BA257496536D99F62B9D73F8F9EB3CE9FF3EEC709EB883655EC9EB896B9128F2AFC89CF7D1AB58A72F4A3BF034D2B4A",
|
||||
"3A988D38D75611F3EF38B8774980B33E573B6C57BEE0469BA5EED9B44F29945E7347967FBA2C162E1C3BE7F310F2F75EE2381E7BFD6B3F0BAEA8D95DFB1DAFB1",
|
||||
"58AEDFCE6F67DDC85A28C992F1C0BD0969F041E66F1EE88020A125CBFCFEBCD61709C9C4EBA192C15E69F020D462486019FA8DEA0CD7A42921A19D2FE546D43D",
|
||||
"9347BD291473E6B4E368437B8E561E065F649A6D8ADA479AD09B1999A8F26B91CF6120FD3BFE014E83F23ACFA4C0AD7B3712B2C3C0733270663112CCD9285CD9",
|
||||
"B32163E7C5DBB5F51FDC11D2EAC875EFBBCB7E7699090A7E7FF8A8D50795AF5D74D9FF98543EF8CDF89AC13D0485278756E0EF00C817745661E1D59FE38E7537",
|
||||
"1085D78307B1C4B008C57A2E7E5B234658A0A82E4FF1E4AAAC72B312FDA0FE27D233BC5B10E9CC17FDC7697B540C7D95EB215A19A1A0E20E1ABFA126EFD568C7",
|
||||
"4E5C734C7DDE011D83EAC2B7347B373594F92D7091B9CA34CB9C6F39BDF5A8D2F134379E16D822F6522170CCF2DDD55C84B9E6C64FC927AC4CF8DFB2A17701F2",
|
||||
"695D83BD990A1117B3D0CE06CC888027D12A054C2677FD82F0D4FBFC93575523E7991A5E35A3752E9B70CE62992E268A877744CDD435F5F130869C9A2074B338",
|
||||
"A6213743568E3B3158B9184301F3690847554C68457CB40FC9A4B8CFD8D4A118C301A07737AEDA0F929C68913C5F51C80394F53BFF1C3E83B2E40CA97EBA9E15",
|
||||
"D444BFA2362A96DF213D070E33FA841F51334E4E76866B8139E8AF3BB3398BE2DFADDCBC56B9146DE9F68118DC5829E74B0C28D7711907B121F9161CB92B69A9",
|
||||
"142709D62E28FCCCD0AF97FAD0F8465B971E82201DC51070FAA0372AA43E92484BE1C1E73BA10906D5D1853DB6A4106E0A7BF9800D373D6DEE2D46D62EF2A461"
|
||||
};
|
||||
}
|
||||
}
|
34
csharp/Blake2Sharp.sln
Normal file
34
csharp/Blake2Sharp.sln
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{98C3F5AC-1FDF-4AAF-B067-A9E9C663D87B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blake2Sharp", "Blake2Sharp\Blake2Sharp.csproj", "{E21AB364-9130-4F14-ABE1-18FA0C089130}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blake2Sharp.Tests", "Blake2Sharp.Tests\Blake2Sharp.Tests.csproj", "{A32451B3-03A3-4CB3-AD9F-1408143D6AB7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blake2Sharp.CompressionCodeGen", "Blake2Sharp.CompressionCodeGen\Blake2Sharp.CompressionCodeGen.csproj", "{17466328-5736-4EA1-A88D-CE016CCA2E80}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E21AB364-9130-4F14-ABE1-18FA0C089130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E21AB364-9130-4F14-ABE1-18FA0C089130}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E21AB364-9130-4F14-ABE1-18FA0C089130}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E21AB364-9130-4F14-ABE1-18FA0C089130}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A32451B3-03A3-4CB3-AD9F-1408143D6AB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A32451B3-03A3-4CB3-AD9F-1408143D6AB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A32451B3-03A3-4CB3-AD9F-1408143D6AB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A32451B3-03A3-4CB3-AD9F-1408143D6AB7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{17466328-5736-4EA1-A88D-CE016CCA2E80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{17466328-5736-4EA1-A88D-CE016CCA2E80}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{17466328-5736-4EA1-A88D-CE016CCA2E80}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{17466328-5736-4EA1-A88D-CE016CCA2E80}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
72
csharp/Blake2Sharp/Blake2B.cs
Normal file
72
csharp/Blake2Sharp/Blake2B.cs
Normal file
@ -0,0 +1,72 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
public static class Blake2B
|
||||
{
|
||||
public static Hasher Create()
|
||||
{
|
||||
return Create(new Blake2BConfig());
|
||||
}
|
||||
|
||||
public static Hasher Create(Blake2BConfig config)
|
||||
{
|
||||
return new Blake2BHasher(config);
|
||||
}
|
||||
|
||||
/*public static Hasher CreateParallel(int parallelism = 4)
|
||||
{
|
||||
return CreateParallel(null, parallelism);
|
||||
}
|
||||
|
||||
public static Hasher CreateParallel(Blake2Config config, int parallelism = 4)
|
||||
{
|
||||
if (parallelism < 2)
|
||||
throw new ArgumentOutOfRangeException("parallelism", "parallism must be at least 2");
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static Hasher CreateTreeHasher(Blake2BConfig config, Blake2TreeConfig treeConfig)
|
||||
{
|
||||
}
|
||||
|
||||
public static NodeHasher CreateNodeHasher(Blake2BConfig config, Blake2TreeConfig treeConfig)
|
||||
{
|
||||
}*/
|
||||
|
||||
public static byte[] ComputeHash(byte[] data, int start, int count)
|
||||
{
|
||||
return ComputeHash(data, start, count, null);
|
||||
}
|
||||
|
||||
public static byte[] ComputeHash(byte[] data)
|
||||
{
|
||||
return ComputeHash(data, 0, data.Length, null);
|
||||
}
|
||||
|
||||
public static byte[] ComputeHash(byte[] data, Blake2BConfig config)
|
||||
{
|
||||
return ComputeHash(data, 0, data.Length, config);
|
||||
}
|
||||
|
||||
public static byte[] ComputeHash(byte[] data, int start, int count, Blake2BConfig config)
|
||||
{
|
||||
var hasher = Create(config);
|
||||
hasher.Update(data, start, count);
|
||||
return hasher.Finish();
|
||||
}
|
||||
//public static byte[] ComputeParallelHash(byte[] data);
|
||||
//public static byte[] ComputeParallelHash(byte[] data, Blake2Config config);
|
||||
}
|
||||
}
|
57
csharp/Blake2Sharp/Blake2BConfig.cs
Normal file
57
csharp/Blake2Sharp/Blake2BConfig.cs
Normal file
@ -0,0 +1,57 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
public sealed class Blake2BConfig : ICloneable
|
||||
{
|
||||
public byte[] Personalization { get; set; }
|
||||
public byte[] Salt { get; set; }
|
||||
public byte[] Key { get; set; }
|
||||
public int OutputSizeInBytes { get; set; }
|
||||
public int OutputSizeInBits
|
||||
{
|
||||
get { return OutputSizeInBytes * 8; }
|
||||
set
|
||||
{
|
||||
if (value % 8 == 0)
|
||||
throw new ArgumentException("Output size must be a multiple of 8 bits");
|
||||
OutputSizeInBytes = value / 8;
|
||||
}
|
||||
}
|
||||
|
||||
public Blake2BConfig()
|
||||
{
|
||||
OutputSizeInBytes = 64;
|
||||
}
|
||||
|
||||
public Blake2BConfig Clone()
|
||||
{
|
||||
var result = new Blake2BConfig();
|
||||
result.OutputSizeInBytes = OutputSizeInBytes;
|
||||
if (Key != null)
|
||||
result.Key = (byte[])Key.Clone();
|
||||
if (Personalization != null)
|
||||
result.Personalization = (byte[])Personalization.Clone();
|
||||
if (Salt != null)
|
||||
result.Salt = (byte[])Salt.Clone();
|
||||
return result;
|
||||
}
|
||||
|
||||
object ICloneable.Clone()
|
||||
{
|
||||
return Clone();
|
||||
}
|
||||
}
|
||||
}
|
1455
csharp/Blake2Sharp/Blake2BCore-FullyUnrolled.cs
Normal file
1455
csharp/Blake2Sharp/Blake2BCore-FullyUnrolled.cs
Normal file
@ -0,0 +1,1455 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
#if true
|
||||
public sealed partial class Blake2BCore
|
||||
{
|
||||
partial void Compress(byte[] block, int start)
|
||||
{
|
||||
var h = _h;
|
||||
var m = _m;
|
||||
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
Buffer.BlockCopy(block, start, m, 0, BlockSizeInBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
m[i] = BytesToUInt64(block, start + (i << 3));
|
||||
}
|
||||
|
||||
/*var m0 = m[0];
|
||||
var m1 = m[1];
|
||||
var m2 = m[2];
|
||||
var m3 = m[3];
|
||||
var m4 = m[4];
|
||||
var m5 = m[5];
|
||||
var m6 = m[6];
|
||||
var m7 = m[7];
|
||||
var m8 = m[8];
|
||||
var m9 = m[9];
|
||||
var m10 = m[10];
|
||||
var m11 = m[11];
|
||||
var m12 = m[12];
|
||||
var m13 = m[13];
|
||||
var m14 = m[14];
|
||||
var m15 = m[15];*/
|
||||
|
||||
var v0 = h[0];
|
||||
var v1 = h[1];
|
||||
var v2 = h[2];
|
||||
var v3 = h[3];
|
||||
var v4 = h[4];
|
||||
var v5 = h[5];
|
||||
var v6 = h[6];
|
||||
var v7 = h[7];
|
||||
|
||||
var v8 = IV0;
|
||||
var v9 = IV1;
|
||||
var v10 = IV2;
|
||||
var v11 = IV3;
|
||||
var v12 = IV4 ^ _counter0;
|
||||
var v13 = IV5 ^ _counter1;
|
||||
var v14 = IV6 ^ _finalizationFlag0;
|
||||
var v15 = IV7 ^ _finalizationFlag1;
|
||||
|
||||
// Rounds
|
||||
|
||||
//System.Diagnostics.Debugger.Break();
|
||||
|
||||
// ##### Round(0) #####
|
||||
// G(0, 0, v0, v4, v8, v12)
|
||||
v0 = v0 + v4 + m[0];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[1];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(0, 1, v1, v5, v9, v13)
|
||||
v1 = v1 + v5 + m[2];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[3];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(0, 2, v2, v6, v10, v14)
|
||||
v2 = v2 + v6 + m[4];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[5];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(0, 3, v3, v7, v11, v15)
|
||||
v3 = v3 + v7 + m[6];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[7];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(0, 4, v0, v5, v10, v15)
|
||||
v0 = v0 + v5 + m[8];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[9];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(0, 5, v1, v6, v11, v12)
|
||||
v1 = v1 + v6 + m[10];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[11];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(0, 6, v2, v7, v8, v13)
|
||||
v2 = v2 + v7 + m[12];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[13];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(0, 7, v3, v4, v9, v14)
|
||||
v3 = v3 + v4 + m[14];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[15];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
|
||||
// ##### Round(1) #####
|
||||
// G(1, 0, v0, v4, v8, v12)
|
||||
v0 = v0 + v4 + m[14];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[10];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(1, 1, v1, v5, v9, v13)
|
||||
v1 = v1 + v5 + m[4];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[8];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(1, 2, v2, v6, v10, v14)
|
||||
v2 = v2 + v6 + m[9];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[15];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(1, 3, v3, v7, v11, v15)
|
||||
v3 = v3 + v7 + m[13];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[6];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(1, 4, v0, v5, v10, v15)
|
||||
v0 = v0 + v5 + m[1];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[12];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(1, 5, v1, v6, v11, v12)
|
||||
v1 = v1 + v6 + m[0];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[2];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(1, 6, v2, v7, v8, v13)
|
||||
v2 = v2 + v7 + m[11];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[7];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(1, 7, v3, v4, v9, v14)
|
||||
v3 = v3 + v4 + m[5];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[3];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
|
||||
// ##### Round(2) #####
|
||||
// G(2, 0, v0, v4, v8, v12)
|
||||
v0 = v0 + v4 + m[11];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[8];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(2, 1, v1, v5, v9, v13)
|
||||
v1 = v1 + v5 + m[12];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[0];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(2, 2, v2, v6, v10, v14)
|
||||
v2 = v2 + v6 + m[5];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[2];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(2, 3, v3, v7, v11, v15)
|
||||
v3 = v3 + v7 + m[15];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[13];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(2, 4, v0, v5, v10, v15)
|
||||
v0 = v0 + v5 + m[10];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[14];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(2, 5, v1, v6, v11, v12)
|
||||
v1 = v1 + v6 + m[3];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[6];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(2, 6, v2, v7, v8, v13)
|
||||
v2 = v2 + v7 + m[7];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[1];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(2, 7, v3, v4, v9, v14)
|
||||
v3 = v3 + v4 + m[9];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[4];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
|
||||
// ##### Round(3) #####
|
||||
// G(3, 0, v0, v4, v8, v12)
|
||||
v0 = v0 + v4 + m[7];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[9];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(3, 1, v1, v5, v9, v13)
|
||||
v1 = v1 + v5 + m[3];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[1];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(3, 2, v2, v6, v10, v14)
|
||||
v2 = v2 + v6 + m[13];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[12];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(3, 3, v3, v7, v11, v15)
|
||||
v3 = v3 + v7 + m[11];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[14];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(3, 4, v0, v5, v10, v15)
|
||||
v0 = v0 + v5 + m[2];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[6];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(3, 5, v1, v6, v11, v12)
|
||||
v1 = v1 + v6 + m[5];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[10];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(3, 6, v2, v7, v8, v13)
|
||||
v2 = v2 + v7 + m[4];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[0];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(3, 7, v3, v4, v9, v14)
|
||||
v3 = v3 + v4 + m[15];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[8];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
|
||||
// ##### Round(4) #####
|
||||
// G(4, 0, v0, v4, v8, v12)
|
||||
v0 = v0 + v4 + m[9];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[0];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(4, 1, v1, v5, v9, v13)
|
||||
v1 = v1 + v5 + m[5];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[7];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(4, 2, v2, v6, v10, v14)
|
||||
v2 = v2 + v6 + m[2];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[4];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(4, 3, v3, v7, v11, v15)
|
||||
v3 = v3 + v7 + m[10];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[15];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(4, 4, v0, v5, v10, v15)
|
||||
v0 = v0 + v5 + m[14];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[1];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(4, 5, v1, v6, v11, v12)
|
||||
v1 = v1 + v6 + m[11];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[12];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(4, 6, v2, v7, v8, v13)
|
||||
v2 = v2 + v7 + m[6];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[8];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(4, 7, v3, v4, v9, v14)
|
||||
v3 = v3 + v4 + m[3];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[13];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
|
||||
// ##### Round(5) #####
|
||||
// G(5, 0, v0, v4, v8, v12)
|
||||
v0 = v0 + v4 + m[2];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[12];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(5, 1, v1, v5, v9, v13)
|
||||
v1 = v1 + v5 + m[6];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[10];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(5, 2, v2, v6, v10, v14)
|
||||
v2 = v2 + v6 + m[0];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[11];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(5, 3, v3, v7, v11, v15)
|
||||
v3 = v3 + v7 + m[8];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[3];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(5, 4, v0, v5, v10, v15)
|
||||
v0 = v0 + v5 + m[4];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[13];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(5, 5, v1, v6, v11, v12)
|
||||
v1 = v1 + v6 + m[7];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[5];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(5, 6, v2, v7, v8, v13)
|
||||
v2 = v2 + v7 + m[15];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[14];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(5, 7, v3, v4, v9, v14)
|
||||
v3 = v3 + v4 + m[1];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[9];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
|
||||
// ##### Round(6) #####
|
||||
// G(6, 0, v0, v4, v8, v12)
|
||||
v0 = v0 + v4 + m[12];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[5];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(6, 1, v1, v5, v9, v13)
|
||||
v1 = v1 + v5 + m[1];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[15];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(6, 2, v2, v6, v10, v14)
|
||||
v2 = v2 + v6 + m[14];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[13];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(6, 3, v3, v7, v11, v15)
|
||||
v3 = v3 + v7 + m[4];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[10];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(6, 4, v0, v5, v10, v15)
|
||||
v0 = v0 + v5 + m[0];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[7];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(6, 5, v1, v6, v11, v12)
|
||||
v1 = v1 + v6 + m[6];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[3];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(6, 6, v2, v7, v8, v13)
|
||||
v2 = v2 + v7 + m[9];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[2];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(6, 7, v3, v4, v9, v14)
|
||||
v3 = v3 + v4 + m[8];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[11];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
|
||||
// ##### Round(7) #####
|
||||
// G(7, 0, v0, v4, v8, v12)
|
||||
v0 = v0 + v4 + m[13];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[11];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(7, 1, v1, v5, v9, v13)
|
||||
v1 = v1 + v5 + m[7];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[14];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(7, 2, v2, v6, v10, v14)
|
||||
v2 = v2 + v6 + m[12];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[1];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(7, 3, v3, v7, v11, v15)
|
||||
v3 = v3 + v7 + m[3];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[9];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(7, 4, v0, v5, v10, v15)
|
||||
v0 = v0 + v5 + m[5];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[0];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(7, 5, v1, v6, v11, v12)
|
||||
v1 = v1 + v6 + m[15];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[4];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(7, 6, v2, v7, v8, v13)
|
||||
v2 = v2 + v7 + m[8];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[6];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(7, 7, v3, v4, v9, v14)
|
||||
v3 = v3 + v4 + m[2];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[10];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
|
||||
// ##### Round(8) #####
|
||||
// G(8, 0, v0, v4, v8, v12)
|
||||
v0 = v0 + v4 + m[6];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[15];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(8, 1, v1, v5, v9, v13)
|
||||
v1 = v1 + v5 + m[14];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[9];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(8, 2, v2, v6, v10, v14)
|
||||
v2 = v2 + v6 + m[11];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[3];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(8, 3, v3, v7, v11, v15)
|
||||
v3 = v3 + v7 + m[0];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[8];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(8, 4, v0, v5, v10, v15)
|
||||
v0 = v0 + v5 + m[12];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[2];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(8, 5, v1, v6, v11, v12)
|
||||
v1 = v1 + v6 + m[13];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[7];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(8, 6, v2, v7, v8, v13)
|
||||
v2 = v2 + v7 + m[1];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[4];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(8, 7, v3, v4, v9, v14)
|
||||
v3 = v3 + v4 + m[10];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[5];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
|
||||
// ##### Round(9) #####
|
||||
// G(9, 0, v0, v4, v8, v12)
|
||||
v0 = v0 + v4 + m[10];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[2];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(9, 1, v1, v5, v9, v13)
|
||||
v1 = v1 + v5 + m[8];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[4];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(9, 2, v2, v6, v10, v14)
|
||||
v2 = v2 + v6 + m[7];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[6];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(9, 3, v3, v7, v11, v15)
|
||||
v3 = v3 + v7 + m[1];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[5];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(9, 4, v0, v5, v10, v15)
|
||||
v0 = v0 + v5 + m[15];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[11];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(9, 5, v1, v6, v11, v12)
|
||||
v1 = v1 + v6 + m[9];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[14];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(9, 6, v2, v7, v8, v13)
|
||||
v2 = v2 + v7 + m[3];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[12];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(9, 7, v3, v4, v9, v14)
|
||||
v3 = v3 + v4 + m[13];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[0];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
|
||||
// ##### Round(10) #####
|
||||
// G(10, 0, v0, v4, v8, v12)
|
||||
v0 = v0 + v4 + m[0];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[1];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(10, 1, v1, v5, v9, v13)
|
||||
v1 = v1 + v5 + m[2];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[3];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(10, 2, v2, v6, v10, v14)
|
||||
v2 = v2 + v6 + m[4];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[5];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(10, 3, v3, v7, v11, v15)
|
||||
v3 = v3 + v7 + m[6];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[7];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(10, 4, v0, v5, v10, v15)
|
||||
v0 = v0 + v5 + m[8];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[9];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(10, 5, v1, v6, v11, v12)
|
||||
v1 = v1 + v6 + m[10];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[11];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(10, 6, v2, v7, v8, v13)
|
||||
v2 = v2 + v7 + m[12];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[13];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(10, 7, v3, v4, v9, v14)
|
||||
v3 = v3 + v4 + m[14];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[15];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
|
||||
// ##### Round(11) #####
|
||||
// G(11, 0, v0, v4, v8, v12)
|
||||
v0 = v0 + v4 + m[14];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[10];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(11, 1, v1, v5, v9, v13)
|
||||
v1 = v1 + v5 + m[4];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[8];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(11, 2, v2, v6, v10, v14)
|
||||
v2 = v2 + v6 + m[9];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[15];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(11, 3, v3, v7, v11, v15)
|
||||
v3 = v3 + v7 + m[13];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[6];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(11, 4, v0, v5, v10, v15)
|
||||
v0 = v0 + v5 + m[1];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[12];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(11, 5, v1, v6, v11, v12)
|
||||
v1 = v1 + v6 + m[0];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[2];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(11, 6, v2, v7, v8, v13)
|
||||
v2 = v2 + v7 + m[11];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[7];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(11, 7, v3, v4, v9, v14)
|
||||
v3 = v3 + v4 + m[5];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[3];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
|
||||
|
||||
|
||||
//Finalization
|
||||
h[0] ^= v0 ^ v8;
|
||||
h[1] ^= v1 ^ v9;
|
||||
h[2] ^= v2 ^ v10;
|
||||
h[3] ^= v3 ^ v11;
|
||||
h[4] ^= v4 ^ v12;
|
||||
h[5] ^= v5 ^ v13;
|
||||
h[6] ^= v6 ^ v14;
|
||||
h[7] ^= v7 ^ v15;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
177
csharp/Blake2Sharp/Blake2BCore-Inline.cs
Normal file
177
csharp/Blake2Sharp/Blake2BCore-Inline.cs
Normal file
@ -0,0 +1,177 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
using System;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
#if false
|
||||
public sealed partial class Blake2BCore
|
||||
{
|
||||
partial void Compress(byte[] block, int start)
|
||||
{
|
||||
var h = _h;
|
||||
var m = _m;
|
||||
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
Buffer.BlockCopy(block, start, m, 0, BlockSizeInBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
m[i] = BytesToUInt64(block, start + (i << 3));
|
||||
}
|
||||
|
||||
var v0 = h[0];
|
||||
var v1 = h[1];
|
||||
var v2 = h[2];
|
||||
var v3 = h[3];
|
||||
var v4 = h[4];
|
||||
var v5 = h[5];
|
||||
var v6 = h[6];
|
||||
var v7 = h[7];
|
||||
|
||||
var v8 = IV0;
|
||||
var v9 = IV1;
|
||||
var v10 = IV2;
|
||||
var v11 = IV3;
|
||||
var v12 = IV4 ^ _counter0;
|
||||
var v13 = IV5 ^ _counter1;
|
||||
var v14 = IV6 ^ _finaliziationFlag0;
|
||||
var v15 = IV7 ^ _finaliziationFlag1;
|
||||
|
||||
for (int r = 0; r < NumberOfRounds; ++r)
|
||||
{
|
||||
// G(r,0,v0,v4,v8,v12)
|
||||
v0 = v0 + v4 + m[Sigma[16 * r + 2 * 0 + 0]];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v0 = v0 + v4 + m[Sigma[16 * r + 2 * 0 + 1]];
|
||||
v12 ^= v0;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v8 = v8 + v12;
|
||||
v4 ^= v8;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
|
||||
// G(r,1,v1,v5,v9,v13)
|
||||
v1 = v1 + v5 + m[Sigma[16 * r + 2 * 1 + 0]];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v1 = v1 + v5 + m[Sigma[16 * r + 2 * 1 + 1]];
|
||||
v13 ^= v1;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v9 = v9 + v13;
|
||||
v5 ^= v9;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(r,2,v2,v6,v10,v14)
|
||||
v2 = v2 + v6 + m[Sigma[16 * r + 2 * 2 + 0]];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v2 = v2 + v6 + m[Sigma[16 * r + 2 * 2 + 1]];
|
||||
v14 ^= v2;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v10 = v10 + v14;
|
||||
v6 ^= v10;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(r,3,v3,v7,v11,v15)
|
||||
v3 = v3 + v7 + m[Sigma[16 * r + 2 * 3 + 0]];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v3 = v3 + v7 + m[Sigma[16 * r + 2 * 3 + 1]];
|
||||
v15 ^= v3;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v11 = v11 + v15;
|
||||
v7 ^= v11;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(r,4,v0,v5,v10,v15)
|
||||
v0 = v0 + v5 + m[Sigma[16 * r + 2 * 4 + 0]];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 32) | (v15 << (64 - 32)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 24) | (v5 << (64 - 24)));
|
||||
v0 = v0 + v5 + m[Sigma[16 * r + 2 * 4 + 1]];
|
||||
v15 ^= v0;
|
||||
v15 = ((v15 >> 16) | (v15 << (64 - 16)));
|
||||
v10 = v10 + v15;
|
||||
v5 ^= v10;
|
||||
v5 = ((v5 >> 63) | (v5 << (64 - 63)));
|
||||
|
||||
// G(r,5,v1,v6,v11,v12)
|
||||
v1 = v1 + v6 + m[Sigma[16 * r + 2 * 5 + 0]];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 32) | (v12 << (64 - 32)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 24) | (v6 << (64 - 24)));
|
||||
v1 = v1 + v6 + m[Sigma[16 * r + 2 * 5 + 1]];
|
||||
v12 ^= v1;
|
||||
v12 = ((v12 >> 16) | (v12 << (64 - 16)));
|
||||
v11 = v11 + v12;
|
||||
v6 ^= v11;
|
||||
v6 = ((v6 >> 63) | (v6 << (64 - 63)));
|
||||
|
||||
// G(r,6,v2,v7,v8,v13)
|
||||
v2 = v2 + v7 + m[Sigma[16 * r + 2 * 6 + 0]];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 32) | (v13 << (64 - 32)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 24) | (v7 << (64 - 24)));
|
||||
v2 = v2 + v7 + m[Sigma[16 * r + 2 * 6 + 1]];
|
||||
v13 ^= v2;
|
||||
v13 = ((v13 >> 16) | (v13 << (64 - 16)));
|
||||
v8 = v8 + v13;
|
||||
v7 ^= v8;
|
||||
v7 = ((v7 >> 63) | (v7 << (64 - 63)));
|
||||
|
||||
// G(r,7,v3,v4,v9,v14)
|
||||
v3 = v3 + v4 + m[Sigma[16 * r + 2 * 7 + 0]];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 32) | (v14 << (64 - 32)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 24) | (v4 << (64 - 24)));
|
||||
v3 = v3 + v4 + m[Sigma[16 * r + 2 * 7 + 1]];
|
||||
v14 ^= v3;
|
||||
v14 = ((v14 >> 16) | (v14 << (64 - 16)));
|
||||
v9 = v9 + v14;
|
||||
v4 ^= v9;
|
||||
v4 = ((v4 >> 63) | (v4 << (64 - 63)));
|
||||
}
|
||||
|
||||
h[0] ^= v0 ^ v8;
|
||||
h[1] ^= v1 ^ v9;
|
||||
h[2] ^= v2 ^ v10;
|
||||
h[3] ^= v3 ^ v11;
|
||||
h[4] ^= v4 ^ v12;
|
||||
h[5] ^= v5 ^ v13;
|
||||
h[6] ^= v6 ^ v14;
|
||||
h[7] ^= v7 ^ v15;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
88
csharp/Blake2Sharp/Blake2BCore-Simple.cs
Normal file
88
csharp/Blake2Sharp/Blake2BCore-Simple.cs
Normal file
@ -0,0 +1,88 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
#if false
|
||||
public sealed partial class Blake2BCore
|
||||
{
|
||||
private ulong[] _v = new ulong[16];
|
||||
|
||||
private static ulong RotateRight(ulong value, int nBits)
|
||||
{
|
||||
return (value >> nBits) | (value << (64 - nBits));
|
||||
}
|
||||
|
||||
private void G(int a, int b, int c, int d, int r, int i)
|
||||
{
|
||||
int p = (r << 4) + i;
|
||||
int p0 = Sigma[p];
|
||||
int p1 = Sigma[p + 1];
|
||||
var v = _v;
|
||||
var m = _m;
|
||||
|
||||
v[a] += v[b] + m[p0];
|
||||
v[d] = RotateRight(v[d] ^ v[a], 32);
|
||||
v[c] += v[d];
|
||||
v[b] = RotateRight(v[b] ^ v[c], 24);
|
||||
v[a] += v[b] + m[p1];
|
||||
v[d] = RotateRight(v[d] ^ v[a], 16);
|
||||
v[c] += v[d];
|
||||
v[b] = RotateRight(v[b] ^ v[c], 63);
|
||||
}
|
||||
|
||||
partial void Compress(byte[] block, int start)
|
||||
{
|
||||
var v = _v;
|
||||
var h = _h;
|
||||
var m = _m;
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
m[i] = BytesToUInt64(block, start + (i << 3));
|
||||
|
||||
v[0] = h[0];
|
||||
v[1] = h[1];
|
||||
v[2] = h[2];
|
||||
v[3] = h[3];
|
||||
v[4] = h[4];
|
||||
v[5] = h[5];
|
||||
v[6] = h[6];
|
||||
v[7] = h[7];
|
||||
|
||||
v[8] = IV0;
|
||||
v[9] = IV1;
|
||||
v[10] = IV2;
|
||||
v[11] = IV3;
|
||||
v[12] = IV4 ^ _counter0;
|
||||
v[13] = IV5 ^ _counter1;
|
||||
v[14] = IV6 ^ _finaliziationFlag0;
|
||||
v[15] = IV7 ^ _finaliziationFlag1;
|
||||
|
||||
for (int r = 0; r < NumberOfRounds; ++r)
|
||||
{
|
||||
G(0, 4, 8, 12, r, 0);
|
||||
G(1, 5, 9, 13, r, 2);
|
||||
G(2, 6, 10, 14, r, 4);
|
||||
G(3, 7, 11, 15, r, 6);
|
||||
G(3, 4, 9, 14, r, 14);
|
||||
G(2, 7, 8, 13, r, 12);
|
||||
G(0, 5, 10, 15, r, 8);
|
||||
G(1, 6, 11, 12, r, 10);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
h[i] ^= v[i] ^ v[i + 8];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
198
csharp/Blake2Sharp/Blake2BCore.cs
Normal file
198
csharp/Blake2Sharp/Blake2BCore.cs
Normal file
@ -0,0 +1,198 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
//
|
||||
/*
|
||||
Based on BlakeSharp
|
||||
by Dominik Reichl <dominik.reichl@t-online.de>
|
||||
Web: http://www.dominik-reichl.de/
|
||||
If you're using this class, it would be nice if you'd mention
|
||||
me somewhere in the documentation of your program, but it's
|
||||
not required.
|
||||
|
||||
BLAKE was designed by Jean-Philippe Aumasson, Luca Henzen,
|
||||
Willi Meier and Raphael C.-W. Phan.
|
||||
BlakeSharp was derived from the reference C implementation.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
public sealed partial class Blake2BCore
|
||||
{
|
||||
private bool _isInitialized = false;
|
||||
|
||||
private int _bufferFilled;
|
||||
private byte[] _buf = new byte[128];
|
||||
|
||||
private ulong[] _m = new ulong[16];
|
||||
private ulong[] _h = new ulong[8];
|
||||
private ulong _counter0;
|
||||
private ulong _counter1;
|
||||
private ulong _finalizationFlag0;
|
||||
private ulong _finalizationFlag1;
|
||||
|
||||
private const int NumberOfRounds = 12;
|
||||
private const int BlockSizeInBytes = 128;
|
||||
|
||||
const ulong IV0 = 0x6A09E667F3BCC908UL;
|
||||
const ulong IV1 = 0xBB67AE8584CAA73BUL;
|
||||
const ulong IV2 = 0x3C6EF372FE94F82BUL;
|
||||
const ulong IV3 = 0xA54FF53A5F1D36F1UL;
|
||||
const ulong IV4 = 0x510E527FADE682D1UL;
|
||||
const ulong IV5 = 0x9B05688C2B3E6C1FUL;
|
||||
const ulong IV6 = 0x1F83D9ABFB41BD6BUL;
|
||||
const ulong IV7 = 0x5BE0CD19137E2179UL;
|
||||
|
||||
private static readonly int[] Sigma = new int[NumberOfRounds * 16] {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
|
||||
11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
|
||||
7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
|
||||
9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
|
||||
2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
|
||||
12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
|
||||
13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
|
||||
6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
|
||||
10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3
|
||||
};
|
||||
|
||||
internal static ulong BytesToUInt64(byte[] buf, int offset)
|
||||
{
|
||||
return
|
||||
((ulong)buf[offset + 7] << 7 * 8 |
|
||||
((ulong)buf[offset + 6] << 6 * 8) |
|
||||
((ulong)buf[offset + 5] << 5 * 8) |
|
||||
((ulong)buf[offset + 4] << 4 * 8) |
|
||||
((ulong)buf[offset + 3] << 3 * 8) |
|
||||
((ulong)buf[offset + 2] << 2 * 8) |
|
||||
((ulong)buf[offset + 1] << 1 * 8) |
|
||||
((ulong)buf[offset]));
|
||||
}
|
||||
|
||||
private static void UInt64ToBytes(ulong value, byte[] buf, int offset)
|
||||
{
|
||||
buf[offset + 7] = (byte)(value >> 7 * 8);
|
||||
buf[offset + 6] = (byte)(value >> 6 * 8);
|
||||
buf[offset + 5] = (byte)(value >> 5 * 8);
|
||||
buf[offset + 4] = (byte)(value >> 4 * 8);
|
||||
buf[offset + 3] = (byte)(value >> 3 * 8);
|
||||
buf[offset + 2] = (byte)(value >> 2 * 8);
|
||||
buf[offset + 1] = (byte)(value >> 1 * 8);
|
||||
buf[offset] = (byte)value;
|
||||
}
|
||||
|
||||
partial void Compress(byte[] block, int start);
|
||||
|
||||
public void Initialize(ulong[] config)
|
||||
{
|
||||
if (config == null)
|
||||
throw new ArgumentNullException("config");
|
||||
if (config.Length != 8)
|
||||
throw new ArgumentException("config length must be 8 words");
|
||||
_isInitialized = true;
|
||||
|
||||
_h[0] = IV0;
|
||||
_h[1] = IV1;
|
||||
_h[2] = IV2;
|
||||
_h[3] = IV3;
|
||||
_h[4] = IV4;
|
||||
_h[5] = IV5;
|
||||
_h[6] = IV6;
|
||||
_h[7] = IV7;
|
||||
|
||||
_counter0 = 0;
|
||||
_counter1 = 0;
|
||||
_finalizationFlag0 = 0;
|
||||
_finalizationFlag1 = 0;
|
||||
|
||||
_bufferFilled = 0;
|
||||
|
||||
Array.Clear(_buf, 0, _buf.Length);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
_h[i] ^= config[i];
|
||||
}
|
||||
|
||||
public void HashCore(byte[] array, int start, int count)
|
||||
{
|
||||
if (!_isInitialized)
|
||||
throw new InvalidOperationException("Not initialized");
|
||||
if (array == null)
|
||||
throw new ArgumentNullException("array");
|
||||
if (start < 0)
|
||||
throw new ArgumentOutOfRangeException("start");
|
||||
if (count < 0)
|
||||
throw new ArgumentOutOfRangeException("count");
|
||||
if ((long)start + (long)count > array.Length)
|
||||
throw new ArgumentOutOfRangeException("start+count");
|
||||
int offset = start;
|
||||
int bufferRemaining = BlockSizeInBytes - _bufferFilled;
|
||||
|
||||
if ((_bufferFilled > 0) && (count > bufferRemaining))
|
||||
{
|
||||
Array.Copy(array, offset, _buf, _bufferFilled, bufferRemaining);
|
||||
_counter0 += BlockSizeInBytes;
|
||||
if (_counter0 == 0)
|
||||
_counter1++;
|
||||
Compress(_buf, 0);
|
||||
offset += bufferRemaining;
|
||||
count -= bufferRemaining;
|
||||
_bufferFilled = 0;
|
||||
}
|
||||
|
||||
while (count > BlockSizeInBytes)
|
||||
{
|
||||
_counter0 += BlockSizeInBytes;
|
||||
if (_counter0 == 0)
|
||||
_counter1++;
|
||||
Compress(array, offset);
|
||||
offset += BlockSizeInBytes;
|
||||
count -= BlockSizeInBytes;
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
Array.Copy(array, offset, _buf, _bufferFilled, count);
|
||||
_bufferFilled += count;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] HashFinal()
|
||||
{
|
||||
return HashFinal(false);
|
||||
}
|
||||
|
||||
public byte[] HashFinal(bool isEndOfLayer)
|
||||
{
|
||||
if (!_isInitialized)
|
||||
throw new InvalidOperationException("Not initialized");
|
||||
_isInitialized = false;
|
||||
|
||||
//Last compression
|
||||
_counter0 += (uint)_bufferFilled;
|
||||
_finalizationFlag0 = ulong.MaxValue;
|
||||
if (isEndOfLayer)
|
||||
_finalizationFlag1 = ulong.MaxValue;
|
||||
for (int i = _bufferFilled; i < _buf.Length; i++)
|
||||
_buf[i] = 0;
|
||||
Compress(_buf, 0);
|
||||
|
||||
//Output
|
||||
byte[] hash = new byte[64];
|
||||
for (int i = 0; i < 8; ++i)
|
||||
UInt64ToBytes(_h[i], hash, i << 3);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
66
csharp/Blake2Sharp/Blake2BHasher.cs
Normal file
66
csharp/Blake2Sharp/Blake2BHasher.cs
Normal file
@ -0,0 +1,66 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
internal class Blake2BHasher : Hasher
|
||||
{
|
||||
private readonly Blake2BCore core = new Blake2BCore();
|
||||
private readonly ulong[] rawConfig;
|
||||
private readonly byte[] key;
|
||||
private readonly int outputSizeInBytes;
|
||||
private static readonly Blake2BConfig DefaultConfig = new Blake2BConfig();
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
core.Initialize(rawConfig);
|
||||
if (key != null)
|
||||
{
|
||||
core.HashCore(key, 0, key.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public override byte[] Finish()
|
||||
{
|
||||
var fullResult = core.HashFinal();
|
||||
if (outputSizeInBytes != fullResult.Length)
|
||||
{
|
||||
var result = new byte[outputSizeInBytes];
|
||||
Array.Copy(fullResult, result, result.Length);
|
||||
return result;
|
||||
}
|
||||
else return fullResult;
|
||||
}
|
||||
|
||||
public Blake2BHasher(Blake2BConfig config)
|
||||
{
|
||||
if (config == null)
|
||||
config = DefaultConfig;
|
||||
rawConfig = Blake2IvBuilder.ConfigB(config, null);
|
||||
if (config.Key != null && config.Key.Length != 0)
|
||||
{
|
||||
key = new byte[128];
|
||||
Array.Copy(config.Key, key, config.Key.Length);
|
||||
}
|
||||
outputSizeInBytes = config.OutputSizeInBytes;
|
||||
Init();
|
||||
}
|
||||
|
||||
public override void Update(byte[] data, int start, int count)
|
||||
{
|
||||
core.HashCore(data, start, count);
|
||||
}
|
||||
}
|
||||
}
|
52
csharp/Blake2Sharp/Blake2BNodeHasher.cs
Normal file
52
csharp/Blake2Sharp/Blake2BNodeHasher.cs
Normal file
@ -0,0 +1,52 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
/*public class Blake2BNodeHasher : NodeHasher
|
||||
{
|
||||
ulong[] rawConfig;
|
||||
byte[] key;
|
||||
Blake2BCore core = new Blake2BCore();
|
||||
|
||||
public override void Init(int depth, long nodeOffset)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override byte[] Finish(bool isEndOfLayer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Update(byte[] data, int start, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Blake2BNodeHasher(Blake2BConfig config, Blake2BTreeConfig treeConfig)
|
||||
{
|
||||
if (config == null)
|
||||
config = DefaultConfig;
|
||||
rawConfig = Blake2IvBuilder.ConfigB(config, null);
|
||||
if (config.Key != null && config.Key.Length != 0)
|
||||
{
|
||||
key = new byte[128];
|
||||
Array.Copy(config.Key, key, config.Key.Length);
|
||||
}
|
||||
Init(0, 0);
|
||||
}
|
||||
}*/
|
||||
}
|
52
csharp/Blake2Sharp/Blake2BTreeConfig.cs
Normal file
52
csharp/Blake2Sharp/Blake2BTreeConfig.cs
Normal file
@ -0,0 +1,52 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
public sealed class Blake2BTreeConfig : ICloneable
|
||||
{
|
||||
public int IntermediateHashSize { get; set; }
|
||||
public int MaxHeight { get; set; }
|
||||
public long LeafSize { get; set; }
|
||||
public int FanOut { get; set; }
|
||||
|
||||
public Blake2BTreeConfig()
|
||||
{
|
||||
IntermediateHashSize = 64;
|
||||
}
|
||||
|
||||
public Blake2BTreeConfig Clone()
|
||||
{
|
||||
var result = new Blake2BTreeConfig();
|
||||
result.IntermediateHashSize = IntermediateHashSize;
|
||||
result.MaxHeight = MaxHeight;
|
||||
result.LeafSize = LeafSize;
|
||||
result.FanOut = FanOut;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Blake2BTreeConfig CreateInterleaved(int parallelism)
|
||||
{
|
||||
var result = new Blake2BTreeConfig();
|
||||
result.FanOut = parallelism;
|
||||
result.MaxHeight = 2;
|
||||
result.IntermediateHashSize = 64;
|
||||
return result;
|
||||
}
|
||||
|
||||
object ICloneable.Clone()
|
||||
{
|
||||
return Clone();
|
||||
}
|
||||
}
|
||||
}
|
76
csharp/Blake2Sharp/Blake2IvBuilder.cs
Normal file
76
csharp/Blake2Sharp/Blake2IvBuilder.cs
Normal file
@ -0,0 +1,76 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
internal static class Blake2IvBuilder
|
||||
{
|
||||
private static readonly Blake2BTreeConfig SequentialTreeConfig = new Blake2BTreeConfig() { IntermediateHashSize = 0, LeafSize = 0, FanOut = 1, MaxHeight = 1 };
|
||||
|
||||
public static ulong[] ConfigB(Blake2BConfig config, Blake2BTreeConfig treeConfig)
|
||||
{
|
||||
bool isSequential = treeConfig == null;
|
||||
if (isSequential)
|
||||
treeConfig = SequentialTreeConfig;
|
||||
var rawConfig = new ulong[8];
|
||||
var result = new ulong[8];
|
||||
|
||||
//digest length
|
||||
if (config.OutputSizeInBytes <= 0 | config.OutputSizeInBytes > 64)
|
||||
throw new ArgumentOutOfRangeException("config.OutputSize");
|
||||
rawConfig[0] |= (ulong)(uint)config.OutputSizeInBytes;
|
||||
|
||||
//Key length
|
||||
if (config.Key != null)
|
||||
{
|
||||
if (config.Key.Length > 64)
|
||||
throw new ArgumentException("config.Key", "Key too long");
|
||||
rawConfig[0] |= (ulong)((uint)config.Key.Length << 8);
|
||||
}
|
||||
// FanOut
|
||||
rawConfig[0] |= (uint)treeConfig.FanOut << 16;
|
||||
// Depth
|
||||
rawConfig[0] |= (uint)treeConfig.MaxHeight << 24;
|
||||
// Leaf length
|
||||
rawConfig[0] |= ((ulong)(uint)treeConfig.LeafSize) << 32;
|
||||
// Inner length
|
||||
if (!isSequential && (treeConfig.IntermediateHashSize <= 0 || treeConfig.IntermediateHashSize > 64))
|
||||
throw new ArgumentOutOfRangeException("treeConfig.TreeIntermediateHashSize");
|
||||
rawConfig[2] |= (uint)treeConfig.IntermediateHashSize << 8;
|
||||
// Salt
|
||||
if (config.Salt != null)
|
||||
{
|
||||
if (config.Salt.Length != 16)
|
||||
throw new ArgumentException("config.Salt has invalid length");
|
||||
rawConfig[4] = Blake2BCore.BytesToUInt64(config.Salt, 0);
|
||||
rawConfig[5] = Blake2BCore.BytesToUInt64(config.Salt, 8);
|
||||
}
|
||||
// Personalization
|
||||
if (config.Personalization != null)
|
||||
{
|
||||
if (config.Personalization.Length != 16)
|
||||
throw new ArgumentException("config.Personalization has invalid length");
|
||||
rawConfig[6] = Blake2BCore.BytesToUInt64(config.Personalization, 0);
|
||||
rawConfig[6] = Blake2BCore.BytesToUInt64(config.Personalization, 8);
|
||||
}
|
||||
|
||||
return rawConfig;
|
||||
}
|
||||
|
||||
public static void ConfigBSetNode(ulong[] rawConfig, byte depth, ulong nodeOffset)
|
||||
{
|
||||
rawConfig[1] = nodeOffset;
|
||||
rawConfig[2] = (rawConfig[2] & ~0xFFul) | depth;
|
||||
}
|
||||
}
|
||||
}
|
60
csharp/Blake2Sharp/Blake2Sharp.csproj
Normal file
60
csharp/Blake2Sharp/Blake2Sharp.csproj
Normal file
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{E21AB364-9130-4F14-ABE1-18FA0C089130}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Blake2Sharp</RootNamespace>
|
||||
<AssemblyName>Blake2Sharp</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Blake2B.cs" />
|
||||
<Compile Include="Blake2BCore.cs" />
|
||||
<Compile Include="Blake2BNodeHasher.cs" />
|
||||
<Compile Include="Blake2BConfig.cs" />
|
||||
<Compile Include="Blake2BCore-FullyUnrolled.cs" />
|
||||
<Compile Include="Blake2IvBuilder.cs" />
|
||||
<Compile Include="Blake2BTreeConfig.cs" />
|
||||
<Compile Include="Blake2BCore-Simple.cs" />
|
||||
<Compile Include="Blake2BCore-Inline.cs" />
|
||||
<Compile Include="Blake2BHasher.cs" />
|
||||
<Compile Include="NodeHasher.cs" />
|
||||
<Compile Include="Hasher.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TreeHasher.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
60
csharp/Blake2Sharp/Hasher.cs
Normal file
60
csharp/Blake2Sharp/Hasher.cs
Normal file
@ -0,0 +1,60 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
public abstract class Hasher
|
||||
{
|
||||
public abstract void Init();
|
||||
public abstract byte[] Finish();
|
||||
public abstract void Update(byte[] data, int start, int count);
|
||||
|
||||
public void Update(byte[] data)
|
||||
{
|
||||
Update(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public HashAlgorithm AsHashAlgorithm()
|
||||
{
|
||||
return new HashAlgorithmAdapter(this);
|
||||
}
|
||||
|
||||
internal class HashAlgorithmAdapter : HashAlgorithm
|
||||
{
|
||||
private readonly Hasher _hasher;
|
||||
|
||||
protected override void HashCore(byte[] array, int ibStart, int cbSize)
|
||||
{
|
||||
_hasher.Update(array, ibStart, cbSize);
|
||||
}
|
||||
|
||||
protected override byte[] HashFinal()
|
||||
{
|
||||
return _hasher.Finish();
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
_hasher.Init();
|
||||
}
|
||||
|
||||
public HashAlgorithmAdapter(Hasher hasher)
|
||||
{
|
||||
_hasher = hasher;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
csharp/Blake2Sharp/NodeHasher.cs
Normal file
30
csharp/Blake2Sharp/NodeHasher.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
public abstract class NodeHasher
|
||||
{
|
||||
public abstract void Init(int depth, long nodeOffset);
|
||||
public abstract byte[] Finish(bool isEndOfLayer);
|
||||
public abstract void Update(byte[] data, int start, int count);
|
||||
|
||||
public void Update(byte[] data)
|
||||
{
|
||||
Update(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
}
|
36
csharp/Blake2Sharp/Properties/AssemblyInfo.cs
Normal file
36
csharp/Blake2Sharp/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Blake2Sharp")]
|
||||
[assembly: AssemblyDescription("Blake2 Hashfunction")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("CodesInChaos")]
|
||||
[assembly: AssemblyProduct("Blake2Sharp")]
|
||||
[assembly: AssemblyCopyright("Public Domain")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("b7361e6c-1a16-4653-9afb-134066503c8f")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
77
csharp/Blake2Sharp/TreeHasher.cs
Normal file
77
csharp/Blake2Sharp/TreeHasher.cs
Normal file
@ -0,0 +1,77 @@
|
||||
// BLAKE2 reference source code package - C# implementation
|
||||
|
||||
// Written in 2012 by Christian Winnerlein <codesinchaos@gmail.com>
|
||||
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
// this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Blake2Sharp
|
||||
{
|
||||
/*public class TreeHasher : Hasher
|
||||
{
|
||||
NodeHasher nodeHasher;
|
||||
int maxDepth;
|
||||
int maxLeafSize;
|
||||
int currentLeafSize;
|
||||
int fanOut;
|
||||
List<byte[]>[] intermediateHashes;
|
||||
long[] counts;
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
intermediateHashes = new List<byte[]>[maxDepth];
|
||||
counts = new long[maxDepth];
|
||||
}
|
||||
|
||||
public override byte[] Finish()
|
||||
{
|
||||
for (int layer = 0; layer < intermediateHashes.Length; layer++)
|
||||
{
|
||||
if (intermediateHashes[layer].Count > 0)
|
||||
{
|
||||
nodeHasher.Init(layer, counts[layer]);
|
||||
foreach (var hash in intermediateHashes[layer])
|
||||
nodeHasher.Update(hash);
|
||||
}
|
||||
}
|
||||
intermediateHashes = null;
|
||||
}
|
||||
|
||||
public override void Update(byte[] data, int start, int count)
|
||||
{
|
||||
while (count > 0)
|
||||
{
|
||||
int toHash = Math.Min(maxLeafSize - currentLeafSize, count);
|
||||
nodeHasher.Update(data, start, toHash);
|
||||
start += toHash;
|
||||
count -= toHash;
|
||||
if (count > 0)
|
||||
{
|
||||
intermediateHashes[0].Add(nodeHasher.Finish(false));
|
||||
for (int layer = 0; layer < intermediateHashes.Length; layer++)
|
||||
{
|
||||
if ((layer + 1 < maxDepth) && (intermediateHashes[layer].Count == fanOut))
|
||||
{
|
||||
nodeHasher.Init(layer, counts[layer]);
|
||||
foreach (var hash in intermediateHashes[layer])
|
||||
nodeHasher.Update(hash);
|
||||
intermediateHashes[layer + 1].Add(nodeHasher.Finish);
|
||||
intermediateHashes[layer].Clear();
|
||||
counts[layer + 1]++;
|
||||
}
|
||||
}
|
||||
counts[0]++;
|
||||
nodeHasher.Init(0, counts[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
26
csharp/Blake2Sharp/compression.c
Normal file
26
csharp/Blake2Sharp/compression.c
Normal file
@ -0,0 +1,26 @@
|
||||
#define ROT(x, y)\
|
||||
((x >> y)|(x << (64-y)))
|
||||
|
||||
#define G(r,i,a,b,c,d) \
|
||||
YY G(r,i,a,b,c,d) XXX\
|
||||
a = a + b + m[Sigma[16*r+2*i+0]]; XXX\
|
||||
d ^= a; XXX\
|
||||
d = ROT(d, 32); XXX\
|
||||
c = c + d; XXX\
|
||||
b ^= c; XXX\
|
||||
b = ROT(b, 24); XXX\
|
||||
a = a + b + m[Sigma[16*r+2*i+1]]; XXX\
|
||||
d ^= a; XXX\
|
||||
d = ROT(d, 16); XXX\
|
||||
c = c + d; XXX\
|
||||
b ^= c; XXX\
|
||||
b = ROT(b, 63); XXX
|
||||
|
||||
G( r, 0, v0, v4, v8, v12 )
|
||||
G( r, 1, v1, v5, v9, v13 )
|
||||
G( r, 2, v2, v6, v10, v14 )
|
||||
G( r, 3, v3, v7, v11, v15 )
|
||||
G( r, 4, v0, v5, v10, v15 )
|
||||
G( r, 5, v1, v6, v11, v12 )
|
||||
G( r, 6, v2, v7, v8, v13 )
|
||||
G( r, 7, v3, v4, v9, v14 )
|
133
ref/blake2-impl.h
Normal file
133
ref/blake2-impl.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2_IMPL_H__
|
||||
#define __BLAKE2_IMPL_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static inline uint32_t load32( const void *src )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
return *( uint32_t * )( src );
|
||||
#else
|
||||
const uint8_t *p = ( uint8_t * )src;
|
||||
uint32_t w = *p++;
|
||||
w |= ( uint32_t )( *p++ ) << 8;
|
||||
w |= ( uint32_t )( *p++ ) << 16;
|
||||
w |= ( uint32_t )( *p++ ) << 24;
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t load64( const void *src )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
return *( uint64_t * )( src );
|
||||
#else
|
||||
const uint8_t *p = ( uint8_t * )src;
|
||||
uint64_t w = *p++;
|
||||
w |= ( uint64_t )( *p++ ) << 8;
|
||||
w |= ( uint64_t )( *p++ ) << 16;
|
||||
w |= ( uint64_t )( *p++ ) << 24;
|
||||
w |= ( uint64_t )( *p++ ) << 32;
|
||||
w |= ( uint64_t )( *p++ ) << 40;
|
||||
w |= ( uint64_t )( *p++ ) << 48;
|
||||
w |= ( uint64_t )( *p++ ) << 56;
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void store32( void *dst, uint32_t w )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
*( uint32_t * )( dst ) = w;
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void store64( void *dst, uint64_t w )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
*( uint64_t * )( dst ) = w;
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t load48( const void *src )
|
||||
{
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
uint64_t w = *p++;
|
||||
w |= ( uint64_t )( *p++ ) << 8;
|
||||
w |= ( uint64_t )( *p++ ) << 16;
|
||||
w |= ( uint64_t )( *p++ ) << 24;
|
||||
w |= ( uint64_t )( *p++ ) << 32;
|
||||
w |= ( uint64_t )( *p++ ) << 40;
|
||||
return w;
|
||||
}
|
||||
|
||||
static inline void store48( void *dst, uint64_t w )
|
||||
{
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
}
|
||||
|
||||
static inline uint32_t rotl32( const uint32_t w, const unsigned c )
|
||||
{
|
||||
return ( w << c ) | ( w >> ( 32 - c ) );
|
||||
}
|
||||
|
||||
static inline uint64_t rotl64( const uint64_t w, const unsigned c )
|
||||
{
|
||||
return ( w << c ) | ( w >> ( 64 - c ) );
|
||||
}
|
||||
|
||||
static inline uint32_t rotr32( const uint32_t w, const unsigned c )
|
||||
{
|
||||
return ( w >> c ) | ( w << ( 32 - c ) );
|
||||
}
|
||||
|
||||
static inline uint64_t rotr64( const uint64_t w, const unsigned c )
|
||||
{
|
||||
return ( w >> c ) | ( w << ( 64 - c ) );
|
||||
}
|
||||
|
||||
/* prevents compiler optimizing out memset() */
|
||||
static inline void secure_zero_memory( void *v, size_t n )
|
||||
{
|
||||
volatile uint8_t *p = ( volatile uint8_t * )v;
|
||||
|
||||
while( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
16467
ref/blake2-kat.h
Normal file
16467
ref/blake2-kat.h
Normal file
File diff suppressed because it is too large
Load Diff
156
ref/blake2.h
Normal file
156
ref/blake2.h
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2_H__
|
||||
#define __BLAKE2_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define ALIGN(x) __declspec(align(x))
|
||||
#else
|
||||
#define ALIGN(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum blake2s_constant
|
||||
{
|
||||
BLAKE2S_BLOCKBYTES = 64,
|
||||
BLAKE2S_OUTBYTES = 32,
|
||||
BLAKE2S_KEYBYTES = 32,
|
||||
BLAKE2S_SALTBYTES = 8,
|
||||
BLAKE2S_PERSONALBYTES = 8
|
||||
};
|
||||
|
||||
enum blake2b_constant
|
||||
{
|
||||
BLAKE2B_BLOCKBYTES = 128,
|
||||
BLAKE2B_OUTBYTES = 64,
|
||||
BLAKE2B_KEYBYTES = 64,
|
||||
BLAKE2B_SALTBYTES = 16,
|
||||
BLAKE2B_PERSONALBYTES = 16
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct __blake2s_param
|
||||
{
|
||||
uint8_t digest_length; // 1
|
||||
uint8_t key_length; // 2
|
||||
uint8_t fanout; // 3
|
||||
uint8_t depth; // 4
|
||||
uint32_t leaf_length; // 8
|
||||
uint8_t node_offset[6];// 14
|
||||
uint8_t node_depth; // 15
|
||||
uint8_t inner_length; // 16
|
||||
// uint8_t reserved[0];
|
||||
uint8_t salt[BLAKE2S_SALTBYTES]; // 24
|
||||
uint8_t personal[BLAKE2S_PERSONALBYTES]; // 32
|
||||
} blake2s_param;
|
||||
|
||||
ALIGN( 64 ) typedef struct __blake2s_state
|
||||
{
|
||||
uint32_t h[8];
|
||||
uint32_t t[2];
|
||||
uint32_t f[2];
|
||||
uint8_t buf[2 * BLAKE2S_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
uint8_t last_node;
|
||||
} blake2s_state ;
|
||||
|
||||
typedef struct __blake2b_param
|
||||
{
|
||||
uint8_t digest_length; // 1
|
||||
uint8_t key_length; // 2
|
||||
uint8_t fanout; // 3
|
||||
uint8_t depth; // 4
|
||||
uint32_t leaf_length; // 8
|
||||
uint64_t node_offset; // 16
|
||||
uint8_t node_depth; // 17
|
||||
uint8_t inner_length; // 18
|
||||
uint8_t reserved[14]; // 32
|
||||
uint8_t salt[BLAKE2B_SALTBYTES]; // 48
|
||||
uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64
|
||||
} blake2b_param;
|
||||
|
||||
ALIGN( 64 ) typedef struct __blake2b_state
|
||||
{
|
||||
uint64_t h[8];
|
||||
uint64_t t[2];
|
||||
uint64_t f[2];
|
||||
uint8_t buf[2 * BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
uint8_t last_node;
|
||||
} blake2b_state;
|
||||
|
||||
typedef struct __blake2sp_state
|
||||
{
|
||||
blake2s_state S[8][1];
|
||||
blake2s_state R[1];
|
||||
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
} blake2sp_state;
|
||||
|
||||
typedef struct __blake2bp_state
|
||||
{
|
||||
blake2b_state S[4][1];
|
||||
blake2b_state R[1];
|
||||
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
} blake2bp_state;
|
||||
#pragma pack(pop)
|
||||
|
||||
// Streaming API
|
||||
int blake2s_init( blake2s_state *S, const uint8_t outlen );
|
||||
int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
||||
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
|
||||
int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen );
|
||||
int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen );
|
||||
|
||||
int blake2b_init( blake2b_state *S, const uint8_t outlen );
|
||||
int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
||||
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
|
||||
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen );
|
||||
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen );
|
||||
|
||||
int blake2sp_init( blake2sp_state *S, const uint8_t outlen );
|
||||
int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
||||
int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen );
|
||||
int blake2sp_final( blake2sp_state *S, uint8_t *out, uint8_t outlen );
|
||||
|
||||
int blake2bp_init( blake2bp_state *S, const uint8_t outlen );
|
||||
int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
||||
int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen );
|
||||
int blake2bp_final( blake2bp_state *S, uint8_t *out, uint8_t outlen );
|
||||
|
||||
// Simple API
|
||||
int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
||||
int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
||||
|
||||
int blake2sp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
||||
int blake2bp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
||||
|
||||
static inline int blake2( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
return blake2b( out, in, key, outlen, inlen, keylen );
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
391
ref/blake2b-ref.c
Normal file
391
ref/blake2b-ref.c
Normal file
@ -0,0 +1,391 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "blake2.h"
|
||||
#include "blake2-impl.h"
|
||||
|
||||
static const uint64_t blake2b_IV[8] =
|
||||
{
|
||||
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
|
||||
0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
|
||||
0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
|
||||
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
|
||||
};
|
||||
|
||||
static const uint8_t blake2b_sigma[12][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
|
||||
};
|
||||
|
||||
|
||||
static inline int blake2b_set_lastnode( blake2b_state *S )
|
||||
{
|
||||
S->f[1] = ~0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_clear_lastnode( blake2b_state *S )
|
||||
{
|
||||
S->f[1] = 0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Some helper functions, not necessarily useful */
|
||||
static inline int blake2b_set_lastblock( blake2b_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2b_set_lastnode( S );
|
||||
|
||||
S->f[0] = ~0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_clear_lastblock( blake2b_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2b_clear_lastnode( S );
|
||||
|
||||
S->f[0] = 0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
|
||||
{
|
||||
S->t[0] += inc;
|
||||
S->t[1] += ( S->t[0] < inc );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Parameter-related functions
|
||||
static inline int blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length )
|
||||
{
|
||||
P->digest_length = digest_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )
|
||||
{
|
||||
P->fanout = fanout;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )
|
||||
{
|
||||
P->depth = depth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )
|
||||
{
|
||||
store32( &P->leaf_length, leaf_length );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )
|
||||
{
|
||||
store64( &P->node_offset, node_offset );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )
|
||||
{
|
||||
P->node_depth = node_depth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )
|
||||
{
|
||||
P->inner_length = inner_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )
|
||||
{
|
||||
memcpy( P->salt, salt, BLAKE2B_SALTBYTES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )
|
||||
{
|
||||
memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_init0( blake2b_state *S )
|
||||
{
|
||||
memset( S, 0, sizeof( blake2b_state ) );
|
||||
|
||||
for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* init xors IV with input parameter block */
|
||||
int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
|
||||
{
|
||||
blake2b_init0( S );
|
||||
uint8_t *p = ( uint8_t * )( P );
|
||||
|
||||
/* IV XOR ParamBlock */
|
||||
for( size_t i = 0; i < 8; ++i )
|
||||
S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int blake2b_init( blake2b_state *S, const uint8_t outlen )
|
||||
{
|
||||
blake2b_param P[1];
|
||||
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
|
||||
|
||||
P->digest_length = outlen;
|
||||
P->key_length = 0;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store64( &P->node_offset, 0 );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
memset( P->reserved, 0, sizeof( P->reserved ) );
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2b_init_param( S, P );
|
||||
}
|
||||
|
||||
|
||||
int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
|
||||
{
|
||||
blake2b_param P[1];
|
||||
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
|
||||
|
||||
if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
|
||||
|
||||
P->digest_length = outlen;
|
||||
P->key_length = keylen;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store64( &P->node_offset, 0 );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
memset( P->reserved, 0, sizeof( P->reserved ) );
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
|
||||
if( blake2b_init_param( S, P ) < 0 ) return -1;
|
||||
|
||||
{
|
||||
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2B_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
|
||||
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
|
||||
{
|
||||
uint64_t m[16];
|
||||
uint64_t v[16];
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 16; ++i )
|
||||
m[i] = load64( block + i * sizeof( m[i] ) );
|
||||
|
||||
for( i = 0; i < 8; ++i )
|
||||
v[i] = S->h[i];
|
||||
|
||||
v[ 8] = blake2b_IV[0];
|
||||
v[ 9] = blake2b_IV[1];
|
||||
v[10] = blake2b_IV[2];
|
||||
v[11] = blake2b_IV[3];
|
||||
v[12] = S->t[0] ^ blake2b_IV[4];
|
||||
v[13] = S->t[1] ^ blake2b_IV[5];
|
||||
v[14] = S->f[0] ^ blake2b_IV[6];
|
||||
v[15] = S->f[1] ^ blake2b_IV[7];
|
||||
#define G(r,i,a,b,c,d) \
|
||||
do { \
|
||||
a = a + b + m[blake2b_sigma[r][2*i+0]]; \
|
||||
d = rotr64(d ^ a, 32); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 24); \
|
||||
a = a + b + m[blake2b_sigma[r][2*i+1]]; \
|
||||
d = rotr64(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 63); \
|
||||
} while(0)
|
||||
#define ROUND(r) \
|
||||
do { \
|
||||
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
|
||||
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
|
||||
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
|
||||
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
|
||||
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
|
||||
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
|
||||
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
|
||||
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
|
||||
} while(0)
|
||||
ROUND( 0 );
|
||||
ROUND( 1 );
|
||||
ROUND( 2 );
|
||||
ROUND( 3 );
|
||||
ROUND( 4 );
|
||||
ROUND( 5 );
|
||||
ROUND( 6 );
|
||||
ROUND( 7 );
|
||||
ROUND( 8 );
|
||||
ROUND( 9 );
|
||||
ROUND( 10 );
|
||||
ROUND( 11 );
|
||||
|
||||
for( i = 0; i < 8; ++i )
|
||||
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||
|
||||
#undef G
|
||||
#undef ROUND
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* inlen now in bytes */
|
||||
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen )
|
||||
{
|
||||
while( inlen > 0 )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
|
||||
|
||||
if( inlen > fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill ); // Fill buffer
|
||||
S->buflen += fill;
|
||||
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
|
||||
blake2b_compress( S, S->buf ); // Compress
|
||||
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left
|
||||
S->buflen -= BLAKE2B_BLOCKBYTES;
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
}
|
||||
else // inlen <= fill
|
||||
{
|
||||
memcpy( S->buf + left, in, inlen );
|
||||
S->buflen += inlen; // Be lazy, do not compress
|
||||
in += inlen;
|
||||
inlen -= inlen;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Is this correct? */
|
||||
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen )
|
||||
{
|
||||
uint8_t buffer[BLAKE2B_OUTBYTES];
|
||||
|
||||
if( S->buflen > BLAKE2B_BLOCKBYTES )
|
||||
{
|
||||
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
|
||||
blake2b_compress( S, S->buf );
|
||||
S->buflen -= BLAKE2B_BLOCKBYTES;
|
||||
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );
|
||||
}
|
||||
|
||||
blake2b_increment_counter( S, S->buflen );
|
||||
blake2b_set_lastblock( S );
|
||||
memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
|
||||
blake2b_compress( S, S->buf );
|
||||
|
||||
for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
|
||||
store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
|
||||
|
||||
memcpy( out, buffer, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* inlen, at least, should be uint64_t. Others can be size_t. */
|
||||
int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
blake2b_state S[1];
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if( NULL == key ) keylen = 0;
|
||||
|
||||
if( keylen > 0 )
|
||||
{
|
||||
if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( blake2b_init( S, outlen ) < 0 ) return -1;
|
||||
}
|
||||
|
||||
blake2b_update( S, ( uint8_t * )in, inlen );
|
||||
blake2b_final( S, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(BLAKE2B_SELFTEST)
|
||||
#include <string.h>
|
||||
#include "blake2-kat.h"
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
uint8_t key[BLAKE2B_KEYBYTES];
|
||||
uint8_t buf[KAT_LENGTH];
|
||||
|
||||
for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i )
|
||||
key[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
buf[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
{
|
||||
uint8_t hash[BLAKE2B_OUTBYTES];
|
||||
blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );
|
||||
|
||||
if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
|
||||
{
|
||||
puts( "error" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
puts( "ok" );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
288
ref/blake2bp-ref.c
Normal file
288
ref/blake2bp-ref.c
Normal file
@ -0,0 +1,288 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
#include "blake2.h"
|
||||
#include "blake2-impl.h"
|
||||
|
||||
#define PARALLELISM_DEGREE 4
|
||||
|
||||
static inline int blake2bp_init_leaf( blake2b_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )
|
||||
{
|
||||
blake2b_param P[1];
|
||||
P->digest_length = outlen;
|
||||
P->key_length = keylen;
|
||||
P->fanout = PARALLELISM_DEGREE;
|
||||
P->depth = 2;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store64( &P->node_offset, offset );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = outlen;
|
||||
memset( P->reserved, 0, sizeof( P->reserved ) );
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2b_init_param( S, P );
|
||||
}
|
||||
|
||||
static inline int blake2bp_init_root( blake2b_state *S, uint8_t outlen, uint8_t keylen )
|
||||
{
|
||||
blake2b_param P[1];
|
||||
P->digest_length = outlen;
|
||||
P->key_length = keylen;
|
||||
P->fanout = PARALLELISM_DEGREE;
|
||||
P->depth = 2;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store64( &P->node_offset, 0 );
|
||||
P->node_depth = 1;
|
||||
P->inner_length = outlen;
|
||||
memset( P->reserved, 0, sizeof( P->reserved ) );
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2b_init_param( S, P );
|
||||
}
|
||||
|
||||
|
||||
int blake2bp_init( blake2bp_state *S, const uint8_t outlen )
|
||||
{
|
||||
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
|
||||
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
|
||||
if( blake2bp_init_root( S->R, outlen, 0 ) < 0 )
|
||||
return -1;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2bp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1;
|
||||
|
||||
S->R->last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
|
||||
{
|
||||
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
|
||||
|
||||
if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
|
||||
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
|
||||
if( blake2bp_init_root( S->R, outlen, keylen ) < 0 )
|
||||
return -1;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2bp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1;
|
||||
|
||||
S->R->last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||
{
|
||||
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2B_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES );
|
||||
|
||||
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = sizeof( S->buf ) - left;
|
||||
|
||||
if( left && inlen >= fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES );
|
||||
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE)
|
||||
#else
|
||||
|
||||
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
|
||||
#endif
|
||||
{
|
||||
#if defined(_OPENMP)
|
||||
size_t id__ = omp_get_thread_num();
|
||||
#endif
|
||||
uint64_t inlen__ = inlen;
|
||||
const uint8_t *in__ = ( const uint8_t * )in;
|
||||
in__ += id__ * BLAKE2B_BLOCKBYTES;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )
|
||||
{
|
||||
blake2b_update( S->S[id__], in__, BLAKE2B_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
|
||||
in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES );
|
||||
inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||
|
||||
if( inlen > 0 )
|
||||
memcpy( S->buf + left, in, inlen );
|
||||
|
||||
S->buflen = left + inlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2bp_final( blake2bp_state *S, uint8_t *out, const uint8_t outlen )
|
||||
{
|
||||
uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
{
|
||||
if( S->buflen > i * BLAKE2B_BLOCKBYTES )
|
||||
{
|
||||
size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES;
|
||||
|
||||
if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES;
|
||||
|
||||
blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left );
|
||||
}
|
||||
|
||||
blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES );
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES );
|
||||
|
||||
blake2b_final( S->R, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2bp( uint8_t *out, const void *in, const void *key, uint8_t outlen, uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];
|
||||
blake2b_state S[PARALLELISM_DEGREE][1];
|
||||
blake2b_state FS[1];
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if ( NULL == key ) keylen = 0;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2bp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1;
|
||||
|
||||
S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node
|
||||
|
||||
if( keylen > 0 )
|
||||
{
|
||||
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2B_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES );
|
||||
|
||||
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)
|
||||
#else
|
||||
|
||||
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
|
||||
#endif
|
||||
{
|
||||
#if defined(_OPENMP)
|
||||
size_t id__ = omp_get_thread_num();
|
||||
#endif
|
||||
uint64_t inlen__ = inlen;
|
||||
const uint8_t *in__ = ( const uint8_t * )in;
|
||||
in__ += id__ * BLAKE2B_BLOCKBYTES;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )
|
||||
{
|
||||
blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||
}
|
||||
|
||||
if( inlen__ > id__ * BLAKE2B_BLOCKBYTES )
|
||||
{
|
||||
const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES;
|
||||
const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES;
|
||||
blake2b_update( S[id__], in__, len );
|
||||
}
|
||||
|
||||
blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES );
|
||||
}
|
||||
|
||||
if( blake2bp_init_root( FS, outlen, keylen ) < 0 )
|
||||
return -1;
|
||||
|
||||
FS->last_node = 1; // Mark as last node
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES );
|
||||
|
||||
blake2b_final( FS, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(BLAKE2BP_SELFTEST)
|
||||
#include <string.h>
|
||||
#include "blake2-kat.h"
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
uint8_t key[BLAKE2B_KEYBYTES];
|
||||
uint8_t buf[KAT_LENGTH];
|
||||
|
||||
for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i )
|
||||
key[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
buf[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
{
|
||||
uint8_t hash[BLAKE2B_OUTBYTES];
|
||||
blake2bp( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );
|
||||
|
||||
if( 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) )
|
||||
{
|
||||
puts( "error" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
puts( "ok" );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
380
ref/blake2s-ref.c
Normal file
380
ref/blake2s-ref.c
Normal file
@ -0,0 +1,380 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "blake2.h"
|
||||
#include "blake2-impl.h"
|
||||
|
||||
static const uint32_t blake2s_IV[8] =
|
||||
{
|
||||
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
|
||||
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
|
||||
};
|
||||
|
||||
static const uint8_t blake2s_sigma[10][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||
};
|
||||
|
||||
static inline int blake2s_set_lastnode( blake2s_state *S )
|
||||
{
|
||||
S->f[1] = ~0U;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_clear_lastnode( blake2s_state *S )
|
||||
{
|
||||
S->f[1] = 0U;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Some helper functions, not necessarily useful */
|
||||
static inline int blake2s_set_lastblock( blake2s_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2s_set_lastnode( S );
|
||||
|
||||
S->f[0] = ~0U;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_clear_lastblock( blake2s_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2s_clear_lastnode( S );
|
||||
|
||||
S->f[0] = 0U;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
|
||||
{
|
||||
S->t[0] += inc;
|
||||
S->t[1] += ( S->t[0] < inc );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parameter-related functions
|
||||
static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
|
||||
{
|
||||
P->digest_length = digest_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
|
||||
{
|
||||
P->fanout = fanout;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
|
||||
{
|
||||
P->depth = depth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
|
||||
{
|
||||
store32( &P->leaf_length, leaf_length );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
|
||||
{
|
||||
store48( P->node_offset, node_offset );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
|
||||
{
|
||||
P->node_depth = node_depth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
|
||||
{
|
||||
P->inner_length = inner_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
|
||||
{
|
||||
memcpy( P->salt, salt, BLAKE2S_SALTBYTES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
|
||||
{
|
||||
memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_init0( blake2s_state *S )
|
||||
{
|
||||
memset( S, 0, sizeof( blake2s_state ) );
|
||||
|
||||
for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* init2 xors IV with input parameter block */
|
||||
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
|
||||
{
|
||||
blake2s_init0( S );
|
||||
uint32_t *p = ( uint32_t * )( P );
|
||||
|
||||
/* IV XOR ParamBlock */
|
||||
for( size_t i = 0; i < 8; ++i )
|
||||
S->h[i] ^= load32( &p[i] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Sequential blake2s initialization
|
||||
int blake2s_init( blake2s_state *S, const uint8_t outlen )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
|
||||
/* Move interval verification here? */
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
||||
|
||||
P->digest_length = outlen;
|
||||
P->key_length = 0;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store48( &P->node_offset, 0 );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
// memset(P->reserved, 0, sizeof(P->reserved) );
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2s_init_param( S, P );
|
||||
}
|
||||
|
||||
int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
||||
|
||||
if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||
|
||||
P->digest_length = outlen;
|
||||
P->key_length = keylen;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store48( &P->node_offset, 0 );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
// memset(P->reserved, 0, sizeof(P->reserved) );
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
|
||||
if( blake2s_init_param( S, P ) < 0 ) return -1;
|
||||
|
||||
{
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
|
||||
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )
|
||||
{
|
||||
uint32_t m[16];
|
||||
uint32_t v[16];
|
||||
|
||||
for( size_t i = 0; i < 16; ++i )
|
||||
m[i] = load32( block + i * sizeof( m[i] ) );
|
||||
|
||||
for( size_t i = 0; i < 8; ++i )
|
||||
v[i] = S->h[i];
|
||||
|
||||
v[ 8] = blake2s_IV[0];
|
||||
v[ 9] = blake2s_IV[1];
|
||||
v[10] = blake2s_IV[2];
|
||||
v[11] = blake2s_IV[3];
|
||||
v[12] = S->t[0] ^ blake2s_IV[4];
|
||||
v[13] = S->t[1] ^ blake2s_IV[5];
|
||||
v[14] = S->f[0] ^ blake2s_IV[6];
|
||||
v[15] = S->f[1] ^ blake2s_IV[7];
|
||||
#define G(r,i,a,b,c,d) \
|
||||
do { \
|
||||
a = a + b + m[blake2s_sigma[r][2*i+0]]; \
|
||||
d = rotr32(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = rotr32(b ^ c, 12); \
|
||||
a = a + b + m[blake2s_sigma[r][2*i+1]]; \
|
||||
d = rotr32(d ^ a, 8); \
|
||||
c = c + d; \
|
||||
b = rotr32(b ^ c, 7); \
|
||||
} while(0)
|
||||
#define ROUND(r) \
|
||||
do { \
|
||||
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
|
||||
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
|
||||
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
|
||||
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
|
||||
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
|
||||
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
|
||||
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
|
||||
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
|
||||
} while(0)
|
||||
ROUND( 0 );
|
||||
ROUND( 1 );
|
||||
ROUND( 2 );
|
||||
ROUND( 3 );
|
||||
ROUND( 4 );
|
||||
ROUND( 5 );
|
||||
ROUND( 6 );
|
||||
ROUND( 7 );
|
||||
ROUND( 8 );
|
||||
ROUND( 9 );
|
||||
|
||||
for( size_t i = 0; i < 8; ++i )
|
||||
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||
|
||||
#undef G
|
||||
#undef ROUND
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen )
|
||||
{
|
||||
while( inlen > 0 )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
|
||||
|
||||
if( inlen > fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill ); // Fill buffer
|
||||
S->buflen += fill;
|
||||
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||
blake2s_compress( S, S->buf ); // Compress
|
||||
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left
|
||||
S->buflen -= BLAKE2S_BLOCKBYTES;
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
}
|
||||
else // inlen <= fill
|
||||
{
|
||||
memcpy( S->buf + left, in, inlen );
|
||||
S->buflen += inlen; // Be lazy, do not compress
|
||||
in += inlen;
|
||||
inlen -= inlen;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen )
|
||||
{
|
||||
uint8_t buffer[BLAKE2S_OUTBYTES];
|
||||
|
||||
if( S->buflen > BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||
blake2s_compress( S, S->buf );
|
||||
S->buflen -= BLAKE2S_BLOCKBYTES;
|
||||
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
|
||||
}
|
||||
|
||||
blake2s_increment_counter( S, ( uint32_t )S->buflen );
|
||||
blake2s_set_lastblock( S );
|
||||
memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
|
||||
blake2s_compress( S, S->buf );
|
||||
|
||||
for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
|
||||
store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
|
||||
|
||||
memcpy( out, buffer, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
blake2s_state S[1];
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if ( NULL == key ) keylen = 0; /* Fail here instead if keylen != 0 and key == NULL? */
|
||||
|
||||
if( keylen > 0 )
|
||||
{
|
||||
if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( blake2s_init( S, outlen ) < 0 ) return -1;
|
||||
}
|
||||
|
||||
blake2s_update( S, ( uint8_t * )in, inlen );
|
||||
blake2s_final( S, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(BLAKE2S_SELFTEST)
|
||||
#include <string.h>
|
||||
#include "blake2-kat.h"
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
uint8_t key[BLAKE2S_KEYBYTES];
|
||||
uint8_t buf[KAT_LENGTH];
|
||||
|
||||
for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i )
|
||||
key[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
buf[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
{
|
||||
uint8_t hash[BLAKE2S_OUTBYTES];
|
||||
blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES );
|
||||
|
||||
if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
|
||||
{
|
||||
puts( "error" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
puts( "ok" );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
295
ref/blake2sp-ref.c
Normal file
295
ref/blake2sp-ref.c
Normal file
@ -0,0 +1,295 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
#include "blake2.h"
|
||||
#include "blake2-impl.h"
|
||||
|
||||
#define PARALLELISM_DEGREE 8
|
||||
|
||||
static inline int blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
P->digest_length = outlen;
|
||||
P->key_length = keylen;
|
||||
P->fanout = PARALLELISM_DEGREE;
|
||||
P->depth = 2;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store48( P->node_offset, offset );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = outlen;
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2s_init_param( S, P );
|
||||
}
|
||||
|
||||
static inline int blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
P->digest_length = outlen;
|
||||
P->key_length = keylen;
|
||||
P->fanout = PARALLELISM_DEGREE;
|
||||
P->depth = 2;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store48( P->node_offset, 0ULL );
|
||||
P->node_depth = 1;
|
||||
P->inner_length = outlen;
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2s_init_param( S, P );
|
||||
}
|
||||
|
||||
|
||||
int blake2sp_init( blake2sp_state *S, const uint8_t outlen )
|
||||
{
|
||||
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
|
||||
if( blake2sp_init_root( S->R, outlen, 0 ) < 0 )
|
||||
return -1;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2sp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1;
|
||||
|
||||
S->R->last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
|
||||
{
|
||||
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||
|
||||
if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
|
||||
if( blake2sp_init_root( S->R, outlen, keylen ) < 0 )
|
||||
return -1;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2sp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1;
|
||||
|
||||
S->R->last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||
{
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = sizeof( S->buf ) - left;
|
||||
|
||||
if( left && inlen >= fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE)
|
||||
#else
|
||||
|
||||
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
|
||||
#endif
|
||||
{
|
||||
#if defined(_OPENMP)
|
||||
size_t id__ = omp_get_thread_num();
|
||||
#endif
|
||||
uint64_t inlen__ = inlen;
|
||||
const uint8_t *in__ = ( const uint8_t * )in;
|
||||
in__ += id__ * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
blake2s_update( S->S[id__], in__, BLAKE2S_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
|
||||
in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );
|
||||
inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
if( inlen > 0 )
|
||||
memcpy( S->buf + left, in, inlen );
|
||||
|
||||
S->buflen = left + inlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2sp_final( blake2sp_state *S, uint8_t *out, const uint8_t outlen )
|
||||
{
|
||||
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
{
|
||||
if( S->buflen > i * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;
|
||||
|
||||
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );
|
||||
}
|
||||
|
||||
blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES );
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );
|
||||
|
||||
blake2s_final( S->R, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2sp( uint8_t *out, const void *in, const void *key, uint8_t outlen, uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
|
||||
blake2s_state S[PARALLELISM_DEGREE][1];
|
||||
blake2s_state FS[1];
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if ( NULL == key ) keylen = 0;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2sp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1;
|
||||
|
||||
S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node
|
||||
|
||||
if( keylen > 0 )
|
||||
{
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)
|
||||
#else
|
||||
|
||||
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
|
||||
#endif
|
||||
{
|
||||
#if defined(_OPENMP)
|
||||
size_t id__ = omp_get_thread_num();
|
||||
#endif
|
||||
uint64_t inlen__ = inlen;
|
||||
const uint8_t *in__ = ( const uint8_t * )in;
|
||||
in__ += id__ * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
}
|
||||
|
||||
if( inlen__ > id__ * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES;
|
||||
const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;
|
||||
blake2s_update( S[id__], in__, len );
|
||||
}
|
||||
|
||||
blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES );
|
||||
}
|
||||
|
||||
if( blake2sp_init_root( FS, outlen, keylen ) < 0 )
|
||||
return -1;
|
||||
|
||||
FS->last_node = 1;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );
|
||||
|
||||
blake2s_final( FS, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined(BLAKE2SP_SELFTEST)
|
||||
#include <string.h>
|
||||
#include "blake2-kat.h"
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
uint8_t key[BLAKE2S_KEYBYTES];
|
||||
uint8_t buf[KAT_LENGTH];
|
||||
|
||||
for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i )
|
||||
key[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
buf[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
{
|
||||
uint8_t hash[BLAKE2S_OUTBYTES];
|
||||
blake2sp( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES );
|
||||
|
||||
if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) )
|
||||
{
|
||||
puts( "error" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
puts( "ok" );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
210
ref/genkat.c
Normal file
210
ref/genkat.c
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "blake2.h"
|
||||
|
||||
#define STR_(x) #x
|
||||
#define STR(x) STR_(x)
|
||||
|
||||
#define LENGTH 256
|
||||
|
||||
#define MAKE_KAT(name,size_prefix) \
|
||||
do \
|
||||
{ \
|
||||
printf( "static const uint8_t " #name "_kat[KAT_LENGTH][" #size_prefix "_OUTBYTES] = \n{\n" ); \
|
||||
\
|
||||
for( size_t i = 0; i < LENGTH; ++i ) \
|
||||
{ \
|
||||
name( hash, in, NULL, size_prefix ## _OUTBYTES, i, 0 ); \
|
||||
printf( "\t{\n\t\t" ); \
|
||||
\
|
||||
for( int j = 0; j < size_prefix ## _OUTBYTES; ++j ) \
|
||||
printf( "0x%02X%s", hash[j], ( j + 1 ) == size_prefix ## _OUTBYTES ? "\n" : j && !( ( j + 1 ) % 8 ) ? ",\n\t\t" : ", " ); \
|
||||
\
|
||||
printf( "\t},\n" ); \
|
||||
} \
|
||||
\
|
||||
printf( "};\n\n\n\n\n" ); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#define MAKE_KEYED_KAT(name,size_prefix) \
|
||||
do \
|
||||
{ \
|
||||
printf( "static const uint8_t " #name "_keyed_kat[KAT_LENGTH][" #size_prefix "_OUTBYTES] = \n{\n" ); \
|
||||
\
|
||||
for( size_t i = 0; i < LENGTH; ++i ) \
|
||||
{ \
|
||||
name( hash, in, key, size_prefix ## _OUTBYTES, i, size_prefix ## _KEYBYTES ); \
|
||||
printf( "\t{\n\t\t" ); \
|
||||
\
|
||||
for( int j = 0; j < size_prefix ## _OUTBYTES; ++j ) \
|
||||
printf( "0x%02X%s", hash[j], ( j + 1 ) == size_prefix ## _OUTBYTES ? "\n" : j && !( ( j + 1 ) % 8 ) ? ",\n\t\t" : ", " ); \
|
||||
\
|
||||
printf( "\t},\n" ); \
|
||||
} \
|
||||
\
|
||||
printf( "};\n\n\n\n\n" ); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
uint8_t key[64] = {0};
|
||||
uint8_t in[LENGTH] = {0};
|
||||
uint8_t hash[64] = {0};
|
||||
|
||||
for( size_t i = 0; i < sizeof( in ); ++i )
|
||||
in[i] = i;
|
||||
|
||||
for( size_t i = 0; i < sizeof( key ); ++i )
|
||||
key[i] = i;
|
||||
|
||||
puts( "#pragma once\n"
|
||||
"#ifndef __BLAKE2_KAT_H__\n"
|
||||
"#define __BLAKE2_KAT_H__\n\n\n"
|
||||
"#include <stdint.h>\n\n"
|
||||
"#define KAT_LENGTH " STR( LENGTH ) "\n\n\n" );
|
||||
MAKE_KAT( blake2s, BLAKE2S );
|
||||
MAKE_KEYED_KAT( blake2s, BLAKE2S );
|
||||
MAKE_KAT( blake2b, BLAKE2B );
|
||||
MAKE_KEYED_KAT( blake2b, BLAKE2B );
|
||||
MAKE_KAT( blake2sp, BLAKE2S );
|
||||
MAKE_KEYED_KAT( blake2sp, BLAKE2S );
|
||||
MAKE_KAT( blake2bp, BLAKE2B );
|
||||
MAKE_KEYED_KAT( blake2bp, BLAKE2B );
|
||||
/*printf( "static const uint8_t blake2s_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = \n{\n" );
|
||||
|
||||
for( size_t i = 0; i < LENGTH; ++i )
|
||||
{
|
||||
blake2s( hash, in, NULL, BLAKE2S_OUTBYTES, i, 0 );
|
||||
printf( "\t{\n\t\t" );
|
||||
|
||||
for( int j = 0; j < BLAKE2S_OUTBYTES; ++j )
|
||||
printf( "0x%02X%s", hash[j], ( j + 1 ) == BLAKE2S_OUTBYTES ? "\n" : j && !( ( j + 1 ) % 8 ) ? ",\n\t\t" : ", " );
|
||||
|
||||
printf( "\t},\n" );
|
||||
}
|
||||
|
||||
printf( "};\n\n\n\n\n" );
|
||||
printf( "static const uint8_t blake2s_keyed_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = \n{\n" );
|
||||
|
||||
for( size_t i = 0; i < LENGTH; ++i )
|
||||
{
|
||||
blake2s( hash, in, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES );
|
||||
printf( "\t{\n\t\t" );
|
||||
|
||||
for( int j = 0; j < BLAKE2S_OUTBYTES; ++j )
|
||||
printf( "0x%02X%s", hash[j], ( j + 1 ) == BLAKE2S_OUTBYTES ? "\n" : j && !( ( j + 1 ) % 8 ) ? ",\n\t\t" : ", " );
|
||||
|
||||
printf( "\t},\n" );
|
||||
}
|
||||
|
||||
printf( "};\n\n\n\n\n" );
|
||||
printf( "static const uint8_t blake2b_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = \n{\n" );
|
||||
|
||||
for( size_t i = 0; i < LENGTH; ++i )
|
||||
{
|
||||
blake2b( hash, in, NULL, BLAKE2B_OUTBYTES, i, 0 );
|
||||
printf( "\t{\n\t\t" );
|
||||
|
||||
for( int j = 0; j < BLAKE2B_OUTBYTES; ++j )
|
||||
printf( "0x%02X%s", hash[j], ( j + 1 ) == BLAKE2B_OUTBYTES ? "\n" : j && !( ( j + 1 ) % 8 ) ? ",\n\t\t" : ", " );
|
||||
|
||||
printf( "\t},\n" );
|
||||
}
|
||||
|
||||
printf( "};\n\n\n\n\n" );
|
||||
printf( "static const uint8_t blake2b_keyed_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = \n{\n" );
|
||||
|
||||
for( size_t i = 0; i < LENGTH; ++i )
|
||||
{
|
||||
blake2b( hash, in, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );
|
||||
printf( "\t{\n\t\t" );
|
||||
|
||||
for( int j = 0; j < BLAKE2B_OUTBYTES; ++j )
|
||||
printf( "0x%02X%s", hash[j], ( j + 1 ) == BLAKE2B_OUTBYTES ? "\n" : j && !( ( j + 1 ) % 8 ) ? ",\n\t\t" : ", " );
|
||||
|
||||
printf( "\t},\n" );
|
||||
}
|
||||
|
||||
printf( "};\n\n\n\n\n" );
|
||||
|
||||
|
||||
printf( "static const uint8_t blake2sp_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = \n{\n" );
|
||||
|
||||
for( size_t i = 0; i < LENGTH; ++i )
|
||||
{
|
||||
blake2sp( hash, in, NULL, BLAKE2S_OUTBYTES, i, 0 );
|
||||
printf( "\t{\n\t\t" );
|
||||
|
||||
for( int j = 0; j < BLAKE2S_OUTBYTES; ++j )
|
||||
printf( "0x%02X%s", hash[j], ( j + 1 ) == BLAKE2S_OUTBYTES ? "\n" : j && !( ( j + 1 ) % 8 ) ? ",\n\t\t" : ", " );
|
||||
|
||||
printf( "\t},\n" );
|
||||
}
|
||||
|
||||
printf( "};\n\n\n\n\n" );
|
||||
printf( "static const uint8_t blake2sp_keyed_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = \n{\n" );
|
||||
|
||||
for( size_t i = 0; i < LENGTH; ++i )
|
||||
{
|
||||
blake2sp( hash, in, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES );
|
||||
printf( "\t{\n\t\t" );
|
||||
|
||||
for( int j = 0; j < BLAKE2S_OUTBYTES; ++j )
|
||||
printf( "0x%02X%s", hash[j], ( j + 1 ) == BLAKE2S_OUTBYTES ? "\n" : j && !( ( j + 1 ) % 8 ) ? ",\n\t\t" : ", " );
|
||||
|
||||
printf( "\t},\n" );
|
||||
}
|
||||
|
||||
printf( "};\n\n\n\n\n" );
|
||||
|
||||
|
||||
printf( "static const uint8_t blake2bp_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = \n{\n" );
|
||||
|
||||
for( size_t i = 0; i < LENGTH; ++i )
|
||||
{
|
||||
blake2bp( hash, in, NULL, BLAKE2B_OUTBYTES, i, 0 );
|
||||
printf( "\t{\n\t\t" );
|
||||
|
||||
for( int j = 0; j < BLAKE2B_OUTBYTES; ++j )
|
||||
printf( "0x%02X%s", hash[j], ( j + 1 ) == BLAKE2B_OUTBYTES ? "\n" : j && !( ( j + 1 ) % 8 ) ? ",\n\t\t" : ", " );
|
||||
|
||||
printf( "\t},\n" );
|
||||
}
|
||||
|
||||
printf( "};\n\n\n\n\n" );
|
||||
printf( "static const uint8_t blake2bp_keyed_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = \n{\n" );
|
||||
|
||||
for( size_t i = 0; i < LENGTH; ++i )
|
||||
{
|
||||
blake2bp( hash, in, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );
|
||||
printf( "\t{\n\t\t" );
|
||||
|
||||
for( int j = 0; j < BLAKE2B_OUTBYTES; ++j )
|
||||
printf( "0x%02X%s", hash[j], ( j + 1 ) == BLAKE2B_OUTBYTES ? "\n" : j && !( ( j + 1 ) % 8 ) ? ",\n\t\t" : ", " );
|
||||
|
||||
printf( "\t},\n" );
|
||||
}
|
||||
|
||||
printf( "};\n\n\n\n\n" );*/
|
||||
puts( "#endif\n\n\n" );
|
||||
return 0;
|
||||
}
|
23
ref/makefile
Normal file
23
ref/makefile
Normal file
@ -0,0 +1,23 @@
|
||||
CC?=gcc
|
||||
CFLAGS=-std=c99 -Wall -pedantic
|
||||
|
||||
all: blake2s blake2b blake2sp blake2bp
|
||||
|
||||
blake2s: blake2s-ref.c
|
||||
$(CC) blake2s-ref.c -o $@ $(CFLAGS) -DBLAKE2S_SELFTEST
|
||||
|
||||
blake2b: blake2b-ref.c
|
||||
$(CC) blake2b-ref.c -o $@ $(CFLAGS) -DBLAKE2B_SELFTEST
|
||||
|
||||
blake2sp: blake2sp-ref.c blake2s-ref.c
|
||||
$(CC) blake2sp-ref.c -o $@ $(CFLAGS) -DBLAKE2SP_SELFTEST
|
||||
|
||||
blake2bp: blake2bp-ref.c blake2b-ref.c
|
||||
$(CC) blake2bp-ref.c -o $@ $(CFLAGS) -DBLAKE2BP_SELFTEST
|
||||
|
||||
kat:
|
||||
$(CC) $(CFLAGS) -o genkat genkat.c blake2b-ref.c blake2s-ref.c blake2sp-ref.c blake2bp-ref.c
|
||||
./genkat > blake2-kat.h
|
||||
|
||||
clean:
|
||||
rm -rf *.o genkat blake2s blake2b blake2sp blake2bp
|
72
sse/blake2-config.h
Normal file
72
sse/blake2-config.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2_CONFIG_H__
|
||||
#define __BLAKE2_CONFIG_H__
|
||||
|
||||
// These don't work everywhere
|
||||
#if defined(__SSE2__)
|
||||
#define HAVE_SSE2
|
||||
#endif
|
||||
|
||||
#if defined(__SSSE3__)
|
||||
#define HAVE_SSSE3
|
||||
#endif
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
#define HAVE_SSE41
|
||||
#endif
|
||||
|
||||
#if defined(__AVX__)
|
||||
#define HAVE_AVX
|
||||
#endif
|
||||
|
||||
#if defined(__XOP__)
|
||||
#define HAVE_XOP
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_AVX2
|
||||
#ifndef HAVE_AVX
|
||||
#define HAVE_AVX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XOP
|
||||
#ifndef HAVE_AVX
|
||||
#define HAVE_AVX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_AVX
|
||||
#ifndef HAVE_SSE41
|
||||
#define HAVE_SSE41
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SSE41
|
||||
#ifndef HAVE_SSSE3
|
||||
#define HAVE_SSSE3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SSSE3
|
||||
#define HAVE_SSE2
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_SSE2)
|
||||
#error "This code requires at least SSE2."
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
133
sse/blake2-impl.h
Normal file
133
sse/blake2-impl.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2_IMPL_H__
|
||||
#define __BLAKE2_IMPL_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static inline uint32_t load32( const void *src )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
return *( uint32_t * )( src );
|
||||
#else
|
||||
const uint8_t *p = ( uint8_t * )src;
|
||||
uint32_t w = *p++;
|
||||
w |= ( uint32_t )( *p++ ) << 8;
|
||||
w |= ( uint32_t )( *p++ ) << 16;
|
||||
w |= ( uint32_t )( *p++ ) << 24;
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t load64( const void *src )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
return *( uint64_t * )( src );
|
||||
#else
|
||||
const uint8_t *p = ( uint8_t * )src;
|
||||
uint64_t w = *p++;
|
||||
w |= ( uint64_t )( *p++ ) << 8;
|
||||
w |= ( uint64_t )( *p++ ) << 16;
|
||||
w |= ( uint64_t )( *p++ ) << 24;
|
||||
w |= ( uint64_t )( *p++ ) << 32;
|
||||
w |= ( uint64_t )( *p++ ) << 40;
|
||||
w |= ( uint64_t )( *p++ ) << 48;
|
||||
w |= ( uint64_t )( *p++ ) << 56;
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void store32( void *dst, uint32_t w )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
*( uint32_t * )( dst ) = w;
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void store64( void *dst, uint64_t w )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
*( uint64_t * )( dst ) = w;
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t load48( const void *src )
|
||||
{
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
uint64_t w = *p++;
|
||||
w |= ( uint64_t )( *p++ ) << 8;
|
||||
w |= ( uint64_t )( *p++ ) << 16;
|
||||
w |= ( uint64_t )( *p++ ) << 24;
|
||||
w |= ( uint64_t )( *p++ ) << 32;
|
||||
w |= ( uint64_t )( *p++ ) << 40;
|
||||
return w;
|
||||
}
|
||||
|
||||
static inline void store48( void *dst, uint64_t w )
|
||||
{
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
}
|
||||
|
||||
static inline uint32_t rotl32( const uint32_t w, const unsigned c )
|
||||
{
|
||||
return ( w << c ) | ( w >> ( 32 - c ) );
|
||||
}
|
||||
|
||||
static inline uint64_t rotl64( const uint64_t w, const unsigned c )
|
||||
{
|
||||
return ( w << c ) | ( w >> ( 64 - c ) );
|
||||
}
|
||||
|
||||
static inline uint32_t rotr32( const uint32_t w, const unsigned c )
|
||||
{
|
||||
return ( w >> c ) | ( w << ( 32 - c ) );
|
||||
}
|
||||
|
||||
static inline uint64_t rotr64( const uint64_t w, const unsigned c )
|
||||
{
|
||||
return ( w >> c ) | ( w << ( 64 - c ) );
|
||||
}
|
||||
|
||||
/* prevents compiler optimizing out memset() */
|
||||
static inline void secure_zero_memory( void *v, size_t n )
|
||||
{
|
||||
volatile uint8_t *p = ( volatile uint8_t * )v;
|
||||
|
||||
while( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
16467
sse/blake2-kat.h
Normal file
16467
sse/blake2-kat.h
Normal file
File diff suppressed because it is too large
Load Diff
156
sse/blake2.h
Normal file
156
sse/blake2.h
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2_H__
|
||||
#define __BLAKE2_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define ALIGN(x) __declspec(align(x))
|
||||
#else
|
||||
#define ALIGN(x) __attribute__ ((__aligned__(x)))
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum blake2s_constant
|
||||
{
|
||||
BLAKE2S_BLOCKBYTES = 64,
|
||||
BLAKE2S_OUTBYTES = 32,
|
||||
BLAKE2S_KEYBYTES = 32,
|
||||
BLAKE2S_SALTBYTES = 8,
|
||||
BLAKE2S_PERSONALBYTES = 8
|
||||
};
|
||||
|
||||
enum blake2b_constant
|
||||
{
|
||||
BLAKE2B_BLOCKBYTES = 128,
|
||||
BLAKE2B_OUTBYTES = 64,
|
||||
BLAKE2B_KEYBYTES = 64,
|
||||
BLAKE2B_SALTBYTES = 16,
|
||||
BLAKE2B_PERSONALBYTES = 16
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct __blake2s_param
|
||||
{
|
||||
uint8_t digest_length; // 1
|
||||
uint8_t key_length; // 2
|
||||
uint8_t fanout; // 3
|
||||
uint8_t depth; // 4
|
||||
uint32_t leaf_length; // 8
|
||||
uint8_t node_offset[6];// 14
|
||||
uint8_t node_depth; // 15
|
||||
uint8_t inner_length; // 16
|
||||
// uint8_t reserved[0];
|
||||
uint8_t salt[BLAKE2S_SALTBYTES]; // 24
|
||||
uint8_t personal[BLAKE2S_PERSONALBYTES]; // 32
|
||||
} blake2s_param;
|
||||
|
||||
ALIGN( 64 ) typedef struct __blake2s_state
|
||||
{
|
||||
uint32_t h[8];
|
||||
uint32_t t[2];
|
||||
uint32_t f[2];
|
||||
uint8_t buf[2 * BLAKE2S_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
uint8_t last_node;
|
||||
} blake2s_state;
|
||||
|
||||
typedef struct __blake2b_param
|
||||
{
|
||||
uint8_t digest_length; // 1
|
||||
uint8_t key_length; // 2
|
||||
uint8_t fanout; // 3
|
||||
uint8_t depth; // 4
|
||||
uint32_t leaf_length; // 8
|
||||
uint64_t node_offset; // 16
|
||||
uint8_t node_depth; // 17
|
||||
uint8_t inner_length; // 18
|
||||
uint8_t reserved[14]; // 32
|
||||
uint8_t salt[BLAKE2B_SALTBYTES]; // 48
|
||||
uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64
|
||||
} blake2b_param;
|
||||
|
||||
ALIGN( 64 ) typedef struct __blake2b_state
|
||||
{
|
||||
uint64_t h[8];
|
||||
uint64_t t[2];
|
||||
uint64_t f[2];
|
||||
uint8_t buf[2 * BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
uint8_t last_node;
|
||||
} blake2b_state;
|
||||
|
||||
ALIGN( 64 ) typedef struct __blake2sp_state
|
||||
{
|
||||
blake2s_state S[8][1];
|
||||
blake2s_state R[1];
|
||||
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
} blake2sp_state;
|
||||
|
||||
ALIGN( 64 ) typedef struct __blake2bp_state
|
||||
{
|
||||
blake2b_state S[4][1];
|
||||
blake2b_state R[1];
|
||||
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
} blake2bp_state;
|
||||
#pragma pack(pop)
|
||||
|
||||
// Streaming API
|
||||
int blake2s_init( blake2s_state *S, const uint8_t outlen );
|
||||
int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
||||
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
|
||||
int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen );
|
||||
int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen );
|
||||
|
||||
int blake2b_init( blake2b_state *S, const uint8_t outlen );
|
||||
int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
||||
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
|
||||
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen );
|
||||
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen );
|
||||
|
||||
int blake2sp_init( blake2sp_state *S, const uint8_t outlen );
|
||||
int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
||||
int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen );
|
||||
int blake2sp_final( blake2sp_state *S, uint8_t *out, uint8_t outlen );
|
||||
|
||||
int blake2bp_init( blake2bp_state *S, const uint8_t outlen );
|
||||
int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
||||
int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen );
|
||||
int blake2bp_final( blake2bp_state *S, uint8_t *out, uint8_t outlen );
|
||||
|
||||
// Simple API
|
||||
int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
||||
int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
||||
|
||||
int blake2sp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
||||
int blake2bp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
||||
|
||||
static inline int blake2( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
return blake2b( out, in, key, outlen, inlen, keylen );
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
68
sse/blake2b-load-sse2.h
Normal file
68
sse/blake2b-load-sse2.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2B_LOAD_SSE2_H__
|
||||
#define __BLAKE2B_LOAD_SSE2_H__
|
||||
|
||||
#define LOAD_MSG_0_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4)
|
||||
#define LOAD_MSG_0_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5)
|
||||
#define LOAD_MSG_0_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12)
|
||||
#define LOAD_MSG_0_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13)
|
||||
#define LOAD_MSG_1_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9)
|
||||
#define LOAD_MSG_1_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15)
|
||||
#define LOAD_MSG_1_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11)
|
||||
#define LOAD_MSG_1_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7)
|
||||
#define LOAD_MSG_2_1(b0, b1) b0 = _mm_set_epi64x(m12, m11); b1 = _mm_set_epi64x(m15, m5)
|
||||
#define LOAD_MSG_2_2(b0, b1) b0 = _mm_set_epi64x(m0, m8); b1 = _mm_set_epi64x(m13, m2)
|
||||
#define LOAD_MSG_2_3(b0, b1) b0 = _mm_set_epi64x(m3, m10); b1 = _mm_set_epi64x(m9, m7)
|
||||
#define LOAD_MSG_2_4(b0, b1) b0 = _mm_set_epi64x(m6, m14); b1 = _mm_set_epi64x(m4, m1)
|
||||
#define LOAD_MSG_3_1(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m13)
|
||||
#define LOAD_MSG_3_2(b0, b1) b0 = _mm_set_epi64x(m1, m9); b1 = _mm_set_epi64x(m14, m12)
|
||||
#define LOAD_MSG_3_3(b0, b1) b0 = _mm_set_epi64x(m5, m2); b1 = _mm_set_epi64x(m15, m4)
|
||||
#define LOAD_MSG_3_4(b0, b1) b0 = _mm_set_epi64x(m10, m6); b1 = _mm_set_epi64x(m8, m0)
|
||||
#define LOAD_MSG_4_1(b0, b1) b0 = _mm_set_epi64x(m5, m9); b1 = _mm_set_epi64x(m10, m2)
|
||||
#define LOAD_MSG_4_2(b0, b1) b0 = _mm_set_epi64x(m7, m0); b1 = _mm_set_epi64x(m15, m4)
|
||||
#define LOAD_MSG_4_3(b0, b1) b0 = _mm_set_epi64x(m11, m14); b1 = _mm_set_epi64x(m3, m6)
|
||||
#define LOAD_MSG_4_4(b0, b1) b0 = _mm_set_epi64x(m12, m1); b1 = _mm_set_epi64x(m13, m8)
|
||||
#define LOAD_MSG_5_1(b0, b1) b0 = _mm_set_epi64x(m6, m2); b1 = _mm_set_epi64x(m8, m0)
|
||||
#define LOAD_MSG_5_2(b0, b1) b0 = _mm_set_epi64x(m10, m12); b1 = _mm_set_epi64x(m3, m11)
|
||||
#define LOAD_MSG_5_3(b0, b1) b0 = _mm_set_epi64x(m7, m4); b1 = _mm_set_epi64x(m1, m15)
|
||||
#define LOAD_MSG_5_4(b0, b1) b0 = _mm_set_epi64x(m5, m13); b1 = _mm_set_epi64x(m9, m14)
|
||||
#define LOAD_MSG_6_1(b0, b1) b0 = _mm_set_epi64x(m1, m12); b1 = _mm_set_epi64x(m4, m14)
|
||||
#define LOAD_MSG_6_2(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m10, m13)
|
||||
#define LOAD_MSG_6_3(b0, b1) b0 = _mm_set_epi64x(m6, m0); b1 = _mm_set_epi64x(m8, m9)
|
||||
#define LOAD_MSG_6_4(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m2)
|
||||
#define LOAD_MSG_7_1(b0, b1) b0 = _mm_set_epi64x(m7, m13); b1 = _mm_set_epi64x(m3, m12)
|
||||
#define LOAD_MSG_7_2(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m9, m1)
|
||||
#define LOAD_MSG_7_3(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m2, m8)
|
||||
#define LOAD_MSG_7_4(b0, b1) b0 = _mm_set_epi64x(m4, m0); b1 = _mm_set_epi64x(m10, m6)
|
||||
#define LOAD_MSG_8_1(b0, b1) b0 = _mm_set_epi64x(m14, m6); b1 = _mm_set_epi64x(m0, m11)
|
||||
#define LOAD_MSG_8_2(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m8, m3)
|
||||
#define LOAD_MSG_8_3(b0, b1) b0 = _mm_set_epi64x(m13, m12); b1 = _mm_set_epi64x(m10, m1)
|
||||
#define LOAD_MSG_8_4(b0, b1) b0 = _mm_set_epi64x(m7, m2); b1 = _mm_set_epi64x(m5, m4)
|
||||
#define LOAD_MSG_9_1(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m1, m7)
|
||||
#define LOAD_MSG_9_2(b0, b1) b0 = _mm_set_epi64x(m4, m2); b1 = _mm_set_epi64x(m5, m6)
|
||||
#define LOAD_MSG_9_3(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m13, m3)
|
||||
#define LOAD_MSG_9_4(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m0, m12)
|
||||
#define LOAD_MSG_10_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4)
|
||||
#define LOAD_MSG_10_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5)
|
||||
#define LOAD_MSG_10_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12)
|
||||
#define LOAD_MSG_10_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13)
|
||||
#define LOAD_MSG_11_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9)
|
||||
#define LOAD_MSG_11_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15)
|
||||
#define LOAD_MSG_11_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11)
|
||||
#define LOAD_MSG_11_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7)
|
||||
|
||||
|
||||
#endif
|
||||
|
402
sse/blake2b-load-sse41.h
Normal file
402
sse/blake2b-load-sse41.h
Normal file
@ -0,0 +1,402 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2B_LOAD_SSE41_H__
|
||||
#define __BLAKE2B_LOAD_SSE41_H__
|
||||
|
||||
#define LOAD_MSG_0_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m0, m1); \
|
||||
b1 = _mm_unpacklo_epi64(m2, m3); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_0_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m0, m1); \
|
||||
b1 = _mm_unpackhi_epi64(m2, m3); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_0_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m4, m5); \
|
||||
b1 = _mm_unpacklo_epi64(m6, m7); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_0_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m4, m5); \
|
||||
b1 = _mm_unpackhi_epi64(m6, m7); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_1_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m7, m2); \
|
||||
b1 = _mm_unpackhi_epi64(m4, m6); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_1_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m5, m4); \
|
||||
b1 = _mm_alignr_epi8(m3, m7, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_1_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \
|
||||
b1 = _mm_unpackhi_epi64(m5, m2); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_1_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m6, m1); \
|
||||
b1 = _mm_unpackhi_epi64(m3, m1); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_2_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_alignr_epi8(m6, m5, 8); \
|
||||
b1 = _mm_unpackhi_epi64(m2, m7); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_2_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m4, m0); \
|
||||
b1 = _mm_blend_epi16(m1, m6, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_2_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m5, m1, 0xF0); \
|
||||
b1 = _mm_unpackhi_epi64(m3, m4); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_2_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m7, m3); \
|
||||
b1 = _mm_alignr_epi8(m2, m0, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_3_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m3, m1); \
|
||||
b1 = _mm_unpackhi_epi64(m6, m5); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_3_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m4, m0); \
|
||||
b1 = _mm_unpacklo_epi64(m6, m7); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_3_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m1, m2, 0xF0); \
|
||||
b1 = _mm_blend_epi16(m2, m7, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_3_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m3, m5); \
|
||||
b1 = _mm_unpacklo_epi64(m0, m4); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_4_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m4, m2); \
|
||||
b1 = _mm_unpacklo_epi64(m1, m5); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_4_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m0, m3, 0xF0); \
|
||||
b1 = _mm_blend_epi16(m2, m7, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_4_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m7, m5, 0xF0); \
|
||||
b1 = _mm_blend_epi16(m3, m1, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_4_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_alignr_epi8(m6, m0, 8); \
|
||||
b1 = _mm_blend_epi16(m4, m6, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_5_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m1, m3); \
|
||||
b1 = _mm_unpacklo_epi64(m0, m4); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_5_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m6, m5); \
|
||||
b1 = _mm_unpackhi_epi64(m5, m1); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_5_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m2, m3, 0xF0); \
|
||||
b1 = _mm_unpackhi_epi64(m7, m0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_5_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m6, m2); \
|
||||
b1 = _mm_blend_epi16(m7, m4, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_6_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m6, m0, 0xF0); \
|
||||
b1 = _mm_unpacklo_epi64(m7, m2); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_6_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m2, m7); \
|
||||
b1 = _mm_alignr_epi8(m5, m6, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_6_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m0, m3); \
|
||||
b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1,0,3,2)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_6_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m3, m1); \
|
||||
b1 = _mm_blend_epi16(m1, m5, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_7_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m6, m3); \
|
||||
b1 = _mm_blend_epi16(m6, m1, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_7_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_alignr_epi8(m7, m5, 8); \
|
||||
b1 = _mm_unpackhi_epi64(m0, m4); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_7_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m2, m7); \
|
||||
b1 = _mm_unpacklo_epi64(m4, m1); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_7_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m0, m2); \
|
||||
b1 = _mm_unpacklo_epi64(m3, m5); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_8_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m3, m7); \
|
||||
b1 = _mm_alignr_epi8(m0, m5, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_8_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m7, m4); \
|
||||
b1 = _mm_alignr_epi8(m4, m1, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_8_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = m6; \
|
||||
b1 = _mm_alignr_epi8(m5, m0, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_8_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m1, m3, 0xF0); \
|
||||
b1 = m2; \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_9_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m5, m4); \
|
||||
b1 = _mm_unpackhi_epi64(m3, m0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_9_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m1, m2); \
|
||||
b1 = _mm_blend_epi16(m3, m2, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_9_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m7, m4); \
|
||||
b1 = _mm_unpackhi_epi64(m1, m6); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_9_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_alignr_epi8(m7, m5, 8); \
|
||||
b1 = _mm_unpacklo_epi64(m6, m0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_10_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m0, m1); \
|
||||
b1 = _mm_unpacklo_epi64(m2, m3); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_10_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m0, m1); \
|
||||
b1 = _mm_unpackhi_epi64(m2, m3); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_10_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m4, m5); \
|
||||
b1 = _mm_unpacklo_epi64(m6, m7); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_10_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m4, m5); \
|
||||
b1 = _mm_unpackhi_epi64(m6, m7); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_11_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m7, m2); \
|
||||
b1 = _mm_unpackhi_epi64(m4, m6); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_11_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m5, m4); \
|
||||
b1 = _mm_alignr_epi8(m3, m7, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_11_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \
|
||||
b1 = _mm_unpackhi_epi64(m5, m2); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_11_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m6, m1); \
|
||||
b1 = _mm_unpackhi_epi64(m3, m1); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#endif
|
||||
|
160
sse/blake2b-round.h
Normal file
160
sse/blake2b-round.h
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2B_ROUND_H__
|
||||
#define __BLAKE2B_ROUND_H__
|
||||
|
||||
#define LOAD(p) _mm_load_si128( (__m128i *)(p) )
|
||||
#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)
|
||||
|
||||
#define LOADU(p) _mm_loadu_si128( (__m128i *)(p) )
|
||||
#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r)
|
||||
|
||||
#define TOF(reg) _mm_castsi128_ps((reg))
|
||||
#define TOI(reg) _mm_castps_si128((reg))
|
||||
|
||||
#define LIKELY(x) __builtin_expect((x),1)
|
||||
|
||||
|
||||
/* Microarchitecture-specific macros */
|
||||
#ifndef HAVE_XOP
|
||||
#ifdef HAVE_SSSE3
|
||||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \
|
||||
: (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \
|
||||
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c))))
|
||||
#else
|
||||
#define _mm_roti_epi64(r, c) _mm_xor_si128(_mm_srli_epi64( (r), -(c) ),_mm_slli_epi64( (r), 64-(-c) ))
|
||||
#endif
|
||||
#else
|
||||
/* ... */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \
|
||||
row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
|
||||
row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -32); \
|
||||
row4h = _mm_roti_epi64(row4h, -32); \
|
||||
\
|
||||
row3l = _mm_add_epi64(row3l, row4l); \
|
||||
row3h = _mm_add_epi64(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -24); \
|
||||
row2h = _mm_roti_epi64(row2h, -24); \
|
||||
|
||||
#define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \
|
||||
row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
|
||||
row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -16); \
|
||||
row4h = _mm_roti_epi64(row4h, -16); \
|
||||
\
|
||||
row3l = _mm_add_epi64(row3l, row4l); \
|
||||
row3h = _mm_add_epi64(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -63); \
|
||||
row2h = _mm_roti_epi64(row2h, -63); \
|
||||
|
||||
#if defined(HAVE_SSSE3)
|
||||
#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
t1 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
t1 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
|
||||
#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
t1 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
t1 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
#else
|
||||
|
||||
#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = row4l;\
|
||||
t1 = row2l;\
|
||||
row4l = row3l;\
|
||||
row3l = row3h;\
|
||||
row3h = row4l;\
|
||||
row4l = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t0, t0)); \
|
||||
row4h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row4h, row4h)); \
|
||||
row2l = _mm_unpackhi_epi64(row2l, _mm_unpacklo_epi64(row2h, row2h)); \
|
||||
row2h = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(t1, t1))
|
||||
|
||||
#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = row3l;\
|
||||
row3l = row3h;\
|
||||
row3h = t0;\
|
||||
t0 = row2l;\
|
||||
t1 = row4l;\
|
||||
row2l = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(row2l, row2l)); \
|
||||
row2h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row2h, row2h)); \
|
||||
row4l = _mm_unpackhi_epi64(row4l, _mm_unpacklo_epi64(row4h, row4h)); \
|
||||
row4h = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t1, t1))
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SSE41)
|
||||
#include "blake2b-load-sse41.h"
|
||||
#else
|
||||
#include "blake2b-load-sse2.h"
|
||||
#endif
|
||||
|
||||
#define ROUND(r) \
|
||||
LOAD_MSG_ ##r ##_1(b0, b1); \
|
||||
G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||
LOAD_MSG_ ##r ##_2(b0, b1); \
|
||||
G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||
DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
LOAD_MSG_ ##r ##_3(b0, b1); \
|
||||
G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||
LOAD_MSG_ ##r ##_4(b0, b1); \
|
||||
G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||
UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h);
|
||||
|
||||
#endif
|
||||
|
431
sse/blake2b.c
Normal file
431
sse/blake2b.c
Normal file
@ -0,0 +1,431 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "blake2.h"
|
||||
#include "blake2-impl.h"
|
||||
|
||||
#include "blake2-config.h"
|
||||
|
||||
|
||||
#include <emmintrin.h>
|
||||
#if defined(HAVE_SSSE3)
|
||||
#include <tmmintrin.h>
|
||||
#endif
|
||||
#if defined(HAVE_SSE41)
|
||||
#include <smmintrin.h>
|
||||
#endif
|
||||
#if defined(HAVE_AVX)
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#if defined(HAVE_XOP)
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#include "blake2b-round.h"
|
||||
|
||||
ALIGN( 64 ) static const uint64_t blake2b_IV[8] =
|
||||
{
|
||||
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
|
||||
0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
|
||||
0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
|
||||
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
|
||||
};
|
||||
|
||||
static const uint8_t blake2b_sigma[12][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
|
||||
};
|
||||
|
||||
|
||||
/* Some helper functions, not necessarily useful */
|
||||
static inline int blake2b_set_lastnode( blake2b_state *S )
|
||||
{
|
||||
S->f[1] = ~0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_clear_lastnode( blake2b_state *S )
|
||||
{
|
||||
S->f[1] = 0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_set_lastblock( blake2b_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2b_set_lastnode( S );
|
||||
|
||||
S->f[0] = ~0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_clear_lastblock( blake2b_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2b_clear_lastnode( S );
|
||||
|
||||
S->f[0] = 0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
|
||||
{
|
||||
#if __x86_64__
|
||||
// ADD/ADC chain
|
||||
__uint128_t t = ( ( __uint128_t )S->t[1] << 64 ) | S->t[0];
|
||||
t += inc;
|
||||
S->t[0] = ( uint64_t )( t >> 0 );
|
||||
S->t[1] = ( uint64_t )( t >> 64 );
|
||||
#else
|
||||
S->t[0] += inc;
|
||||
S->t[1] += ( S->t[0] < inc );
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Parameter-related functions
|
||||
static inline int blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length )
|
||||
{
|
||||
P->digest_length = digest_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )
|
||||
{
|
||||
P->fanout = fanout;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )
|
||||
{
|
||||
P->depth = depth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )
|
||||
{
|
||||
P->leaf_length = leaf_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )
|
||||
{
|
||||
P->node_offset = node_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )
|
||||
{
|
||||
P->node_depth = node_depth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )
|
||||
{
|
||||
P->inner_length = inner_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )
|
||||
{
|
||||
memcpy( P->salt, salt, BLAKE2B_SALTBYTES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )
|
||||
{
|
||||
memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_init0( blake2b_state *S )
|
||||
{
|
||||
memset( S, 0, sizeof( blake2b_state ) );
|
||||
|
||||
for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* init xors IV with input parameter block */
|
||||
int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
|
||||
{
|
||||
uint8_t *p, *h, *v;
|
||||
//blake2b_init0( S );
|
||||
v = ( uint8_t * )( blake2b_IV );
|
||||
h = ( uint8_t * )( S->h );
|
||||
p = ( uint8_t * )( P );
|
||||
/* IV XOR ParamBlock */
|
||||
memset( S, 0, sizeof( blake2b_state ) );
|
||||
|
||||
for( int i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Some sort of default parameter block initialization, for sequential blake2b */
|
||||
int blake2b_init( blake2b_state *S, const uint8_t outlen )
|
||||
{
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
|
||||
|
||||
const blake2b_param P =
|
||||
{
|
||||
outlen,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{0},
|
||||
{0},
|
||||
{0}
|
||||
};
|
||||
return blake2b_init_param( S, &P );
|
||||
}
|
||||
|
||||
int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
|
||||
{
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
|
||||
|
||||
if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1;
|
||||
|
||||
const blake2b_param P =
|
||||
{
|
||||
outlen,
|
||||
keylen,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{0},
|
||||
{0},
|
||||
{0}
|
||||
};
|
||||
|
||||
if( blake2b_init_param( S, &P ) < 0 )
|
||||
return 0;
|
||||
|
||||
{
|
||||
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2B_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
|
||||
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
|
||||
{
|
||||
__m128i row1l, row1h;
|
||||
__m128i row2l, row2h;
|
||||
__m128i row3l, row3h;
|
||||
__m128i row4l, row4h;
|
||||
__m128i b0, b1;
|
||||
__m128i t0, t1;
|
||||
#if defined(HAVE_SSSE3) && !defined(HAVE_XOP)
|
||||
const __m128i r16 = _mm_setr_epi8( 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9 );
|
||||
const __m128i r24 = _mm_setr_epi8( 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10 );
|
||||
#endif
|
||||
#if defined(HAVE_SSE41)
|
||||
const __m128i m0 = LOADU( block + 00 );
|
||||
const __m128i m1 = LOADU( block + 16 );
|
||||
const __m128i m2 = LOADU( block + 32 );
|
||||
const __m128i m3 = LOADU( block + 48 );
|
||||
const __m128i m4 = LOADU( block + 64 );
|
||||
const __m128i m5 = LOADU( block + 80 );
|
||||
const __m128i m6 = LOADU( block + 96 );
|
||||
const __m128i m7 = LOADU( block + 112 );
|
||||
#else
|
||||
const uint64_t m0 = ( ( uint64_t * )block )[ 0];
|
||||
const uint64_t m1 = ( ( uint64_t * )block )[ 1];
|
||||
const uint64_t m2 = ( ( uint64_t * )block )[ 2];
|
||||
const uint64_t m3 = ( ( uint64_t * )block )[ 3];
|
||||
const uint64_t m4 = ( ( uint64_t * )block )[ 4];
|
||||
const uint64_t m5 = ( ( uint64_t * )block )[ 5];
|
||||
const uint64_t m6 = ( ( uint64_t * )block )[ 6];
|
||||
const uint64_t m7 = ( ( uint64_t * )block )[ 7];
|
||||
const uint64_t m8 = ( ( uint64_t * )block )[ 8];
|
||||
const uint64_t m9 = ( ( uint64_t * )block )[ 9];
|
||||
const uint64_t m10 = ( ( uint64_t * )block )[10];
|
||||
const uint64_t m11 = ( ( uint64_t * )block )[11];
|
||||
const uint64_t m12 = ( ( uint64_t * )block )[12];
|
||||
const uint64_t m13 = ( ( uint64_t * )block )[13];
|
||||
const uint64_t m14 = ( ( uint64_t * )block )[14];
|
||||
const uint64_t m15 = ( ( uint64_t * )block )[15];
|
||||
#endif
|
||||
row1l = LOAD( &S->h[0] );
|
||||
row1h = LOAD( &S->h[2] );
|
||||
row2l = LOAD( &S->h[4] );
|
||||
row2h = LOAD( &S->h[6] );
|
||||
row3l = LOAD( &blake2b_IV[0] );
|
||||
row3h = LOAD( &blake2b_IV[2] );
|
||||
row4l = _mm_xor_si128( LOAD( &blake2b_IV[4] ), LOAD( &S->t[0] ) );
|
||||
row4h = _mm_xor_si128( LOAD( &blake2b_IV[6] ), LOAD( &S->f[0] ) );
|
||||
ROUND( 0 );
|
||||
ROUND( 1 );
|
||||
ROUND( 2 );
|
||||
ROUND( 3 );
|
||||
ROUND( 4 );
|
||||
ROUND( 5 );
|
||||
ROUND( 6 );
|
||||
ROUND( 7 );
|
||||
ROUND( 8 );
|
||||
ROUND( 9 );
|
||||
ROUND( 10 );
|
||||
ROUND( 11 );
|
||||
row1l = _mm_xor_si128( row3l, row1l );
|
||||
row1h = _mm_xor_si128( row3h, row1h );
|
||||
STORE( &S->h[0], _mm_xor_si128( LOAD( &S->h[0] ), row1l ) );
|
||||
STORE( &S->h[2], _mm_xor_si128( LOAD( &S->h[2] ), row1h ) );
|
||||
row2l = _mm_xor_si128( row4l, row2l );
|
||||
row2h = _mm_xor_si128( row4h, row2h );
|
||||
STORE( &S->h[4], _mm_xor_si128( LOAD( &S->h[4] ), row2l ) );
|
||||
STORE( &S->h[6], _mm_xor_si128( LOAD( &S->h[6] ), row2h ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen )
|
||||
{
|
||||
while( inlen > 0 )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
|
||||
|
||||
if( inlen > fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill ); // Fill buffer
|
||||
S->buflen += fill;
|
||||
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
|
||||
blake2b_compress( S, S->buf ); // Compress
|
||||
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left
|
||||
S->buflen -= BLAKE2B_BLOCKBYTES;
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
}
|
||||
else // inlen <= fill
|
||||
{
|
||||
memcpy( S->buf + left, in, inlen );
|
||||
S->buflen += inlen; // Be lazy, do not compress
|
||||
in += inlen;
|
||||
inlen -= inlen;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen )
|
||||
{
|
||||
if( S->buflen > BLAKE2B_BLOCKBYTES )
|
||||
{
|
||||
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
|
||||
blake2b_compress( S, S->buf );
|
||||
S->buflen -= BLAKE2B_BLOCKBYTES;
|
||||
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );
|
||||
}
|
||||
|
||||
blake2b_increment_counter( S, S->buflen );
|
||||
blake2b_set_lastblock( S );
|
||||
memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
|
||||
blake2b_compress( S, S->buf );
|
||||
memcpy( out, &S->h[0], outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
blake2b_state S[1];
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if( NULL == key ) keylen = 0;
|
||||
|
||||
if( keylen )
|
||||
{
|
||||
if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( blake2b_init( S, outlen ) < 0 ) return -1;
|
||||
}
|
||||
|
||||
blake2b_update( S, ( uint8_t * )in, inlen );
|
||||
blake2b_final( S, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(SUPERCOP)
|
||||
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
|
||||
{
|
||||
return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BLAKE2B_SELFTEST)
|
||||
#include <string.h>
|
||||
#include "blake2-kat.h"
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
uint8_t key[BLAKE2B_KEYBYTES];
|
||||
uint8_t buf[KAT_LENGTH];
|
||||
|
||||
for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i )
|
||||
key[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
buf[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
{
|
||||
uint8_t hash[BLAKE2B_OUTBYTES];
|
||||
blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );
|
||||
|
||||
if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
|
||||
{
|
||||
puts( "error" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
puts( "ok" );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
296
sse/blake2bp.c
Normal file
296
sse/blake2bp.c
Normal file
@ -0,0 +1,296 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
#include "blake2.h"
|
||||
#include "blake2-impl.h"
|
||||
|
||||
#define PARALLELISM_DEGREE 4
|
||||
|
||||
static inline int blake2bp_init_leaf( blake2b_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )
|
||||
{
|
||||
blake2b_param P[1];
|
||||
P->digest_length = outlen;
|
||||
P->key_length = keylen;
|
||||
P->fanout = PARALLELISM_DEGREE;
|
||||
P->depth = 2;
|
||||
P->leaf_length = 0;
|
||||
P->node_offset = offset;
|
||||
P->node_depth = 0;
|
||||
P->inner_length = outlen;
|
||||
memset( P->reserved, 0, sizeof( P->reserved ) );
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2b_init_param( S, P );
|
||||
}
|
||||
|
||||
static inline int blake2bp_init_root( blake2b_state *S, uint8_t outlen, uint8_t keylen )
|
||||
{
|
||||
blake2b_param P[1];
|
||||
P->digest_length = outlen;
|
||||
P->key_length = keylen;
|
||||
P->fanout = PARALLELISM_DEGREE;
|
||||
P->depth = 2;
|
||||
P->leaf_length = 0;
|
||||
P->node_offset = 0;
|
||||
P->node_depth = 1;
|
||||
P->inner_length = outlen;
|
||||
memset( P->reserved, 0, sizeof( P->reserved ) );
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2b_init_param( S, P );
|
||||
}
|
||||
|
||||
|
||||
int blake2bp_init( blake2bp_state *S, const uint8_t outlen )
|
||||
{
|
||||
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
|
||||
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
|
||||
if( blake2bp_init_root( S->R, outlen, 0 ) < 0 )
|
||||
return -1;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2bp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1;
|
||||
|
||||
S->R->last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
|
||||
{
|
||||
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
|
||||
|
||||
if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
|
||||
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
|
||||
if( blake2bp_init_root( S->R, outlen, keylen ) < 0 )
|
||||
return -1;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2bp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1;
|
||||
|
||||
S->R->last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||
{
|
||||
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2B_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES );
|
||||
|
||||
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = sizeof( S->buf ) - left;
|
||||
|
||||
if( left && inlen >= fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES );
|
||||
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE)
|
||||
#else
|
||||
|
||||
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
|
||||
#endif
|
||||
{
|
||||
#if defined(_OPENMP)
|
||||
size_t id__ = omp_get_thread_num();
|
||||
#endif
|
||||
uint64_t inlen__ = inlen;
|
||||
const uint8_t *in__ = ( const uint8_t * )in;
|
||||
in__ += id__ * BLAKE2B_BLOCKBYTES;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )
|
||||
{
|
||||
blake2b_update( S->S[id__], in__, BLAKE2B_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
|
||||
in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES );
|
||||
inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||
|
||||
if( inlen > 0 )
|
||||
memcpy( S->buf + left, in, inlen );
|
||||
|
||||
S->buflen = left + inlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int blake2bp_final( blake2bp_state *S, uint8_t *out, const uint8_t outlen )
|
||||
{
|
||||
uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
{
|
||||
if( S->buflen > i * BLAKE2B_BLOCKBYTES )
|
||||
{
|
||||
size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES;
|
||||
|
||||
if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES;
|
||||
|
||||
blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left );
|
||||
}
|
||||
|
||||
blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES );
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES );
|
||||
|
||||
blake2b_final( S->R, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2bp( uint8_t *out, const void *in, const void *key, uint8_t outlen, uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];
|
||||
blake2b_state S[PARALLELISM_DEGREE][1];
|
||||
blake2b_state FS[1];
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if ( NULL == key ) keylen = 0;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2bp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1;
|
||||
|
||||
S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node
|
||||
|
||||
if( keylen > 0 )
|
||||
{
|
||||
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2B_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES );
|
||||
|
||||
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)
|
||||
#else
|
||||
|
||||
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
|
||||
#endif
|
||||
{
|
||||
#if defined(_OPENMP)
|
||||
size_t id__ = omp_get_thread_num();
|
||||
#endif
|
||||
uint64_t inlen__ = inlen;
|
||||
const uint8_t *in__ = ( const uint8_t * )in;
|
||||
in__ += id__ * BLAKE2B_BLOCKBYTES;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )
|
||||
{
|
||||
blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||
}
|
||||
|
||||
if( inlen__ > id__ * BLAKE2B_BLOCKBYTES )
|
||||
{
|
||||
const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES;
|
||||
const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES;
|
||||
blake2b_update( S[id__], in__, len );
|
||||
}
|
||||
|
||||
blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES );
|
||||
}
|
||||
|
||||
if( blake2bp_init_root( FS, outlen, keylen ) < 0 )
|
||||
return -1;
|
||||
|
||||
FS->last_node = 1; // Mark as last node
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES );
|
||||
|
||||
blake2b_final( FS, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if defined(BLAKE2BP_SELFTEST)
|
||||
#include <string.h>
|
||||
#include "blake2-kat.h"
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
uint8_t key[BLAKE2B_KEYBYTES];
|
||||
uint8_t buf[KAT_LENGTH];
|
||||
|
||||
for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i )
|
||||
key[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
buf[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
{
|
||||
uint8_t hash[BLAKE2B_OUTBYTES];
|
||||
//blake2bp( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );
|
||||
blake2bp_state S[1];
|
||||
blake2bp_init_key( S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES );
|
||||
blake2bp_update( S, buf, i );
|
||||
blake2bp_final( S, hash, BLAKE2B_OUTBYTES );
|
||||
|
||||
if( 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) )
|
||||
{
|
||||
puts( "error" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
puts( "ok" );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
59
sse/blake2s-load-sse2.h
Normal file
59
sse/blake2s-load-sse2.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2S_LOAD_SSE2_H__
|
||||
#define __BLAKE2S_LOAD_SSE2_H__
|
||||
|
||||
#define LOAD_MSG_0_1(buf) buf = _mm_set_epi32(m6,m4,m2,m0)
|
||||
#define LOAD_MSG_0_2(buf) buf = _mm_set_epi32(m7,m5,m3,m1)
|
||||
#define LOAD_MSG_0_3(buf) buf = _mm_set_epi32(m14,m12,m10,m8)
|
||||
#define LOAD_MSG_0_4(buf) buf = _mm_set_epi32(m15,m13,m11,m9)
|
||||
#define LOAD_MSG_1_1(buf) buf = _mm_set_epi32(m13,m9,m4,m14)
|
||||
#define LOAD_MSG_1_2(buf) buf = _mm_set_epi32(m6,m15,m8,m10)
|
||||
#define LOAD_MSG_1_3(buf) buf = _mm_set_epi32(m5,m11,m0,m1)
|
||||
#define LOAD_MSG_1_4(buf) buf = _mm_set_epi32(m3,m7,m2,m12)
|
||||
#define LOAD_MSG_2_1(buf) buf = _mm_set_epi32(m15,m5,m12,m11)
|
||||
#define LOAD_MSG_2_2(buf) buf = _mm_set_epi32(m13,m2,m0,m8)
|
||||
#define LOAD_MSG_2_3(buf) buf = _mm_set_epi32(m9,m7,m3,m10)
|
||||
#define LOAD_MSG_2_4(buf) buf = _mm_set_epi32(m4,m1,m6,m14)
|
||||
#define LOAD_MSG_3_1(buf) buf = _mm_set_epi32(m11,m13,m3,m7)
|
||||
#define LOAD_MSG_3_2(buf) buf = _mm_set_epi32(m14,m12,m1,m9)
|
||||
#define LOAD_MSG_3_3(buf) buf = _mm_set_epi32(m15,m4,m5,m2)
|
||||
#define LOAD_MSG_3_4(buf) buf = _mm_set_epi32(m8,m0,m10,m6)
|
||||
#define LOAD_MSG_4_1(buf) buf = _mm_set_epi32(m10,m2,m5,m9)
|
||||
#define LOAD_MSG_4_2(buf) buf = _mm_set_epi32(m15,m4,m7,m0)
|
||||
#define LOAD_MSG_4_3(buf) buf = _mm_set_epi32(m3,m6,m11,m14)
|
||||
#define LOAD_MSG_4_4(buf) buf = _mm_set_epi32(m13,m8,m12,m1)
|
||||
#define LOAD_MSG_5_1(buf) buf = _mm_set_epi32(m8,m0,m6,m2)
|
||||
#define LOAD_MSG_5_2(buf) buf = _mm_set_epi32(m3,m11,m10,m12)
|
||||
#define LOAD_MSG_5_3(buf) buf = _mm_set_epi32(m1,m15,m7,m4)
|
||||
#define LOAD_MSG_5_4(buf) buf = _mm_set_epi32(m9,m14,m5,m13)
|
||||
#define LOAD_MSG_6_1(buf) buf = _mm_set_epi32(m4,m14,m1,m12)
|
||||
#define LOAD_MSG_6_2(buf) buf = _mm_set_epi32(m10,m13,m15,m5)
|
||||
#define LOAD_MSG_6_3(buf) buf = _mm_set_epi32(m8,m9,m6,m0)
|
||||
#define LOAD_MSG_6_4(buf) buf = _mm_set_epi32(m11,m2,m3,m7)
|
||||
#define LOAD_MSG_7_1(buf) buf = _mm_set_epi32(m3,m12,m7,m13)
|
||||
#define LOAD_MSG_7_2(buf) buf = _mm_set_epi32(m9,m1,m14,m11)
|
||||
#define LOAD_MSG_7_3(buf) buf = _mm_set_epi32(m2,m8,m15,m5)
|
||||
#define LOAD_MSG_7_4(buf) buf = _mm_set_epi32(m10,m6,m4,m0)
|
||||
#define LOAD_MSG_8_1(buf) buf = _mm_set_epi32(m0,m11,m14,m6)
|
||||
#define LOAD_MSG_8_2(buf) buf = _mm_set_epi32(m8,m3,m9,m15)
|
||||
#define LOAD_MSG_8_3(buf) buf = _mm_set_epi32(m10,m1,m13,m12)
|
||||
#define LOAD_MSG_8_4(buf) buf = _mm_set_epi32(m5,m4,m7,m2)
|
||||
#define LOAD_MSG_9_1(buf) buf = _mm_set_epi32(m1,m7,m8,m10)
|
||||
#define LOAD_MSG_9_2(buf) buf = _mm_set_epi32(m5,m6,m4,m2)
|
||||
#define LOAD_MSG_9_3(buf) buf = _mm_set_epi32(m13,m3,m9,m15)
|
||||
#define LOAD_MSG_9_4(buf) buf = _mm_set_epi32(m0,m12,m14,m11)
|
||||
|
||||
|
||||
#endif
|
229
sse/blake2s-load-sse41.h
Normal file
229
sse/blake2s-load-sse41.h
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2S_LOAD_SSE41_H__
|
||||
#define __BLAKE2S_LOAD_SSE41_H__
|
||||
|
||||
#define LOAD_MSG_0_1(buf) \
|
||||
buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(2,0,2,0)));
|
||||
|
||||
#define LOAD_MSG_0_2(buf) \
|
||||
buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(3,1,3,1)));
|
||||
|
||||
#define LOAD_MSG_0_3(buf) \
|
||||
buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(2,0,2,0)));
|
||||
|
||||
#define LOAD_MSG_0_4(buf) \
|
||||
buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(3,1,3,1)));
|
||||
|
||||
#define LOAD_MSG_1_1(buf) \
|
||||
t0 = _mm_blend_epi16(m1, m2, 0x0C); \
|
||||
t1 = _mm_slli_si128(m3, 4); \
|
||||
t2 = _mm_blend_epi16(t0, t1, 0xF0); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3));
|
||||
|
||||
#define LOAD_MSG_1_2(buf) \
|
||||
t0 = _mm_shuffle_epi32(m2,_MM_SHUFFLE(0,0,2,0)); \
|
||||
t1 = _mm_blend_epi16(m1,m3,0xC0); \
|
||||
t2 = _mm_blend_epi16(t0, t1, 0xF0); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1));
|
||||
|
||||
#define LOAD_MSG_1_3(buf) \
|
||||
t0 = _mm_slli_si128(m1, 4); \
|
||||
t1 = _mm_blend_epi16(m2, t0, 0x30); \
|
||||
t2 = _mm_blend_epi16(m0, t1, 0xF0); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1));
|
||||
|
||||
#define LOAD_MSG_1_4(buf) \
|
||||
t0 = _mm_unpackhi_epi32(m0,m1); \
|
||||
t1 = _mm_slli_si128(m3, 4); \
|
||||
t2 = _mm_blend_epi16(t0, t1, 0x0C); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1));
|
||||
|
||||
#define LOAD_MSG_2_1(buf) \
|
||||
t0 = _mm_unpackhi_epi32(m2,m3); \
|
||||
t1 = _mm_blend_epi16(m3,m1,0x0C); \
|
||||
t2 = _mm_blend_epi16(t0, t1, 0x0F); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2));
|
||||
|
||||
#define LOAD_MSG_2_2(buf) \
|
||||
t0 = _mm_unpacklo_epi32(m2,m0); \
|
||||
t1 = _mm_blend_epi16(t0, m0, 0xF0); \
|
||||
t2 = _mm_slli_si128(m3, 8); \
|
||||
buf = _mm_blend_epi16(t1, t2, 0xC0);
|
||||
|
||||
#define LOAD_MSG_2_3(buf) \
|
||||
t0 = _mm_blend_epi16(m0, m2, 0x3C); \
|
||||
t1 = _mm_srli_si128(m1, 12); \
|
||||
t2 = _mm_blend_epi16(t0,t1,0x03); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,3,2));
|
||||
|
||||
#define LOAD_MSG_2_4(buf) \
|
||||
t0 = _mm_slli_si128(m3, 4); \
|
||||
t1 = _mm_blend_epi16(m0, m1, 0x33); \
|
||||
t2 = _mm_blend_epi16(t1, t0, 0xC0); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(0,1,2,3));
|
||||
|
||||
#define LOAD_MSG_3_1(buf) \
|
||||
t0 = _mm_unpackhi_epi32(m0,m1); \
|
||||
t1 = _mm_unpackhi_epi32(t0, m2); \
|
||||
t2 = _mm_blend_epi16(t1, m3, 0x0C); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2));
|
||||
|
||||
#define LOAD_MSG_3_2(buf) \
|
||||
t0 = _mm_slli_si128(m2, 8); \
|
||||
t1 = _mm_blend_epi16(m3,m0,0x0C); \
|
||||
t2 = _mm_blend_epi16(t1, t0, 0xC0); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3));
|
||||
|
||||
#define LOAD_MSG_3_3(buf) \
|
||||
t0 = _mm_blend_epi16(m0,m1,0x0F); \
|
||||
t1 = _mm_blend_epi16(t0, m3, 0xC0); \
|
||||
buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2));
|
||||
|
||||
#define LOAD_MSG_3_4(buf) \
|
||||
t0 = _mm_unpacklo_epi32(m0,m2); \
|
||||
t1 = _mm_unpackhi_epi32(m1,m2); \
|
||||
buf = _mm_unpacklo_epi64(t1,t0);
|
||||
|
||||
#define LOAD_MSG_4_1(buf) \
|
||||
t0 = _mm_unpacklo_epi64(m1,m2); \
|
||||
t1 = _mm_unpackhi_epi64(m0,m2); \
|
||||
t2 = _mm_blend_epi16(t0,t1,0x33); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3));
|
||||
|
||||
#define LOAD_MSG_4_2(buf) \
|
||||
t0 = _mm_unpackhi_epi64(m1,m3); \
|
||||
t1 = _mm_unpacklo_epi64(m0,m1); \
|
||||
buf = _mm_blend_epi16(t0,t1,0x33);
|
||||
|
||||
#define LOAD_MSG_4_3(buf) \
|
||||
t0 = _mm_unpackhi_epi64(m3,m1); \
|
||||
t1 = _mm_unpackhi_epi64(m2,m0); \
|
||||
buf = _mm_blend_epi16(t1,t0,0x33);
|
||||
|
||||
#define LOAD_MSG_4_4(buf) \
|
||||
t0 = _mm_blend_epi16(m0,m2,0x03); \
|
||||
t1 = _mm_slli_si128(t0, 8); \
|
||||
t2 = _mm_blend_epi16(t1,m3,0x0F); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,0,3));
|
||||
|
||||
#define LOAD_MSG_5_1(buf) \
|
||||
t0 = _mm_unpackhi_epi32(m0,m1); \
|
||||
t1 = _mm_unpacklo_epi32(m0,m2); \
|
||||
buf = _mm_unpacklo_epi64(t0,t1);
|
||||
|
||||
#define LOAD_MSG_5_2(buf) \
|
||||
t0 = _mm_srli_si128(m2, 4); \
|
||||
t1 = _mm_blend_epi16(m0,m3,0x03); \
|
||||
buf = _mm_blend_epi16(t1,t0,0x3C);
|
||||
|
||||
#define LOAD_MSG_5_3(buf) \
|
||||
t0 = _mm_blend_epi16(m1,m0,0x0C); \
|
||||
t1 = _mm_srli_si128(m3, 4); \
|
||||
t2 = _mm_blend_epi16(t0,t1,0x30); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,3,0));
|
||||
|
||||
#define LOAD_MSG_5_4(buf) \
|
||||
t0 = _mm_unpacklo_epi64(m1,m2); \
|
||||
t1= _mm_shuffle_epi32(m3, _MM_SHUFFLE(0,2,0,1)); \
|
||||
buf = _mm_blend_epi16(t0,t1,0x33);
|
||||
|
||||
#define LOAD_MSG_6_1(buf) \
|
||||
t0 = _mm_slli_si128(m1, 12); \
|
||||
t1 = _mm_blend_epi16(m0,m3,0x33); \
|
||||
buf = _mm_blend_epi16(t1,t0,0xC0);
|
||||
|
||||
#define LOAD_MSG_6_2(buf) \
|
||||
t0 = _mm_blend_epi16(m3,m2,0x30); \
|
||||
t1 = _mm_srli_si128(m1, 4); \
|
||||
t2 = _mm_blend_epi16(t0,t1,0x03); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,3,0));
|
||||
|
||||
#define LOAD_MSG_6_3(buf) \
|
||||
t0 = _mm_unpacklo_epi64(m0,m2); \
|
||||
t1 = _mm_srli_si128(m1, 4); \
|
||||
buf = _mm_shuffle_epi32(_mm_blend_epi16(t0,t1,0x0C), _MM_SHUFFLE(2,3,1,0));
|
||||
|
||||
#define LOAD_MSG_6_4(buf) \
|
||||
t0 = _mm_unpackhi_epi32(m1,m2); \
|
||||
t1 = _mm_unpackhi_epi64(m0,t0); \
|
||||
buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2));
|
||||
|
||||
#define LOAD_MSG_7_1(buf) \
|
||||
t0 = _mm_unpackhi_epi32(m0,m1); \
|
||||
t1 = _mm_blend_epi16(t0,m3,0x0F); \
|
||||
buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(2,0,3,1));
|
||||
|
||||
#define LOAD_MSG_7_2(buf) \
|
||||
t0 = _mm_blend_epi16(m2,m3,0x30); \
|
||||
t1 = _mm_srli_si128(m0,4); \
|
||||
t2 = _mm_blend_epi16(t0,t1,0x03); \
|
||||
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,2,3));
|
||||
|
||||
#define LOAD_MSG_7_3(buf) \
|
||||
t0 = _mm_unpackhi_epi64(m0,m3); \
|
||||
t1 = _mm_unpacklo_epi64(m1,m2); \
|
||||
t2 = _mm_blend_epi16(t0,t1,0x3C); \
|
||||
buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,2,3,1));
|
||||
|
||||
#define LOAD_MSG_7_4(buf) \
|
||||
t0 = _mm_unpacklo_epi32(m0,m1); \
|
||||
t1 = _mm_unpackhi_epi32(m1,m2); \
|
||||
buf = _mm_unpacklo_epi64(t0,t1);
|
||||
|
||||
#define LOAD_MSG_8_1(buf) \
|
||||
t0 = _mm_unpackhi_epi32(m1,m3); \
|
||||
t1 = _mm_unpacklo_epi64(t0,m0); \
|
||||
t2 = _mm_blend_epi16(t1,m2,0xC0); \
|
||||
buf = _mm_shufflehi_epi16(t2,_MM_SHUFFLE(1,0,3,2));
|
||||
|
||||
#define LOAD_MSG_8_2(buf) \
|
||||
t0 = _mm_unpackhi_epi32(m0,m3); \
|
||||
t1 = _mm_blend_epi16(m2,t0,0xF0); \
|
||||
buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(0,2,1,3));
|
||||
|
||||
#define LOAD_MSG_8_3(buf) \
|
||||
t0 = _mm_blend_epi16(m2,m0,0x0C); \
|
||||
t1 = _mm_slli_si128(t0,4); \
|
||||
buf = _mm_blend_epi16(t1,m3,0x0F);
|
||||
|
||||
#define LOAD_MSG_8_4(buf) \
|
||||
t0 = _mm_blend_epi16(m1,m0,0x30); \
|
||||
buf = _mm_shuffle_epi32(t0,_MM_SHUFFLE(1,0,3,2));
|
||||
|
||||
#define LOAD_MSG_9_1(buf) \
|
||||
t0 = _mm_blend_epi16(m0,m2,0x03); \
|
||||
t1 = _mm_blend_epi16(m1,m2,0x30); \
|
||||
t2 = _mm_blend_epi16(t1,t0,0x0F); \
|
||||
buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(1,3,0,2));
|
||||
|
||||
#define LOAD_MSG_9_2(buf) \
|
||||
t0 = _mm_slli_si128(m0,4); \
|
||||
t1 = _mm_blend_epi16(m1,t0,0xC0); \
|
||||
buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(1,2,0,3));
|
||||
|
||||
#define LOAD_MSG_9_3(buf) \
|
||||
t0 = _mm_unpackhi_epi32(m0,m3); \
|
||||
t1 = _mm_unpacklo_epi32(m2,m3); \
|
||||
t2 = _mm_unpackhi_epi64(t0,t1); \
|
||||
buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(3,0,2,1));
|
||||
|
||||
#define LOAD_MSG_9_4(buf) \
|
||||
t0 = _mm_blend_epi16(m3,m2,0xC0); \
|
||||
t1 = _mm_unpacklo_epi32(m0,m3); \
|
||||
t2 = _mm_blend_epi16(t0,t1,0x0F); \
|
||||
buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,1,2,3));
|
||||
|
||||
#endif
|
||||
|
189
sse/blake2s-load-xop.h
Normal file
189
sse/blake2s-load-xop.h
Normal file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2S_LOAD_XOP_H__
|
||||
#define __BLAKE2S_LOAD_XOP_H__
|
||||
|
||||
#define TOB(x) ((x)*4*0x01010101 + 0x03020100) // ..or not TOB
|
||||
|
||||
/* Basic VPPERM emulation, for testing purposes */
|
||||
/*static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel)
|
||||
{
|
||||
const __m128i sixteen = _mm_set1_epi8(16);
|
||||
const __m128i t0 = _mm_shuffle_epi8(src1, sel);
|
||||
const __m128i s1 = _mm_shuffle_epi8(src2, _mm_sub_epi8(sel, sixteen));
|
||||
const __m128i mask = _mm_or_si128(_mm_cmpeq_epi8(sel, sixteen),
|
||||
_mm_cmpgt_epi8(sel, sixteen)); // (>=16) = 0xff : 00
|
||||
return _mm_blendv_epi8(t0, s1, mask);
|
||||
}*/
|
||||
|
||||
#define LOAD_MSG_0_1(buf) \
|
||||
buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_0_2(buf) \
|
||||
buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) );
|
||||
|
||||
#define LOAD_MSG_0_3(buf) \
|
||||
buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_0_4(buf) \
|
||||
buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) );
|
||||
|
||||
#define LOAD_MSG_1_1(buf) \
|
||||
t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(5),TOB(0),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) );
|
||||
|
||||
#define LOAD_MSG_1_2(buf) \
|
||||
t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(2),TOB(0),TOB(4),TOB(6)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_1_3(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(0),TOB(0),TOB(1)) ); \
|
||||
buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_1_4(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(7),TOB(2),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) );
|
||||
|
||||
#define LOAD_MSG_2_1(buf) \
|
||||
t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(1),TOB(0),TOB(7)) ); \
|
||||
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(4),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_2_2(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(2),TOB(0),TOB(4)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_2_3(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(7),TOB(3),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) );
|
||||
|
||||
#define LOAD_MSG_2_4(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(1),TOB(6),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) );
|
||||
|
||||
#define LOAD_MSG_3_1(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(3),TOB(7)) ); \
|
||||
t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(1),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_3_2(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(1),TOB(5)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(1),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_3_3(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(5),TOB(2)) ); \
|
||||
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_3_4(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \
|
||||
buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(6),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_4_1(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(5),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(5)) );
|
||||
|
||||
#define LOAD_MSG_4_2(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(7),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_4_3(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(6),TOB(0),TOB(0)) ); \
|
||||
t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) );
|
||||
|
||||
#define LOAD_MSG_4_4(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(4),TOB(0),TOB(1)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(4),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_5_1(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(2)) ); \
|
||||
buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(1),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_5_2(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(6),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) );
|
||||
|
||||
#define LOAD_MSG_5_3(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(0),TOB(7),TOB(4)) ); \
|
||||
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_5_4(buf) \
|
||||
t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(5),TOB(0),TOB(1),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(5)) );
|
||||
|
||||
#define LOAD_MSG_6_1(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(0),TOB(1),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(4)) );
|
||||
|
||||
#define LOAD_MSG_6_2(buf) \
|
||||
t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(6),TOB(0),TOB(0),TOB(1)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(7),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_6_3(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(5),TOB(1),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_6_4(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(3),TOB(7)) ); \
|
||||
buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_7_1(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(0),TOB(7),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(5)) );
|
||||
|
||||
#define LOAD_MSG_7_2(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(5),TOB(1),TOB(0),TOB(7)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_7_3(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(2),TOB(0),TOB(0),TOB(5)) ); \
|
||||
t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_7_4(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(6),TOB(4),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_8_1(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \
|
||||
t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) );
|
||||
|
||||
#define LOAD_MSG_8_2(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(4),TOB(3),TOB(5),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(7)) );
|
||||
|
||||
#define LOAD_MSG_8_3(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(6),TOB(1),TOB(0),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(5),TOB(4)) ); \
|
||||
|
||||
#define LOAD_MSG_8_4(buf) \
|
||||
buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(4),TOB(7),TOB(2)) );
|
||||
|
||||
#define LOAD_MSG_9_1(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(7),TOB(0),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(4),TOB(6)) );
|
||||
|
||||
#define LOAD_MSG_9_2(buf) \
|
||||
buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(6),TOB(4),TOB(2)) );
|
||||
|
||||
#define LOAD_MSG_9_3(buf) \
|
||||
t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(3),TOB(5),TOB(0)) ); \
|
||||
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(7)) );
|
||||
|
||||
#define LOAD_MSG_9_4(buf) \
|
||||
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(7)) ); \
|
||||
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(6),TOB(0)) );
|
||||
|
||||
#endif
|
||||
|
91
sse/blake2s-round.h
Normal file
91
sse/blake2s-round.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2S_ROUND_H__
|
||||
#define __BLAKE2S_ROUND_H__
|
||||
|
||||
#define LOAD(p) _mm_load_si128( (__m128i *)(p) )
|
||||
#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)
|
||||
|
||||
#define LOADU(p) _mm_loadu_si128( (__m128i *)(p) )
|
||||
#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r)
|
||||
|
||||
#define TOF(reg) _mm_castsi128_ps((reg))
|
||||
#define TOI(reg) _mm_castps_si128((reg))
|
||||
|
||||
#define LIKELY(x) __builtin_expect((x),1)
|
||||
|
||||
|
||||
/* Microarchitecture-specific macros */
|
||||
#ifndef HAVE_XOP
|
||||
#ifdef HAVE_SSSE3
|
||||
#define _mm_roti_epi32(r, c) ( \
|
||||
(8==-(c)) ? _mm_shuffle_epi8(r,r8) \
|
||||
: (16==-(c)) ? _mm_shuffle_epi8(r,r16) \
|
||||
: _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) )
|
||||
#else
|
||||
#define _mm_roti_epi32(r, c) _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-c) ))
|
||||
#endif
|
||||
#else
|
||||
/* ... */
|
||||
#endif
|
||||
|
||||
|
||||
#define G1(row1,row2,row3,row4,buf) \
|
||||
row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \
|
||||
row4 = _mm_xor_si128( row4, row1 ); \
|
||||
row4 = _mm_roti_epi32(row4, -16); \
|
||||
row3 = _mm_add_epi32( row3, row4 ); \
|
||||
row2 = _mm_xor_si128( row2, row3 ); \
|
||||
row2 = _mm_roti_epi32(row2, -12);
|
||||
|
||||
#define G2(row1,row2,row3,row4,buf) \
|
||||
row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \
|
||||
row4 = _mm_xor_si128( row4, row1 ); \
|
||||
row4 = _mm_roti_epi32(row4, -8); \
|
||||
row3 = _mm_add_epi32( row3, row4 ); \
|
||||
row2 = _mm_xor_si128( row2, row3 ); \
|
||||
row2 = _mm_roti_epi32(row2, -7);
|
||||
|
||||
#define DIAGONALIZE(row1,row2,row3,row4) \
|
||||
row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(2,1,0,3) ); \
|
||||
row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \
|
||||
row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(0,3,2,1) );
|
||||
|
||||
#define UNDIAGONALIZE(row1,row2,row3,row4) \
|
||||
row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(0,3,2,1) ); \
|
||||
row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \
|
||||
row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(2,1,0,3) );
|
||||
|
||||
#if defined(HAVE_XOP)
|
||||
#include "blake2s-load-xop.h"
|
||||
#elif defined(HAVE_SSE41)
|
||||
#include "blake2s-load-sse41.h"
|
||||
#else
|
||||
#include "blake2s-load-sse2.h"
|
||||
#endif
|
||||
|
||||
#define ROUND(r) \
|
||||
LOAD_MSG_ ##r ##_1(buf1); \
|
||||
G1(row1,row2,row3,row4,buf1); \
|
||||
LOAD_MSG_ ##r ##_2(buf2); \
|
||||
G2(row1,row2,row3,row4,buf2); \
|
||||
DIAGONALIZE(row1,row2,row3,row4); \
|
||||
LOAD_MSG_ ##r ##_3(buf3); \
|
||||
G1(row1,row2,row3,row4,buf3); \
|
||||
LOAD_MSG_ ##r ##_4(buf4); \
|
||||
G2(row1,row2,row3,row4,buf4); \
|
||||
UNDIAGONALIZE(row1,row2,row3,row4); \
|
||||
|
||||
#endif
|
||||
|
416
sse/blake2s.c
Normal file
416
sse/blake2s.c
Normal file
@ -0,0 +1,416 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "blake2.h"
|
||||
#include "blake2-impl.h"
|
||||
|
||||
#include "blake2-config.h"
|
||||
|
||||
|
||||
#include <emmintrin.h>
|
||||
#if defined(HAVE_SSSE3)
|
||||
#include <tmmintrin.h>
|
||||
#endif
|
||||
#if defined(HAVE_SSE41)
|
||||
#include <smmintrin.h>
|
||||
#endif
|
||||
#if defined(HAVE_AVX)
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#if defined(HAVE_XOP)
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#include "blake2s-round.h"
|
||||
|
||||
ALIGN( 64 ) static const uint32_t blake2s_IV[8] =
|
||||
{
|
||||
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
|
||||
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
|
||||
};
|
||||
|
||||
static const uint8_t blake2s_sigma[10][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||
};
|
||||
|
||||
|
||||
/* Some helper functions, not necessarily useful */
|
||||
static inline int blake2s_set_lastnode( blake2s_state *S )
|
||||
{
|
||||
S->f[1] = ~0U;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_clear_lastnode( blake2s_state *S )
|
||||
{
|
||||
S->f[1] = 0U;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_set_lastblock( blake2s_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2s_set_lastnode( S );
|
||||
|
||||
S->f[0] = ~0U;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_clear_lastblock( blake2s_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2s_clear_lastnode( S );
|
||||
|
||||
S->f[0] = 0U;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
|
||||
{
|
||||
uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0];
|
||||
t += inc;
|
||||
S->t[0] = ( uint32_t )( t >> 0 );
|
||||
S->t[1] = ( uint32_t )( t >> 32 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Parameter-related functions
|
||||
static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
|
||||
{
|
||||
P->digest_length = digest_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
|
||||
{
|
||||
P->fanout = fanout;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
|
||||
{
|
||||
P->depth = depth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
|
||||
{
|
||||
P->leaf_length = leaf_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
|
||||
{
|
||||
store48( P->node_offset, node_offset );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
|
||||
{
|
||||
P->node_depth = node_depth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
|
||||
{
|
||||
P->inner_length = inner_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
|
||||
{
|
||||
memcpy( P->salt, salt, BLAKE2S_SALTBYTES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
|
||||
{
|
||||
memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2s_init0( blake2s_state *S )
|
||||
{
|
||||
memset( S, 0, sizeof( blake2s_state ) );
|
||||
|
||||
for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* init2 xors IV with input parameter block */
|
||||
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
|
||||
{
|
||||
uint8_t *p, *h, *v;
|
||||
//blake2s_init0( S );
|
||||
v = ( uint8_t * )( blake2s_IV );
|
||||
h = ( uint8_t * )( S->h );
|
||||
p = ( uint8_t * )( P );
|
||||
/* IV XOR ParamBlock */
|
||||
memset( S, 0, sizeof( blake2s_state ) );
|
||||
|
||||
for( int i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Some sort of default parameter block initialization, for sequential blake2s */
|
||||
int blake2s_init( blake2s_state *S, const uint8_t outlen )
|
||||
{
|
||||
/* Move interval verification here? */
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
||||
|
||||
const blake2s_param P =
|
||||
{
|
||||
outlen,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
{0},
|
||||
0,
|
||||
0,
|
||||
{0},
|
||||
{0}
|
||||
};
|
||||
return blake2s_init_param( S, &P );
|
||||
}
|
||||
|
||||
|
||||
int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
|
||||
{
|
||||
/* Move interval verification here? */
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
||||
|
||||
if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||
|
||||
const blake2s_param P =
|
||||
{
|
||||
outlen,
|
||||
keylen,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
{0},
|
||||
0,
|
||||
0,
|
||||
{0},
|
||||
{0}
|
||||
};
|
||||
|
||||
if( blake2s_init_param( S, &P ) < 0 )
|
||||
return -1;
|
||||
|
||||
{
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
|
||||
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )
|
||||
{
|
||||
__m128i row1, row2, row3, row4;
|
||||
__m128i buf1, buf2, buf3, buf4;
|
||||
#if defined(HAVE_SSE41)
|
||||
__m128i t0, t1;
|
||||
#if !defined(HAVE_XOP)
|
||||
__m128i t2;
|
||||
#endif
|
||||
#endif
|
||||
__m128i ff0, ff1;
|
||||
#if defined(HAVE_SSSE3) && !defined(HAVE_XOP)
|
||||
const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 );
|
||||
const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 );
|
||||
#endif
|
||||
#if defined(HAVE_SSE41)
|
||||
const __m128i m0 = LOADU( block + 00 );
|
||||
const __m128i m1 = LOADU( block + 16 );
|
||||
const __m128i m2 = LOADU( block + 32 );
|
||||
const __m128i m3 = LOADU( block + 48 );
|
||||
#else
|
||||
const uint32_t m0 = ( ( uint32_t * )block )[ 0];
|
||||
const uint32_t m1 = ( ( uint32_t * )block )[ 1];
|
||||
const uint32_t m2 = ( ( uint32_t * )block )[ 2];
|
||||
const uint32_t m3 = ( ( uint32_t * )block )[ 3];
|
||||
const uint32_t m4 = ( ( uint32_t * )block )[ 4];
|
||||
const uint32_t m5 = ( ( uint32_t * )block )[ 5];
|
||||
const uint32_t m6 = ( ( uint32_t * )block )[ 6];
|
||||
const uint32_t m7 = ( ( uint32_t * )block )[ 7];
|
||||
const uint32_t m8 = ( ( uint32_t * )block )[ 8];
|
||||
const uint32_t m9 = ( ( uint32_t * )block )[ 9];
|
||||
const uint32_t m10 = ( ( uint32_t * )block )[10];
|
||||
const uint32_t m11 = ( ( uint32_t * )block )[11];
|
||||
const uint32_t m12 = ( ( uint32_t * )block )[12];
|
||||
const uint32_t m13 = ( ( uint32_t * )block )[13];
|
||||
const uint32_t m14 = ( ( uint32_t * )block )[14];
|
||||
const uint32_t m15 = ( ( uint32_t * )block )[15];
|
||||
#endif
|
||||
row1 = ff0 = LOAD( &S->h[0] );
|
||||
row2 = ff1 = LOAD( &S->h[4] );
|
||||
row3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A );
|
||||
row4 = _mm_xor_si128( _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ), LOAD( &S->t[0] ) );
|
||||
ROUND( 0 );
|
||||
ROUND( 1 );
|
||||
ROUND( 2 );
|
||||
ROUND( 3 );
|
||||
ROUND( 4 );
|
||||
ROUND( 5 );
|
||||
ROUND( 6 );
|
||||
ROUND( 7 );
|
||||
ROUND( 8 );
|
||||
ROUND( 9 );
|
||||
STORE( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row1, row3 ) ) );
|
||||
STORE( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row2, row4 ) ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* inlen now in bytes */
|
||||
int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen )
|
||||
{
|
||||
while( inlen > 0 )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
|
||||
|
||||
if( inlen > fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill ); // Fill buffer
|
||||
S->buflen += fill;
|
||||
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||
blake2s_compress( S, S->buf ); // Compress
|
||||
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left
|
||||
S->buflen -= BLAKE2S_BLOCKBYTES;
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
}
|
||||
else // inlen <= fill
|
||||
{
|
||||
memcpy( S->buf + left, in, inlen );
|
||||
S->buflen += inlen; // Be lazy, do not compress
|
||||
in += inlen;
|
||||
inlen -= inlen;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Is this correct? */
|
||||
int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen )
|
||||
{
|
||||
uint8_t buffer[BLAKE2S_OUTBYTES];
|
||||
|
||||
if( S->buflen > BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||
blake2s_compress( S, S->buf );
|
||||
S->buflen -= BLAKE2S_BLOCKBYTES;
|
||||
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
|
||||
}
|
||||
|
||||
blake2s_increment_counter( S, ( uint32_t )S->buflen );
|
||||
blake2s_set_lastblock( S );
|
||||
memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
|
||||
blake2s_compress( S, S->buf );
|
||||
|
||||
for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
|
||||
store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
|
||||
|
||||
memcpy( out, buffer, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* inlen, at least, should be uint64_t. Others can be size_t. */
|
||||
int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
blake2s_state S[1];
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if ( NULL == key ) keylen = 0; /* Fail here instead if keylen != 0 and key == NULL? */
|
||||
|
||||
if( keylen > 0 )
|
||||
{
|
||||
if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( blake2s_init( S, outlen ) < 0 ) return -1;
|
||||
}
|
||||
|
||||
blake2s_update( S, ( uint8_t * )in, inlen );
|
||||
blake2s_final( S, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(SUPERCOP)
|
||||
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
|
||||
{
|
||||
return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, inlen, 0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BLAKE2S_SELFTEST)
|
||||
#include <string.h>
|
||||
#include "blake2-kat.h"
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
uint8_t key[BLAKE2S_KEYBYTES];
|
||||
uint8_t buf[KAT_LENGTH];
|
||||
|
||||
for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i )
|
||||
key[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
buf[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
{
|
||||
uint8_t hash[BLAKE2S_OUTBYTES];
|
||||
|
||||
if( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 ||
|
||||
0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
|
||||
{
|
||||
puts( "error" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
puts( "ok" );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
291
sse/blake2sp.c
Normal file
291
sse/blake2sp.c
Normal file
@ -0,0 +1,291 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - optimized C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
#include "blake2.h"
|
||||
#include "blake2-impl.h"
|
||||
|
||||
#define PARALLELISM_DEGREE 8
|
||||
|
||||
static inline int blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
P->digest_length = outlen;
|
||||
P->key_length = keylen;
|
||||
P->fanout = PARALLELISM_DEGREE;
|
||||
P->depth = 2;
|
||||
P->leaf_length = 0;
|
||||
store48( P->node_offset, offset );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = outlen;
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2s_init_param( S, P );
|
||||
}
|
||||
|
||||
static inline int blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
P->digest_length = outlen;
|
||||
P->key_length = keylen;
|
||||
P->fanout = PARALLELISM_DEGREE;
|
||||
P->depth = 2;
|
||||
P->leaf_length = 0;
|
||||
store48( P->node_offset, 0ULL );
|
||||
P->node_depth = 1;
|
||||
P->inner_length = outlen;
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2s_init_param( S, P );
|
||||
}
|
||||
|
||||
|
||||
int blake2sp_init( blake2sp_state *S, const uint8_t outlen )
|
||||
{
|
||||
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
|
||||
if( blake2sp_init_root( S->R, outlen, 0 ) < 0 )
|
||||
return -1;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2sp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1;
|
||||
|
||||
S->R->last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
|
||||
{
|
||||
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||
|
||||
if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
|
||||
if( blake2sp_init_root( S->R, outlen, keylen ) < 0 )
|
||||
return -1;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2sp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1;
|
||||
|
||||
S->R->last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||
{
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = sizeof( S->buf ) - left;
|
||||
|
||||
if( left && inlen >= fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE)
|
||||
#else
|
||||
|
||||
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
|
||||
#endif
|
||||
{
|
||||
#if defined(_OPENMP)
|
||||
size_t id__ = omp_get_thread_num();
|
||||
#endif
|
||||
uint64_t inlen__ = inlen;
|
||||
const uint8_t *in__ = ( const uint8_t * )in;
|
||||
in__ += id__ * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
blake2s_update( S->S[id__], in__, BLAKE2S_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
|
||||
in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );
|
||||
inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
if( inlen > 0 )
|
||||
memcpy( S->buf + left, in, inlen );
|
||||
|
||||
S->buflen = left + inlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2sp_final( blake2sp_state *S, uint8_t *out, const uint8_t outlen )
|
||||
{
|
||||
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
{
|
||||
if( S->buflen > i * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;
|
||||
|
||||
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );
|
||||
}
|
||||
|
||||
blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES );
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );
|
||||
|
||||
blake2s_final( S->R, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2sp( uint8_t *out, const void *in, const void *key, uint8_t outlen, uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
|
||||
blake2s_state S[PARALLELISM_DEGREE][1];
|
||||
blake2s_state FS[1];
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if ( NULL == key ) keylen = 0;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2sp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1;
|
||||
|
||||
S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node
|
||||
|
||||
if( keylen > 0 )
|
||||
{
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)
|
||||
#else
|
||||
|
||||
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
|
||||
#endif
|
||||
{
|
||||
#if defined(_OPENMP)
|
||||
size_t id__ = omp_get_thread_num();
|
||||
#endif
|
||||
uint64_t inlen__ = inlen;
|
||||
const uint8_t *in__ = ( const uint8_t * )in;
|
||||
in__ += id__ * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
}
|
||||
|
||||
if( inlen__ > id__ * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES;
|
||||
const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;
|
||||
blake2s_update( S[id__], in__, len );
|
||||
}
|
||||
|
||||
blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES );
|
||||
}
|
||||
|
||||
if( blake2sp_init_root( FS, outlen, keylen ) < 0 )
|
||||
return -1;
|
||||
|
||||
FS->last_node = 1;
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );
|
||||
|
||||
blake2s_final( FS, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(BLAKE2SP_SELFTEST)
|
||||
#include <string.h>
|
||||
#include "blake2-kat.h"
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
uint8_t key[BLAKE2S_KEYBYTES];
|
||||
uint8_t buf[KAT_LENGTH];
|
||||
|
||||
for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i )
|
||||
key[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
buf[i] = ( uint8_t )i;
|
||||
|
||||
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
||||
{
|
||||
uint8_t hash[BLAKE2S_OUTBYTES];
|
||||
blake2sp( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES );
|
||||
|
||||
if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) )
|
||||
{
|
||||
puts( "error" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
puts( "ok" );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
19
sse/makefile
Normal file
19
sse/makefile
Normal file
@ -0,0 +1,19 @@
|
||||
CC=gcc
|
||||
CFLAGS=-std=c99 -Wall -pedantic -O3 -march=native
|
||||
|
||||
all: blake2s blake2b blake2sp blake2bp
|
||||
|
||||
blake2s: blake2s.c
|
||||
$(CC) blake2s.c -o $@ $(CFLAGS) -DBLAKE2S_SELFTEST
|
||||
|
||||
blake2b: blake2b.c
|
||||
$(CC) blake2b.c -o $@ $(CFLAGS) -DBLAKE2B_SELFTEST
|
||||
|
||||
blake2sp: blake2sp.c blake2s.c
|
||||
$(CC) blake2sp.c blake2s.c -o $@ $(CFLAGS) -DBLAKE2SP_SELFTEST
|
||||
|
||||
blake2bp: blake2bp.c blake2b.c
|
||||
$(CC) blake2bp.c blake2b.c -o $@ $(CFLAGS) -DBLAKE2BP_SELFTEST
|
||||
|
||||
clean:
|
||||
rm -rf *.o blake2s blake2b blake2sp blake2bp
|
Loading…
Reference in New Issue
Block a user