mirror of
https://github.com/albertobsd/keyhunt.git
synced 2025-09-18 11:51:24 +02:00
Added mode rmd160, and param -l to seach exclusive compress or uncompress address/hash or bot (default behaivor)
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
#Version 0.1.20210311 K*BSGS
|
||||
- Added mode rmd160, this method works two times faster than Address method. This mode can search all the altcoins
|
||||
|
||||
|
||||
#Version 0.1.20210311 K*BSGS
|
||||
- Solved some bug when the publickeys in the input file was invalid but the program keeps running with 0 publickeys
|
||||
- Now publickeys can be compressed, not only uncompressed
|
||||
|
2
Makefile
2
Makefile
@@ -4,9 +4,11 @@ default:
|
||||
gcc -O3 -c sha256/sha256.c -o sha256.o
|
||||
gcc -O3 -c base58/base58.c -o base58.o
|
||||
gcc -O3 -c rmd160/rmd160.c -o rmd160.o
|
||||
gcc -O3 -c sha3/sha3.c -o sha3.o
|
||||
gcc -O3 -c keyhunt.c -o keyhunt.o -lm
|
||||
gcc -o keyhunt keyhunt.o base58.o rmd160.o sha256.o bloom.o murmurhash2.o -lgmp -lm -lpthread
|
||||
gcc -O3 hexcharstoraw.c -o hexcharstoraw -lm
|
||||
gcc -o bPfile bPfile.c -lgmp -lm
|
||||
clean:
|
||||
rm -r *.o
|
||||
|
||||
|
10
TODO.md
10
TODO.md
@@ -1,17 +1,13 @@
|
||||
#TODO
|
||||
- Implement libkeccak at https://github.com/maandree/libkeccak
|
||||
This is the only library that implement legacy keccak funtion (NOT SHA3)
|
||||
See https://medium.com/@ConsenSys/are-you-really-using-sha-3-or-old-code-c5df31ad2b0 as reference
|
||||
- GPU support
|
||||
- Optimize Point Addition, maybe with a custom bignumber lib instead libgmp
|
||||
- Fix a minor bug in Partition process of Introsort
|
||||
fixing this will half the time of sorting data
|
||||
- Make a test files for All cases of input data with fixed ranges of search
|
||||
- address BTC legacy, bech32, ETH
|
||||
- xpoint hexchars and binary
|
||||
|
||||
|
||||
#DONE
|
||||
- Added sha3 same files used by brainflayer
|
||||
- Added mode rmd160
|
||||
- Fixed the bug in Partition process of Introsort
|
||||
- Fixed Quicksort edges cases (All data already sorted)
|
||||
To fix it Introsort was inmplement
|
||||
- Fixed bottleneck of Point - Scalar multiplication
|
||||
|
543
keyhunt.c
543
keyhunt.c
@@ -16,6 +16,7 @@ email: alberto.bsd@gmail.com
|
||||
#include "rmd160/rmd160.h"
|
||||
#include "sha256/sha256.h"
|
||||
#include "bloom/bloom.h"
|
||||
#include "sha3/sha3.h"
|
||||
#include "util.h"
|
||||
|
||||
#define CRYPTO_NONE 0
|
||||
@@ -26,6 +27,12 @@ email: alberto.bsd@gmail.com
|
||||
#define MODE_XPOINT 0
|
||||
#define MODE_ADDRESS 1
|
||||
#define MODE_BSGS 2
|
||||
#define MODE_RMD160 3
|
||||
|
||||
#define SEARCH_UNCOMPRESS 0
|
||||
#define SEARCH_COMPRESS 1
|
||||
#define SEARCH_BOTH 2
|
||||
|
||||
|
||||
struct Point {
|
||||
mpz_t x;
|
||||
@@ -48,7 +55,7 @@ struct tothread {
|
||||
char *rpt; //rng per thread
|
||||
};
|
||||
|
||||
const char *version = "0.1.20210311 K*BSGS";
|
||||
const char *version = "0.1.20210318 K*BSGS";
|
||||
const char *EC_constant_N = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141";
|
||||
const char *EC_constant_P = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f";
|
||||
const char *EC_constant_Gx = "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798";
|
||||
@@ -86,6 +93,7 @@ void *thread_process_bsgs(void *vargp);
|
||||
void *thread_process_bsgs_random(void *vargp);
|
||||
|
||||
void init_doublingG(struct Point *P);
|
||||
char *publickeytohashrmd160(char *pkey,int length);
|
||||
char *pubkeytopubaddress(char *pkey,int length);
|
||||
//char *pubkeytopubaddress_eth(char *pkey,int length);
|
||||
|
||||
@@ -93,10 +101,11 @@ char *pubkeytopubaddress(char *pkey,int length);
|
||||
char *bit_range_str_min;
|
||||
char *bit_range_str_max;
|
||||
|
||||
const char *modes[3] = {"xpoint","address","bsgs"};
|
||||
const char *modes[4] = {"xpoint","address","bsgs","rmd160"};
|
||||
const char *cryptos[3] = {"btc","eth","all"};
|
||||
const char *publicsearch[3] = {"compress","uncompress","both"};
|
||||
const char *default_filename = "addresses.txt";
|
||||
const char *minus_params[2] = {"quiet","help"};
|
||||
//const char *minus_params[2] = {"quiet","help"};
|
||||
|
||||
pthread_t *tid = NULL;
|
||||
pthread_mutex_t write_keys;
|
||||
@@ -122,6 +131,7 @@ int KFACTOR = 1;
|
||||
int MAXLENGTHADDRESS = -1;
|
||||
int NTHREADS = 1;
|
||||
int OUTPUTSECONDS = 30;
|
||||
int FLAGSEARCH = 2;
|
||||
int FLAGBITRANGE = 0;
|
||||
int FLAGRANGE = 0;
|
||||
int FLAGFILE = 0;
|
||||
@@ -186,9 +196,8 @@ int main(int argc, char **argv) {
|
||||
uint64_t i;
|
||||
int64_t j;
|
||||
int readed,s,continue_flag,check_flag,r,lenaux,lendiff;
|
||||
|
||||
mpz_t total,pretotal,debugcount_mpz,Ysquared,mpz_aux,mpz_aux2;
|
||||
|
||||
clock_t c_beging,c_ending;
|
||||
uint32_t seconds = 0;
|
||||
|
||||
int c;
|
||||
@@ -203,7 +212,7 @@ int main(int argc, char **argv) {
|
||||
mpz_init_set_ui(TWO,2);
|
||||
mpz_init(MPZAUX);
|
||||
|
||||
while ((c = getopt(argc, argv, "ehqRwb:c:f:g:k:m:n:p:r:s:t:v:-:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "ehqRwb:c:f:g:k:l:m:n:p:r:s:t:v:-:")) != -1) {
|
||||
switch(c) {
|
||||
case 'h':
|
||||
printf("\nUsage:\n-h\t\tshow this help\n");
|
||||
@@ -211,19 +220,19 @@ int main(int argc, char **argv) {
|
||||
printf("-b bits\t\tFor some puzzles you only need some numbers of bits in the test keys.\n");
|
||||
printf("\t\tThis option only is valid with the Random option -R\n");
|
||||
printf("-c crypto\tSearch for specific crypo. < btc, eth, all > valid only w/ -m address \n");
|
||||
printf("\t\teth option is under develop sorry :(\n");
|
||||
printf("-e\t\tThe file is already Sorted descendent. This skip the sorting process.\n");
|
||||
printf("\t\tYour file MUST be sordted if no you are going to lose collisions\n");
|
||||
printf("-f file\t\tSpecify filename with addresses or xpoints or uncompressed public keys\n");
|
||||
printf("-g count\tJust for the stats, mark as counted every debugcount keys \n");
|
||||
printf("-k value\tUse this with bsgs mode, k value is factor for M, more speed but more RAM use wisely\n");
|
||||
printf("-m mode\t\tmode of search for cryptos. < address, xpoint, bsgs > default: address (more slow)\n");
|
||||
printf("-l look\tWhat type of address/hash160 are you looking for < compress , uncompress , both>\n");
|
||||
printf("-m mode\t\tmode of search for cryptos. ( bsgs , xpoint , rmd160 , address ) default: address (more slow)\n");
|
||||
printf("-n uptoN\tCheck for N secuential numbers before the random chossen this only work with -R option\n");
|
||||
printf("\t\tUse -n to set the N for the BSGS process. Bigger N more RAM needed\n");
|
||||
printf("-p file\t\tfile is a binary raw file with the bP points precalculated. Just work with -m bsgs\n");
|
||||
printf("-q\t\tset quiet the thread output\n");
|
||||
printf("-r SR:EN\tStarRange:EndRange, the end range can be omited for search from start range to N-1 ECC value\n");
|
||||
printf("-R\t\tRandom/Secuential this is the default behaivor, can't use this with range option -r\n");
|
||||
printf("-R\t\tRandom this is the default behaivor\n");
|
||||
printf("-s ns\t\tNumber of seconds for the stats output, 0 to omit output.\n");
|
||||
printf("-t tn\t\tThreads number, must be positive integer\n");
|
||||
printf("-v va\t\tSearch for vanity Address, only with -m address\n");
|
||||
@@ -303,8 +312,25 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
printf("[+] Setting k factor to %i\n",KFACTOR);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
switch(indexOf(optarg,publicsearch,3)) {
|
||||
case SEARCH_UNCOMPRESS:
|
||||
FLAGSEARCH = SEARCH_UNCOMPRESS;
|
||||
printf("[+] Search uncompress only\n");
|
||||
break;
|
||||
case SEARCH_COMPRESS:
|
||||
FLAGSEARCH = SEARCH_COMPRESS;
|
||||
printf("[+] Search compress only\n");
|
||||
break;
|
||||
case SEARCH_BOTH:
|
||||
FLAGSEARCH = SEARCH_BOTH;
|
||||
printf("[+] Search both compress and uncompress\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
switch(indexOf(optarg,modes,3)) {
|
||||
switch(indexOf(optarg,modes,4)) {
|
||||
case MODE_XPOINT: //xpoint
|
||||
FLAGMODE = MODE_XPOINT;
|
||||
printf("[+] Setting mode xpoint\n");
|
||||
@@ -317,6 +343,10 @@ int main(int argc, char **argv) {
|
||||
FLAGMODE = MODE_BSGS;
|
||||
printf("[+] Setting mode BSGS\n");
|
||||
break;
|
||||
case MODE_RMD160:
|
||||
FLAGMODE = MODE_RMD160;
|
||||
printf("[+] Setting mode rmd160\n");
|
||||
break;
|
||||
default:
|
||||
FLAGMODE = MODE_ADDRESS;
|
||||
fprintf(stderr,"[+] Unknow mode value %s.\n",optarg);
|
||||
@@ -344,8 +374,7 @@ int main(int argc, char **argv) {
|
||||
printf("[+] Setting random mode.\n");
|
||||
break;
|
||||
case 'r':
|
||||
if(optarg != NULL) {
|
||||
stringtokenizer(optarg,&t);
|
||||
if(optarg != NULL) { stringtokenizer(optarg,&t);
|
||||
switch(t.n) {
|
||||
case 1:
|
||||
range_start = nextToken(&t);
|
||||
@@ -407,6 +436,7 @@ int main(int argc, char **argv) {
|
||||
printf("[+] Data marked as RAW\n");
|
||||
FLAGRAWDATA = 1;
|
||||
break;
|
||||
/*
|
||||
case '-':
|
||||
switch(indexOf(optarg,minus_params,2)) {
|
||||
case 0: //--quiet
|
||||
@@ -420,6 +450,7 @@ int main(int argc, char **argv) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
printf("[E] Unknow opcion %c\n",c);
|
||||
break;
|
||||
@@ -477,25 +508,14 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
N =0;
|
||||
if(FLAGMODE != MODE_BSGS) {
|
||||
if(FLAGRAWDATA) {
|
||||
aux = malloc(32);
|
||||
if(aux == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
}
|
||||
while(!feof(fd)) {
|
||||
if(fread(aux,1,32,fd) == 32) {
|
||||
N++;
|
||||
}
|
||||
}
|
||||
free(aux);
|
||||
}
|
||||
else {
|
||||
aux = malloc(1000);
|
||||
if(aux == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
}
|
||||
switch(FLAGMODE) {
|
||||
case MODE_ADDRESS:
|
||||
while(!feof(fd)) {
|
||||
hextemp = fgets(aux,1000,fd);
|
||||
hextemp = fgets(aux,998,fd);
|
||||
if(hextemp == aux) {
|
||||
trim(aux," \t\n\r");
|
||||
r = strlen(aux);
|
||||
@@ -507,14 +527,61 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
}
|
||||
MAXLENGTHADDRESS = 32;
|
||||
break;
|
||||
case MODE_RMD160:
|
||||
if(FLAGRAWDATA) {
|
||||
while(!feof(fd)) {
|
||||
if(fread(aux,1,20,fd) == 20) {
|
||||
N++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(!feof(fd)) {
|
||||
hextemp = fgets(aux,998,fd);
|
||||
if(hextemp == aux) {
|
||||
trim(aux," \t\n\r");
|
||||
r = strlen(aux);
|
||||
if(r == 40) { //Any length for invalid Address?
|
||||
N++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MAXLENGTHADDRESS = 20;
|
||||
break;
|
||||
case MODE_XPOINT:
|
||||
if(FLAGRAWDATA) {
|
||||
while(!feof(fd)) {
|
||||
if(fread(aux,1,32,fd) == 32) {
|
||||
N++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(!feof(fd)) {
|
||||
hextemp = fgets(aux,998,fd);
|
||||
if(hextemp == aux) {
|
||||
trim(aux," \t\n\r");
|
||||
r = strlen(aux);
|
||||
if(r > 10) { //Any length for invalid Address?
|
||||
N++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MAXLENGTHADDRESS = 32;
|
||||
break;
|
||||
}
|
||||
free(aux);
|
||||
if(N == 0) {
|
||||
fprintf(stderr,"[E] There is no valid data in the file\n");
|
||||
exit(0);
|
||||
}
|
||||
fseek(fd,0,SEEK_SET);
|
||||
if(FLAGMODE == 0 || FLAGRAWDATA) {
|
||||
MAXLENGTHADDRESS = 32;
|
||||
}
|
||||
|
||||
printf("[+] Allocating memory for %u elements\n",N);
|
||||
printf("[+] Allocating memory for %u elements: %.2f MB\n",N,(MAXLENGTHADDRESS*N)/1048576);
|
||||
i = 0;
|
||||
do {
|
||||
DATABUFFER = malloc(MAXLENGTHADDRESS*N);
|
||||
@@ -540,7 +607,8 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
printf("[+] Loading data to the bloomfilter\n");
|
||||
i = 0;
|
||||
if(FLAGMODE == MODE_ADDRESS) { //Address
|
||||
switch (FLAGMODE) {
|
||||
case MODE_ADDRESS:
|
||||
aux = malloc(2*MAXLENGTHADDRESS);
|
||||
if(aux == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
@@ -561,8 +629,8 @@ int main(int argc, char **argv) {
|
||||
fprintf(stderr,"[E] Omiting line : %s\n",aux);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(FLAGMODE == MODE_XPOINT) {
|
||||
break;
|
||||
case MODE_XPOINT:
|
||||
if(FLAGRAWDATA) {
|
||||
aux = malloc(MAXLENGTHADDRESS);
|
||||
if(aux == NULL) {
|
||||
@@ -586,10 +654,11 @@ int main(int argc, char **argv) {
|
||||
while(i < N) {
|
||||
memset(aux,0,3*MAXLENGTHADDRESS);
|
||||
hextemp = fgets(aux,3*MAXLENGTHADDRESS,fd);
|
||||
memset(DATABUFFER + (i*MAXLENGTHADDRESS),0,MAXLENGTHADDRESS);
|
||||
if(hextemp == aux) {
|
||||
trim(aux," \t\n\r");
|
||||
lenaux = strlen(aux);
|
||||
memset(DATABUFFER + (i*MAXLENGTHADDRESS),0,MAXLENGTHADDRESS);
|
||||
|
||||
if(isValidHex(aux)) {
|
||||
if(lenaux <= 64) {
|
||||
if(lenaux < 64) {
|
||||
@@ -614,14 +683,69 @@ int main(int argc, char **argv) {
|
||||
else {
|
||||
fprintf(stderr,"[E] Ignoring invalid hexvalue %s\n",aux);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,"[E] Omiting line : %s\n",aux);
|
||||
N--;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MODE_RMD160:
|
||||
if(FLAGRAWDATA) {
|
||||
aux = malloc(MAXLENGTHADDRESS);
|
||||
if(aux == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
exit(0);
|
||||
}
|
||||
while(i < N) {
|
||||
if(fread(aux,1,MAXLENGTHADDRESS,fd) == 20) {
|
||||
memcpy(DATABUFFER + (i*MAXLENGTHADDRESS),aux,MAXLENGTHADDRESS);
|
||||
bloom_add(&bloom, aux,MAXLENGTHADDRESS);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aux = malloc(3*MAXLENGTHADDRESS);
|
||||
if(aux == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
exit(0);
|
||||
}
|
||||
while(i < N) {
|
||||
memset(aux,0,3*MAXLENGTHADDRESS);
|
||||
hextemp = fgets(aux,3*MAXLENGTHADDRESS,fd);
|
||||
memset(DATABUFFER + (i*MAXLENGTHADDRESS),0,MAXLENGTHADDRESS);
|
||||
if(hextemp == aux) {
|
||||
trim(aux," \t\n\r");
|
||||
lenaux = strlen(aux);
|
||||
if(isValidHex(aux)) {
|
||||
if(lenaux == 40) {
|
||||
if(hexs2bin(aux,(unsigned char*)(DATABUFFER + (uint64_t)(i*MAXLENGTHADDRESS)))) {
|
||||
bloom_add(&bloom,(char*)( DATABUFFER + (uint64_t)(i*MAXLENGTHADDRESS)),MAXLENGTHADDRESS);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,"[E] error hexs2bin\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,"[E] Ignoring invalid length line %s\n",aux);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,"[E] Ignoring invalid hexvalue %s\n",aux);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,"[E] Omiting line : %s\n",aux);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
free(aux);
|
||||
fclose(fd);
|
||||
printf("[+] Bloomfilter completed\n");
|
||||
@@ -935,15 +1059,7 @@ int main(int argc, char **argv) {
|
||||
if(fd != NULL) {
|
||||
while(!feof(fd) && i < bsgs_m ) {
|
||||
if(fread(rawvalue,1,32,fd) == 32) {
|
||||
//memcpy(bPtable[i].value,rawvalue,BSGS_XVALUE_RAM);
|
||||
bPtable[i].value[0] = rawvalue[6];
|
||||
bPtable[i].value[1] = rawvalue[7];
|
||||
bPtable[i].value[2] = rawvalue[14];
|
||||
bPtable[i].value[3] = rawvalue[15];
|
||||
bPtable[i].value[4] = rawvalue[22];
|
||||
bPtable[i].value[5] = rawvalue[23];
|
||||
bPtable[i].value[6] = rawvalue[30];
|
||||
bPtable[i].value[7] = rawvalue[31];
|
||||
memcpy(bPtable[i].value,rawvalue,BSGS_XVALUE_RAM);
|
||||
|
||||
bPtable[i].index = j;
|
||||
bloom_add(&bloom_bPx, rawvalue, BSGS_BUFFERXPOINTLENGTH);
|
||||
@@ -964,16 +1080,7 @@ int main(int argc, char **argv) {
|
||||
mpz_set(point_temp.y,BSGS_P.y);
|
||||
gmp_sprintf(temporal,"%0.64Zx",BSGS_P.x);
|
||||
hexs2bin(temporal,rawvalue);
|
||||
//memcpy(bPtable[i].value,rawvalue,4);
|
||||
bPtable[i].value[0] = rawvalue[6];
|
||||
bPtable[i].value[1] = rawvalue[7];
|
||||
bPtable[i].value[2] = rawvalue[14];
|
||||
bPtable[i].value[3] = rawvalue[15];
|
||||
bPtable[i].value[4] = rawvalue[22];
|
||||
bPtable[i].value[5] = rawvalue[23];
|
||||
bPtable[i].value[6] = rawvalue[30];
|
||||
bPtable[i].value[7] = rawvalue[31];
|
||||
|
||||
memcpy(bPtable[i].value,rawvalue,BSGS_XVALUE_RAM);
|
||||
bPtable[i].index = j;
|
||||
bloom_add(&bloom_bPx, rawvalue,BSGS_BUFFERXPOINTLENGTH);
|
||||
Point_Addition(&G,&point_temp,&BSGS_P);
|
||||
@@ -989,15 +1096,7 @@ int main(int argc, char **argv) {
|
||||
mpz_set(point_temp.y,BSGS_P.y);
|
||||
gmp_sprintf(temporal,"%0.64Zx",BSGS_P.x);
|
||||
hexs2bin(temporal, rawvalue );
|
||||
//memcpy(bPtable[i].value,rawvalue,BSGS_XVALUE_RAM);
|
||||
bPtable[i].value[0] = rawvalue[6];
|
||||
bPtable[i].value[1] = rawvalue[7];
|
||||
bPtable[i].value[2] = rawvalue[14];
|
||||
bPtable[i].value[3] = rawvalue[15];
|
||||
bPtable[i].value[4] = rawvalue[22];
|
||||
bPtable[i].value[5] = rawvalue[23];
|
||||
bPtable[i].value[6] = rawvalue[30];
|
||||
bPtable[i].value[7] = rawvalue[31];
|
||||
memcpy(bPtable[i].value,rawvalue,BSGS_XVALUE_RAM);
|
||||
bPtable[i].index = j;
|
||||
bloom_add(&bloom_bPx, rawvalue ,BSGS_BUFFERXPOINTLENGTH);
|
||||
Point_Addition(&G,&point_temp,&BSGS_P);
|
||||
@@ -1006,7 +1105,12 @@ int main(int argc, char **argv) {
|
||||
} while( i < bsgs_m );
|
||||
}
|
||||
printf("[+] Sorting %lu elements\n",bsgs_m);
|
||||
c_beging = clock();
|
||||
bsgs_sort(bPtable,bsgs_m);
|
||||
c_ending = clock();
|
||||
double time_spent = (double)(c_ending-c_beging) / CLOCKS_PER_SEC;
|
||||
printf("[+] Sorted %lu elements in %f seconds\n",bsgs_m ,time_spent);
|
||||
|
||||
i = 0;
|
||||
|
||||
steps = (unsigned int *) calloc(NTHREADS,sizeof(int));
|
||||
@@ -1084,25 +1188,17 @@ int main(int argc, char **argv) {
|
||||
mpz_init(debugcount_mpz);
|
||||
sprintf(temporal,"%llu",(long long unsigned int)DEBUGCOUNT);
|
||||
mpz_set_str(debugcount_mpz,temporal,10);
|
||||
/*
|
||||
printf("DEBUGCOUNT: %llu\n",DEBUGCOUNT);
|
||||
gmp_printf("debugcount_mpz: %Zu\n",debugcount_mpz);
|
||||
printf("NTHREADS: %i\n",NTHREADS);
|
||||
*/
|
||||
|
||||
do {
|
||||
sleep(1);
|
||||
seconds+=1;
|
||||
if(FLAGMODE != MODE_BSGS && FLAGRANGE) {
|
||||
check_flag = 1;
|
||||
pthread_mutex_lock(&threads_end);
|
||||
for(i = 0; i <NTHREADS && check_flag; i++) {
|
||||
check_flag &= ends[i];
|
||||
}
|
||||
pthread_mutex_unlock(&threads_end);
|
||||
if(check_flag) {
|
||||
continue_flag = 0;
|
||||
}
|
||||
}
|
||||
if(OUTPUTSECONDS > 0){
|
||||
if(seconds % OUTPUTSECONDS == 0) {
|
||||
mpz_set_ui(total,0);
|
||||
@@ -1279,13 +1375,14 @@ char *pubkeytopubaddress_eth(char *pkey,int length) {
|
||||
|
||||
char *pubkeytopubaddress(char *pkey,int length) {
|
||||
char *pubaddress = calloc(MAXLENGTHADDRESS+10,1);
|
||||
char *digest = malloc(60);
|
||||
char *digest = calloc(60,1);
|
||||
long unsigned int pubaddress_size = MAXLENGTHADDRESS+10;
|
||||
if(pubaddress == NULL || digest == NULL) {
|
||||
fprintf(stderr,"error malloc()\n");
|
||||
exit(0);
|
||||
}
|
||||
memset(digest,0,60);
|
||||
|
||||
|
||||
//digest [000...0]
|
||||
sha256(pkey, length, digest);
|
||||
//digest [SHA256 32 bytes+000....0]
|
||||
@@ -1304,6 +1401,23 @@ char *pubkeytopubaddress(char *pkey,int length) {
|
||||
return pubaddress; // pubaddress need to be free by te caller funtion
|
||||
}
|
||||
|
||||
char *publickeytohashrmd160(char *pkey,int length) {
|
||||
char *hash160 = malloc(20);
|
||||
char *digest = malloc(32);
|
||||
if(hash160 == NULL || digest == NULL) {
|
||||
fprintf(stderr,"error malloc()\n");
|
||||
exit(0);
|
||||
}
|
||||
//digest [000...0]
|
||||
sha256(pkey, length, digest);
|
||||
//digest [SHA256 32 bytes]
|
||||
RMD160Data((const unsigned char*)digest,32, hash160);
|
||||
//hash160 [RMD160 20 bytes]
|
||||
free(digest);
|
||||
return hash160; // hash160 need to be free by te caller funtion
|
||||
}
|
||||
|
||||
|
||||
int searchbinary(char *buffer,char *data,int length,int _N) {
|
||||
char *temp_read;
|
||||
int r = 0,rcmp,current_offset,half,min,max,current;
|
||||
@@ -1339,14 +1453,14 @@ void *thread_process(void *vargp) {
|
||||
uint64_t count = 0;
|
||||
int r,thread_number,found;
|
||||
char *hexstrpoint;
|
||||
char *public_key_compressed,*public_key_uncompressed;
|
||||
char *public_key_compressed,*public_key_uncompressed,*publickeyhashrmd160_compress,*publickeyhashrmd160_uncompress;
|
||||
char *hextemp,*public_key_compressed_hex,*public_key_uncompressed_hex;
|
||||
char *eth_address;
|
||||
char *public_address_compressed,*public_address_uncompressed;
|
||||
unsigned long longtemp;
|
||||
FILE *keys,*vanityKeys;
|
||||
mpz_t random_key_mpz,mpz_bit_range_min,mpz_bit_range_max,mpz_bit_range_diff;
|
||||
mpz_init(random_key_mpz);
|
||||
mpz_t key_mpz,mpz_bit_range_min,mpz_bit_range_max,mpz_bit_range_diff;
|
||||
mpz_init(key_mpz);
|
||||
mpz_init(R.x);
|
||||
mpz_init(R.y);
|
||||
mpz_init(temporal.x);
|
||||
@@ -1371,19 +1485,18 @@ void *thread_process(void *vargp) {
|
||||
do {
|
||||
pthread_mutex_lock(&write_random);
|
||||
if(FLAGBITRANGE) {
|
||||
mpz_urandomm(random_key_mpz,state,mpz_bit_range_diff);
|
||||
mpz_add(random_key_mpz,random_key_mpz,mpz_bit_range_min);
|
||||
mpz_urandomm(key_mpz,state,mpz_bit_range_diff);
|
||||
mpz_add(key_mpz,key_mpz,mpz_bit_range_min);
|
||||
}
|
||||
else {
|
||||
mpz_urandomm(random_key_mpz,state,EC.n);
|
||||
mpz_urandomm(key_mpz,state,EC.n);
|
||||
}
|
||||
pthread_mutex_unlock(&write_random);
|
||||
hextemp = malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",random_key_mpz);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
printf("Thread %i : Setting up base key: %s\n",thread_number,hextemp);
|
||||
|
||||
free(hextemp);
|
||||
Scalar_Multiplication(G, &R, random_key_mpz);
|
||||
Scalar_Multiplication(G, &R, key_mpz);
|
||||
count = 0;
|
||||
public_key_uncompressed[0] = 0x04;
|
||||
|
||||
@@ -1400,19 +1513,29 @@ void *thread_process(void *vargp) {
|
||||
else { //Odd
|
||||
public_key_compressed[0] = 0x03;
|
||||
}
|
||||
if(FLAGMODE ) { // FLAGMODE == 1 search for address but for what crypto ?
|
||||
if( (FLAGCRYPTO & CRYPTO_BTC) != 0) {
|
||||
memcpy(public_key_uncompressed+1,public_key_compressed+1,32);
|
||||
gmp_sprintf(hexstrpoint,"%0.64Zx",R.y);
|
||||
hexs2bin(hexstrpoint,(unsigned char*)(public_key_uncompressed+33));
|
||||
|
||||
switch(FLAGMODE) {
|
||||
case MODE_ADDRESS:
|
||||
switch(FLAGSEARCH) {
|
||||
case SEARCH_UNCOMPRESS:
|
||||
public_address_uncompressed = pubkeytopubaddress(public_key_uncompressed,65);
|
||||
break;
|
||||
case SEARCH_COMPRESS:
|
||||
public_address_compressed = pubkeytopubaddress(public_key_compressed,33);
|
||||
break;
|
||||
case SEARCH_BOTH:
|
||||
public_address_compressed = pubkeytopubaddress(public_key_compressed,33);
|
||||
public_address_uncompressed = pubkeytopubaddress(public_key_uncompressed,65);
|
||||
|
||||
break;
|
||||
}
|
||||
if(FLAGVANITY) {
|
||||
if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
if(strncmp(public_address_uncompressed,vanity,len_vanity) == 0) {
|
||||
hextemp = malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",random_key_mpz);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
vanityKeys = fopen("vanitykeys.txt","a+");
|
||||
if(vanityKeys != NULL) {
|
||||
fprintf(vanityKeys,"PrivKey: %s\nAddress uncompressed: %s\n",hextemp,public_address_uncompressed);
|
||||
@@ -1421,9 +1544,11 @@ void *thread_process(void *vargp) {
|
||||
printf("Vanity privKey: %s\nAddress uncompressed: %s\n",hextemp,public_address_uncompressed);
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
if(strncmp(public_address_compressed,vanity,len_vanity) == 0) {
|
||||
hextemp = malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",random_key_mpz);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
vanityKeys = fopen("vanitykeys.txt","a+");
|
||||
if(vanityKeys != NULL) {
|
||||
fprintf(vanityKeys,"PrivKey: %s\nAddress compressed: %s\n",hextemp,public_address_compressed);
|
||||
@@ -1433,16 +1558,18 @@ void *thread_process(void *vargp) {
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
r = bloom_check(&bloom,public_address_compressed,MAXLENGTHADDRESS);
|
||||
if(r) {
|
||||
r = searchbinary(DATABUFFER,public_address_compressed,MAXLENGTHADDRESS,N);
|
||||
if(r) {
|
||||
found++;
|
||||
hextemp = malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",random_key_mpz);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_compressed_hex = tohex(public_key_compressed,33);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
keys = fopen("keys.txt","a+");
|
||||
keys = fopen("KEYFOUNDKEYFOUND.txt","a+");
|
||||
if(keys != NULL) {
|
||||
fprintf(keys,"PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_compressed_hex,public_address_compressed);
|
||||
fclose(keys);
|
||||
@@ -1453,17 +1580,20 @@ void *thread_process(void *vargp) {
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
free(public_address_compressed);
|
||||
}
|
||||
|
||||
if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
r = bloom_check(&bloom,public_address_uncompressed,MAXLENGTHADDRESS);
|
||||
if(r) {
|
||||
r = searchbinary(DATABUFFER,public_address_uncompressed,MAXLENGTHADDRESS,N);
|
||||
if(r) {
|
||||
found++;
|
||||
hextemp = malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",random_key_mpz);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_uncompressed_hex = tohex(public_key_uncompressed,65);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
keys = fopen("keys.txt","a+");
|
||||
keys = fopen("KEYFOUNDKEYFOUND.txt","a+");
|
||||
if(keys != NULL) {
|
||||
fprintf(keys,"PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,public_address_uncompressed);
|
||||
fclose(keys);
|
||||
@@ -1474,10 +1604,8 @@ void *thread_process(void *vargp) {
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
free(public_address_compressed);
|
||||
free(public_address_uncompressed);
|
||||
}
|
||||
//printf("Resultado %i\n",FLAGCRYPTO & CRYPTO_ETH);
|
||||
if( (FLAGCRYPTO & CRYPTO_ETH) != 0) {
|
||||
/*
|
||||
mpz_export((public_key_uncompressed+1),&longtemp,1,8,1,0,R.x);
|
||||
@@ -1489,7 +1617,7 @@ void *thread_process(void *vargp) {
|
||||
r = searchbinary(DATABUFFER,public_address_uncompressed,MAXLENGTHADDRESS,N);
|
||||
if(r) {
|
||||
hextemp = malloc(65);
|
||||
mpz_get_str(hextemp,16,random_key_mpz);
|
||||
mpz_get_str(hextemp,16,key_mpz);
|
||||
public_key_uncompressed_hex = tohex(public_key_uncompressed+1,64);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
keys = fopen("keys.txt","a+");
|
||||
@@ -1506,16 +1634,29 @@ void *thread_process(void *vargp) {
|
||||
}
|
||||
*/
|
||||
}
|
||||
break;
|
||||
case MODE_RMD160:
|
||||
switch(FLAGSEARCH) {
|
||||
case SEARCH_UNCOMPRESS:
|
||||
publickeyhashrmd160_uncompress = publickeytohashrmd160(public_key_uncompressed,65);
|
||||
break;
|
||||
case SEARCH_COMPRESS:
|
||||
publickeyhashrmd160_compress = publickeytohashrmd160(public_key_compressed,33);
|
||||
break;
|
||||
case SEARCH_BOTH:
|
||||
publickeyhashrmd160_compress = publickeytohashrmd160(public_key_compressed,33);
|
||||
publickeyhashrmd160_uncompress = publickeytohashrmd160(public_key_uncompressed,65);
|
||||
break;
|
||||
}
|
||||
else { //FLAGMODE == 0
|
||||
|
||||
r = bloom_check(&bloom,public_key_compressed+1,MAXLENGTHADDRESS);
|
||||
if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
r = bloom_check(&bloom,publickeyhashrmd160_compress,MAXLENGTHADDRESS);
|
||||
if(r) {
|
||||
r = searchbinary(DATABUFFER,public_key_compressed+1,MAXLENGTHADDRESS,N);
|
||||
r = searchbinary(DATABUFFER,publickeyhashrmd160_compress,MAXLENGTHADDRESS,N);
|
||||
if(r) {
|
||||
found++;
|
||||
hextemp = malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",random_key_mpz);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_compressed_hex = tohex(public_key_compressed,33);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
keys = fopen("KEYFOUNDKEYFOUND.txt","a+");
|
||||
@@ -1529,12 +1670,64 @@ void *thread_process(void *vargp) {
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
free(publickeyhashrmd160_compress);
|
||||
}
|
||||
if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
r = bloom_check(&bloom,publickeyhashrmd160_uncompress,MAXLENGTHADDRESS);
|
||||
if(r) {
|
||||
r = searchbinary(DATABUFFER,publickeyhashrmd160_uncompress,MAXLENGTHADDRESS,N);
|
||||
if(r) {
|
||||
found++;
|
||||
hextemp = malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_uncompressed_hex = tohex(public_key_uncompressed,65);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
keys = fopen("KEYFOUNDKEYFOUND.txt","a+");
|
||||
if(keys != NULL) {
|
||||
fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_uncompressed_hex);
|
||||
fclose(keys);
|
||||
}
|
||||
printf("HIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_uncompressed_hex);
|
||||
pthread_mutex_unlock(&write_keys);
|
||||
free(public_key_uncompressed_hex);
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
free(publickeyhashrmd160_uncompress);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
break;
|
||||
case MODE_XPOINT:
|
||||
r = bloom_check(&bloom,public_key_compressed+1,MAXLENGTHADDRESS);
|
||||
if(r) {
|
||||
r = searchbinary(DATABUFFER,public_key_compressed+1,MAXLENGTHADDRESS,N);
|
||||
if(r) {
|
||||
found++;
|
||||
hextemp = malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_compressed_hex = tohex(public_key_compressed,33);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
keys = fopen("KEYFOUNDKEYFOUND.txt","a+");
|
||||
if(keys != NULL) {
|
||||
fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex);
|
||||
fclose(keys);
|
||||
}
|
||||
printf("HIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex);
|
||||
pthread_mutex_unlock(&write_keys);
|
||||
free(public_key_compressed_hex);
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
if(count % DEBUGCOUNT == 0) {
|
||||
steps[thread_number]++;
|
||||
}
|
||||
mpz_add_ui(random_key_mpz,random_key_mpz,1);
|
||||
mpz_add_ui(key_mpz,key_mpz,1);
|
||||
Point_Addition(&temporal,&G,&R);
|
||||
}while(count <= N_SECUENTIAL_MAX);
|
||||
} while(1);
|
||||
@@ -1548,7 +1741,7 @@ void *thread_process_range(void *vargp) {
|
||||
uint64_t count = 0;
|
||||
int r,thread_number,found = 0;
|
||||
char *hexstrpoint;
|
||||
char *public_key_compressed,*public_key_uncompressed;
|
||||
char *public_key_compressed,*public_key_uncompressed,*publickeyhashrmd160_compress,*publickeyhashrmd160_uncompress;
|
||||
char *hextemp,*public_key_compressed_hex,*public_key_uncompressed_hex;
|
||||
char *eth_address;
|
||||
char *public_address_compressed,*public_address_uncompressed;
|
||||
@@ -1597,19 +1790,28 @@ void *thread_process_range(void *vargp) {
|
||||
else { //ODD
|
||||
public_key_compressed[0] = 0x03;
|
||||
}
|
||||
if(FLAGMODE) { // FLAGMODE == 1
|
||||
if( (FLAGCRYPTO & CRYPTO_BTC) != 0) {
|
||||
memcpy(public_key_uncompressed+1,public_key_compressed+1,32);
|
||||
|
||||
gmp_sprintf(hexstrpoint,"%0.64Zx",R.y);
|
||||
hexs2bin(hexstrpoint,(unsigned char*)(public_key_uncompressed+33));
|
||||
|
||||
switch(FLAGMODE) {
|
||||
case MODE_ADDRESS:
|
||||
if( (FLAGCRYPTO & CRYPTO_BTC) != 0) {
|
||||
switch(FLAGSEARCH) {
|
||||
case SEARCH_UNCOMPRESS:
|
||||
public_address_uncompressed = pubkeytopubaddress(public_key_uncompressed,65);
|
||||
break;
|
||||
case SEARCH_COMPRESS:
|
||||
public_address_compressed = pubkeytopubaddress(public_key_compressed,33);
|
||||
break;
|
||||
case SEARCH_BOTH:
|
||||
public_address_compressed = pubkeytopubaddress(public_key_compressed,33);
|
||||
public_address_uncompressed = pubkeytopubaddress(public_key_uncompressed,65);
|
||||
/*
|
||||
printf("Testing: %s\n",public_address_compressed);
|
||||
printf("Testing: %s\n",public_address_uncompressed);
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if(FLAGVANITY) {
|
||||
if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
if(strncmp(public_address_uncompressed,vanity,len_vanity) == 0) {
|
||||
hextemp = malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
@@ -1621,6 +1823,8 @@ void *thread_process_range(void *vargp) {
|
||||
printf("Vanity privKey: %s\nAddress uncompressed: %s\n",hextemp,public_address_uncompressed);
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
if(strncmp(public_address_compressed,vanity,len_vanity) == 0) {
|
||||
hextemp = malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
@@ -1633,6 +1837,8 @@ void *thread_process_range(void *vargp) {
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
r = bloom_check(&bloom,public_address_compressed,MAXLENGTHADDRESS);
|
||||
if(r) {
|
||||
//printf("bloom_check: %i for %s\n",r,public_address_compressed);
|
||||
@@ -1643,7 +1849,7 @@ void *thread_process_range(void *vargp) {
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_compressed_hex = tohex(public_key_compressed,33);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
keys = fopen("keys.txt","a+");
|
||||
keys = fopen("KEYFOUNDKEYFOUND.txt","a+");
|
||||
if(keys != NULL) {
|
||||
fprintf(keys,"PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_compressed_hex,public_address_compressed);
|
||||
fclose(keys);
|
||||
@@ -1654,8 +1860,10 @@ void *thread_process_range(void *vargp) {
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
free(public_address_compressed);
|
||||
}
|
||||
if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
r = bloom_check(&bloom,public_address_uncompressed,MAXLENGTHADDRESS);
|
||||
|
||||
if(r) {
|
||||
//printf("bloom_check: %i for %s\n",r,public_address_uncompressed);
|
||||
r = searchbinary(DATABUFFER,public_address_uncompressed,MAXLENGTHADDRESS,N);
|
||||
@@ -1665,7 +1873,7 @@ void *thread_process_range(void *vargp) {
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_uncompressed_hex = tohex(public_key_uncompressed,65);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
keys = fopen("keys.txt","a+");
|
||||
keys = fopen("KEYFOUNDKEYFOUND.txt","a+");
|
||||
if(keys != NULL) {
|
||||
fprintf(keys,"PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,public_address_uncompressed);
|
||||
fclose(keys);
|
||||
@@ -1676,9 +1884,12 @@ void *thread_process_range(void *vargp) {
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
free(public_address_compressed);
|
||||
free(public_address_uncompressed);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if( ( FLAGCRYPTO & CRYPTO_ETH ) != 0) {
|
||||
/*
|
||||
mpz_export((public_key_uncompressed+1),&longtemp,1,8,1,0,R.x);
|
||||
@@ -1693,7 +1904,7 @@ void *thread_process_range(void *vargp) {
|
||||
mpz_get_str(hextemp,16,key_mpz);
|
||||
public_key_uncompressed_hex = tohex(public_key_uncompressed+1,64);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
keys = fopen("keys.txt","a+");
|
||||
keys = fopen("KEYFOUNDKEYFOUND.txt","a+");
|
||||
if(keys != NULL) {
|
||||
fprintf(keys,"PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,public_address_uncompressed);
|
||||
fclose(keys);
|
||||
@@ -1707,14 +1918,69 @@ void *thread_process_range(void *vargp) {
|
||||
}
|
||||
*/
|
||||
}
|
||||
break;
|
||||
case MODE_RMD160:
|
||||
switch(FLAGSEARCH) {
|
||||
case SEARCH_UNCOMPRESS:
|
||||
publickeyhashrmd160_uncompress = publickeytohashrmd160(public_key_uncompressed,65);
|
||||
break;
|
||||
case SEARCH_COMPRESS:
|
||||
publickeyhashrmd160_compress = publickeytohashrmd160(public_key_compressed,33);
|
||||
break;
|
||||
case SEARCH_BOTH:
|
||||
publickeyhashrmd160_compress = publickeytohashrmd160(public_key_compressed,33);
|
||||
publickeyhashrmd160_uncompress = publickeytohashrmd160(public_key_uncompressed,65);
|
||||
break;
|
||||
}
|
||||
else { // FLAGMODE == 0
|
||||
/*
|
||||
public_key_compressed_hex = tohex(public_key_compressed+1,32);
|
||||
printf("Buscando %s\n",public_key_compressed_hex);
|
||||
if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
r = bloom_check(&bloom,publickeyhashrmd160_compress,MAXLENGTHADDRESS);
|
||||
if(r) {
|
||||
r = searchbinary(DATABUFFER,publickeyhashrmd160_compress,MAXLENGTHADDRESS,N);
|
||||
if(r) {
|
||||
found++;
|
||||
hextemp = malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_compressed_hex = tohex(public_key_compressed,33);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
keys = fopen("KEYFOUNDKEYFOUND.txt","a+");
|
||||
if(keys != NULL) {
|
||||
fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex);
|
||||
fclose(keys);
|
||||
}
|
||||
printf("HIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex);
|
||||
pthread_mutex_unlock(&write_keys);
|
||||
free(public_key_compressed_hex);
|
||||
*/
|
||||
//printf("Checking: %s\n",hexstrpoint);
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
r = bloom_check(&bloom,publickeyhashrmd160_uncompress,MAXLENGTHADDRESS);
|
||||
if(r) {
|
||||
r = searchbinary(DATABUFFER,publickeyhashrmd160_uncompress,MAXLENGTHADDRESS,N);
|
||||
if(r) {
|
||||
found++;
|
||||
hextemp = malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_uncompressed_hex = tohex(public_key_uncompressed,65);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
keys = fopen("KEYFOUNDKEYFOUND.txt","a+");
|
||||
if(keys != NULL) {
|
||||
fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_uncompressed_hex);
|
||||
fclose(keys);
|
||||
}
|
||||
printf("HIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_uncompressed_hex);
|
||||
pthread_mutex_unlock(&write_keys);
|
||||
free(public_key_uncompressed_hex);
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(publickeyhashrmd160_compress);
|
||||
free(publickeyhashrmd160_uncompress);
|
||||
break;
|
||||
case MODE_XPOINT:
|
||||
r = bloom_check(&bloom,public_key_compressed+1,MAXLENGTHADDRESS);
|
||||
if(r) {
|
||||
r = searchbinary(DATABUFFER,public_key_compressed+1,MAXLENGTHADDRESS,N);
|
||||
@@ -1735,6 +2001,7 @@ void *thread_process_range(void *vargp) {
|
||||
free(hextemp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
if(count % DEBUGCOUNT == 0) {
|
||||
@@ -2042,7 +2309,7 @@ int bsgs_searchbinary(struct bsgs_xvalue *buffer,char *data,int64_t _N,int64_t *
|
||||
|
||||
void *thread_process_bsgs(void *vargp) {
|
||||
struct tothread *tt;
|
||||
char pubkey[131],xpoint_str[65],xpoint_raw[32],tosearch[BSGS_XVALUE_RAM];
|
||||
char pubkey[131],xpoint_str[65],xpoint_raw[32];
|
||||
char *aux_c;
|
||||
mpz_t base_key,keyfound;
|
||||
FILE *filekey;
|
||||
@@ -2162,15 +2429,7 @@ void *thread_process_bsgs(void *vargp) {
|
||||
r = bloom_check(&bloom_bPx,xpoint_raw,32);
|
||||
if(r) {
|
||||
/* Lookup for the xpoint_raw into the full sorted list*/
|
||||
tosearch[0] = xpoint_raw[6];
|
||||
tosearch[1] = xpoint_raw[7];
|
||||
tosearch[2] = xpoint_raw[14];
|
||||
tosearch[3] = xpoint_raw[15];
|
||||
tosearch[4] = xpoint_raw[22];
|
||||
tosearch[5] = xpoint_raw[23];
|
||||
tosearch[6] = xpoint_raw[30];
|
||||
tosearch[7] = xpoint_raw[31];
|
||||
r = bsgs_searchbinary(bPtable,tosearch,bsgs_m,&j);
|
||||
r = bsgs_searchbinary(bPtable,xpoint_raw,bsgs_m,&j);
|
||||
if(r) {
|
||||
/* is the xpoint is in the sorted list we HIT one privkey*/
|
||||
/* privkey = base_key + aM + b */
|
||||
@@ -2241,16 +2500,6 @@ void *thread_process_bsgs(void *vargp) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
/*
|
||||
else {
|
||||
|
||||
printf("[E] Something is wrong!\n");
|
||||
gmp_printf("[I] Basekey: 0x%Zx\n",base_key);
|
||||
gmp_printf("[I] BSGS_M: 0x%Zx\n",BSGS_M);
|
||||
printf("[I] a = %i , b = %li\n",i,j+1);
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2288,7 +2537,7 @@ void *thread_process_bsgs(void *vargp) {
|
||||
|
||||
void *thread_process_bsgs_random(void *vargp) {
|
||||
struct tothread *tt;
|
||||
char pubkey[131],xpoint_str[65],xpoint_raw[32],tosearch[BSGS_XVALUE_RAM];
|
||||
char pubkey[131],xpoint_str[65],xpoint_raw[32];
|
||||
char *aux_c;
|
||||
mpz_t base_key,keyfound;
|
||||
FILE *filekey;
|
||||
@@ -2416,15 +2665,7 @@ void *thread_process_bsgs_random(void *vargp) {
|
||||
if(r) {
|
||||
|
||||
/* Lookup for the xpoint_raw into the full sorted list*/
|
||||
tosearch[0] = xpoint_raw[6];
|
||||
tosearch[1] = xpoint_raw[7];
|
||||
tosearch[2] = xpoint_raw[14];
|
||||
tosearch[3] = xpoint_raw[15];
|
||||
tosearch[4] = xpoint_raw[22];
|
||||
tosearch[5] = xpoint_raw[23];
|
||||
tosearch[6] = xpoint_raw[30];
|
||||
tosearch[7] = xpoint_raw[31];
|
||||
r = bsgs_searchbinary(bPtable,tosearch,bsgs_m,&j);
|
||||
r = bsgs_searchbinary(bPtable,xpoint_raw,bsgs_m,&j);
|
||||
if(r) {
|
||||
/* is the xpoint is in the sorted list we HIT one privkey*/
|
||||
/* privkey = base_key + aM + b */
|
||||
@@ -2492,14 +2733,6 @@ void *thread_process_bsgs_random(void *vargp) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
/*
|
||||
else {
|
||||
printf("[E] Something is wrong!\n");
|
||||
gmp_printf("[I] Basekey: 0x%Zx\n",base_key);
|
||||
gmp_printf("[I] BSGS_M: 0x%Zx\n",BSGS_M);
|
||||
printf("[I] a = %i , b = %li\n",i,j+1);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
182
sha3/keccak.c
Normal file
182
sha3/keccak.c
Normal file
@@ -0,0 +1,182 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Taylor R. Campbell
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "keccak.h"
|
||||
|
||||
#define secret /* can't use in variable-time operations, should zero */
|
||||
|
||||
#define FOR5(X, STMT) do \
|
||||
{ \
|
||||
(X) = 0; (STMT); \
|
||||
(X) = 1; (STMT); \
|
||||
(X) = 2; (STMT); \
|
||||
(X) = 3; (STMT); \
|
||||
(X) = 4; (STMT); \
|
||||
} while (0)
|
||||
|
||||
static inline secret uint64_t
|
||||
rol64(secret uint64_t v, unsigned c)
|
||||
{
|
||||
|
||||
return ((v << c) | (v >> (64 - c)));
|
||||
}
|
||||
|
||||
static inline void
|
||||
keccakf1600_theta(secret uint64_t A[25])
|
||||
{
|
||||
secret uint64_t C0, C1, C2, C3, C4;
|
||||
unsigned y;
|
||||
|
||||
C0 = C1 = C2 = C3 = C4 = 0;
|
||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||
FOR5(y, {
|
||||
C0 ^= A[0 + 5*y];
|
||||
C1 ^= A[1 + 5*y];
|
||||
C2 ^= A[2 + 5*y];
|
||||
C3 ^= A[3 + 5*y];
|
||||
C4 ^= A[4 + 5*y];
|
||||
});
|
||||
FOR5(y, {
|
||||
A[0 + 5*y] ^= C4 ^ rol64(C1, 1);
|
||||
A[1 + 5*y] ^= C0 ^ rol64(C2, 1);
|
||||
A[2 + 5*y] ^= C1 ^ rol64(C3, 1);
|
||||
A[3 + 5*y] ^= C2 ^ rol64(C4, 1);
|
||||
A[4 + 5*y] ^= C3 ^ rol64(C0, 1);
|
||||
});
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
|
||||
static inline void
|
||||
keccakf1600_rho_pi(secret uint64_t A[25])
|
||||
{
|
||||
secret uint64_t T, U;
|
||||
|
||||
/*
|
||||
* Permute by (x,y) |---> (y, 2x + 3y mod 5) starting at (1,0),
|
||||
* rotate the ith element by (i + 1)(i + 2)/2 mod 64.
|
||||
*/
|
||||
U = A[ 1]; T = U;
|
||||
U = A[10]; A[10] = rol64(T, 1); T = U;
|
||||
U = A[ 7]; A[ 7] = rol64(T, 3); T = U;
|
||||
U = A[11]; A[11] = rol64(T, 6); T = U;
|
||||
U = A[17]; A[17] = rol64(T, 10); T = U;
|
||||
U = A[18]; A[18] = rol64(T, 15); T = U;
|
||||
U = A[ 3]; A[ 3] = rol64(T, 21); T = U;
|
||||
U = A[ 5]; A[ 5] = rol64(T, 28); T = U;
|
||||
U = A[16]; A[16] = rol64(T, 36); T = U;
|
||||
U = A[ 8]; A[ 8] = rol64(T, 45); T = U;
|
||||
U = A[21]; A[21] = rol64(T, 55); T = U;
|
||||
U = A[24]; A[24] = rol64(T, 2); T = U;
|
||||
U = A[ 4]; A[ 4] = rol64(T, 14); T = U;
|
||||
U = A[15]; A[15] = rol64(T, 27); T = U;
|
||||
U = A[23]; A[23] = rol64(T, 41); T = U;
|
||||
U = A[19]; A[19] = rol64(T, 56); T = U;
|
||||
U = A[13]; A[13] = rol64(T, 8); T = U;
|
||||
U = A[12]; A[12] = rol64(T, 25); T = U;
|
||||
U = A[ 2]; A[ 2] = rol64(T, 43); T = U;
|
||||
U = A[20]; A[20] = rol64(T, 62); T = U;
|
||||
U = A[14]; A[14] = rol64(T, 18); T = U;
|
||||
U = A[22]; A[22] = rol64(T, 39); T = U;
|
||||
U = A[ 9]; A[ 9] = rol64(T, 61); T = U;
|
||||
U = A[ 6]; A[ 6] = rol64(T, 20); T = U;
|
||||
A[ 1] = rol64(T, 44);
|
||||
}
|
||||
|
||||
static inline void
|
||||
keccakf1600_chi(secret uint64_t A[25])
|
||||
{
|
||||
secret uint64_t B0, B1, B2, B3, B4;
|
||||
unsigned y;
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||
FOR5(y, {
|
||||
B0 = A[0 + 5*y];
|
||||
B1 = A[1 + 5*y];
|
||||
B2 = A[2 + 5*y];
|
||||
B3 = A[3 + 5*y];
|
||||
B4 = A[4 + 5*y];
|
||||
A[0 + 5*y] ^= ~B1 & B2;
|
||||
A[1 + 5*y] ^= ~B2 & B3;
|
||||
A[2 + 5*y] ^= ~B3 & B4;
|
||||
A[3 + 5*y] ^= ~B4 & B0;
|
||||
A[4 + 5*y] ^= ~B0 & B1;
|
||||
});
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
|
||||
static void
|
||||
keccakf1600_round(secret uint64_t A[25])
|
||||
{
|
||||
|
||||
keccakf1600_theta(A);
|
||||
keccakf1600_rho_pi(A);
|
||||
keccakf1600_chi(A);
|
||||
}
|
||||
|
||||
void
|
||||
keccakf1600(secret uint64_t A[25])
|
||||
{
|
||||
/*
|
||||
* RC[i] = \sum_{j = 0,...,6} rc(j + 7i) 2^(2^j - 1),
|
||||
* rc(t) = (x^t mod x^8 + x^6 + x^5 + x^4 + 1) mod x in GF(2)[x]
|
||||
*/
|
||||
static const uint64_t RC[24] = {
|
||||
0x0000000000000001ULL,
|
||||
0x0000000000008082ULL,
|
||||
0x800000000000808aULL,
|
||||
0x8000000080008000ULL,
|
||||
0x000000000000808bULL,
|
||||
0x0000000080000001ULL,
|
||||
0x8000000080008081ULL,
|
||||
0x8000000000008009ULL,
|
||||
0x000000000000008aULL,
|
||||
0x0000000000000088ULL,
|
||||
0x0000000080008009ULL,
|
||||
0x000000008000000aULL,
|
||||
0x000000008000808bULL,
|
||||
0x800000000000008bULL,
|
||||
0x8000000000008089ULL,
|
||||
0x8000000000008003ULL,
|
||||
0x8000000000008002ULL,
|
||||
0x8000000000000080ULL,
|
||||
0x000000000000800aULL,
|
||||
0x800000008000000aULL,
|
||||
0x8000000080008081ULL,
|
||||
0x8000000000008080ULL,
|
||||
0x0000000080000001ULL,
|
||||
0x8000000080008008ULL,
|
||||
};
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 24; i++) {
|
||||
keccakf1600_round(A);
|
||||
A[0] ^= RC[i];
|
||||
}
|
||||
}
|
34
sha3/keccak.h
Normal file
34
sha3/keccak.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Taylor R. Campbell
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef KECCAK_H
|
||||
#define KECCAK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void keccakf1600(uint64_t A[25]);
|
||||
|
||||
#endif /* KECCAK_H */
|
674
sha3/sha3.c
Normal file
674
sha3/sha3.c
Normal file
@@ -0,0 +1,674 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Taylor R. Campbell
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SHA-3: FIPS-202, Permutation-Based Hash and Extendable-Ouptut Functions
|
||||
*/
|
||||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "keccak.h"
|
||||
|
||||
#include "sha3.h"
|
||||
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
void *(*volatile sha3_explicit_memset_impl)(void *, int, size_t) = &memset;
|
||||
static void *
|
||||
explicit_memset(void *buf, int c, size_t n)
|
||||
{
|
||||
|
||||
return (*sha3_explicit_memset_impl)(buf, c, n);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
le64dec(const void *buf)
|
||||
{
|
||||
const uint8_t *p = buf;
|
||||
|
||||
return (((uint64_t)p[0]) |
|
||||
((uint64_t)p[1] << 8) |
|
||||
((uint64_t)p[2] << 16) |
|
||||
((uint64_t)p[3] << 24) |
|
||||
((uint64_t)p[4] << 32) |
|
||||
((uint64_t)p[5] << 40) |
|
||||
((uint64_t)p[6] << 48) |
|
||||
((uint64_t)p[7] << 56));
|
||||
}
|
||||
|
||||
static inline void
|
||||
le64enc(void *buf, uint64_t v)
|
||||
{
|
||||
uint8_t *p = buf;
|
||||
|
||||
*p++ = v; v >>= 8;
|
||||
*p++ = v; v >>= 8;
|
||||
*p++ = v; v >>= 8;
|
||||
*p++ = v; v >>= 8;
|
||||
*p++ = v; v >>= 8;
|
||||
*p++ = v; v >>= 8;
|
||||
*p++ = v; v >>= 8;
|
||||
*p++ = v;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common body. All the SHA-3 functions share code structure. They
|
||||
* differ only in the size of the chunks they split the message into:
|
||||
* for digest size d, they are split into chunks of 200 - d bytes.
|
||||
*/
|
||||
|
||||
static inline unsigned
|
||||
sha3_rate(unsigned d)
|
||||
{
|
||||
const unsigned cw = 2*d/8; /* capacity in words */
|
||||
|
||||
return 25 - cw;
|
||||
}
|
||||
|
||||
static void
|
||||
sha3_init(struct sha3 *C, unsigned rw)
|
||||
{
|
||||
unsigned iw;
|
||||
|
||||
C->nb = 8*rw;
|
||||
for (iw = 0; iw < 25; iw++)
|
||||
C->A[iw] = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sha3_update(struct sha3 *C, const uint8_t *data, size_t len, unsigned rw)
|
||||
{
|
||||
uint64_t T;
|
||||
unsigned ib, iw; /* index of byte/word */
|
||||
|
||||
assert(0 < C->nb);
|
||||
|
||||
/* If there's a partial word, try to fill it. */
|
||||
if ((C->nb % 8) != 0) {
|
||||
T = 0;
|
||||
for (ib = 0; ib < MIN(len, C->nb % 8); ib++)
|
||||
T |= (uint64_t)data[ib] << (8*ib);
|
||||
C->A[rw - (C->nb + 7)/8] ^= T << (8*(8 - (C->nb % 8)));
|
||||
C->nb -= ib;
|
||||
data += ib;
|
||||
len -= ib;
|
||||
|
||||
/* If we filled the buffer, permute now. */
|
||||
if (C->nb == 0) {
|
||||
keccakf1600(C->A);
|
||||
C->nb = 8*rw;
|
||||
}
|
||||
|
||||
/* If that exhausted the input, we're done. */
|
||||
if (len == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* At a word boundary. Fill any partial buffer. */
|
||||
assert((C->nb % 8) == 0);
|
||||
if (C->nb < 8*rw) {
|
||||
for (iw = 0; iw < MIN(len, C->nb)/8; iw++)
|
||||
C->A[rw - C->nb/8 + iw] ^= le64dec(data + 8*iw);
|
||||
C->nb -= 8*iw;
|
||||
data += 8*iw;
|
||||
len -= 8*iw;
|
||||
|
||||
/* If we filled the buffer, permute now. */
|
||||
if (C->nb == 0) {
|
||||
keccakf1600(C->A);
|
||||
C->nb = 8*rw;
|
||||
} else {
|
||||
/* Otherwise, less than a word left. */
|
||||
assert(len < 8);
|
||||
goto partial;
|
||||
}
|
||||
}
|
||||
|
||||
/* At a buffer boundary. Absorb input one buffer at a time. */
|
||||
assert(C->nb == 8*rw);
|
||||
while (8*rw <= len) {
|
||||
for (iw = 0; iw < rw; iw++)
|
||||
C->A[iw] ^= le64dec(data + 8*iw);
|
||||
keccakf1600(C->A);
|
||||
data += 8*rw;
|
||||
len -= 8*rw;
|
||||
}
|
||||
|
||||
/* Partially fill the buffer with as many words as we can. */
|
||||
for (iw = 0; iw < len/8; iw++)
|
||||
C->A[rw - C->nb/8 + iw] ^= le64dec(data + 8*iw);
|
||||
C->nb -= 8*iw;
|
||||
data += 8*iw;
|
||||
len -= 8*iw;
|
||||
|
||||
partial:
|
||||
/* Partially fill the last word with as many bytes as we can. */
|
||||
assert(len < 8);
|
||||
assert(0 < C->nb);
|
||||
assert((C->nb % 8) == 0);
|
||||
T = 0;
|
||||
for (ib = 0; ib < len; ib++)
|
||||
T |= (uint64_t)data[ib] << (8*ib);
|
||||
C->A[rw - C->nb/8] ^= T;
|
||||
C->nb -= ib;
|
||||
assert(0 < C->nb);
|
||||
}
|
||||
|
||||
static inline void
|
||||
sha3_or_keccak_final(uint8_t *h, unsigned d, struct sha3 *C, unsigned rw, uint64_t padding)
|
||||
{
|
||||
unsigned nw, iw;
|
||||
|
||||
assert(d <= 8*25);
|
||||
assert(0 < C->nb);
|
||||
|
||||
/* Append 01, pad with 10*1 up to buffer boundary, LSB first. */
|
||||
nw = (C->nb + 7)/8;
|
||||
assert(0 < nw);
|
||||
assert(nw <= rw);
|
||||
C->A[rw - nw] ^= padding << (8*(8*nw - C->nb));
|
||||
C->A[rw - 1] ^= 0x8000000000000000ULL;
|
||||
|
||||
/* Permute one last time. */
|
||||
keccakf1600(C->A);
|
||||
|
||||
/* Reveal the first 8d bits of state, forget 1600-8d of them. */
|
||||
for (iw = 0; iw < d/8; iw++)
|
||||
le64enc(h + 8*iw, C->A[iw]);
|
||||
h += 8*iw;
|
||||
d -= 8*iw;
|
||||
if (0 < d) {
|
||||
/* For SHA3-224, we need to expose a partial word. */
|
||||
uint64_t T = C->A[iw];
|
||||
do {
|
||||
*h++ = T & 0xff;
|
||||
T >>= 8;
|
||||
} while (--d);
|
||||
}
|
||||
(void)explicit_memset(C->A, 0, sizeof C->A);
|
||||
C->nb = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sha3_final(uint8_t *h, unsigned d, struct sha3 *C, unsigned rw)
|
||||
{
|
||||
sha3_or_keccak_final(h, d, C, rw, 0x06);
|
||||
}
|
||||
|
||||
static void
|
||||
keccak_final(uint8_t *h, unsigned d, struct sha3 *C, unsigned rw)
|
||||
{
|
||||
sha3_or_keccak_final(h, d, C, rw, 0x01);
|
||||
}
|
||||
|
||||
static void
|
||||
shake_final(uint8_t *h, unsigned d, struct sha3 *C, unsigned rw)
|
||||
{
|
||||
unsigned nw, iw;
|
||||
|
||||
assert(0 < C->nb);
|
||||
|
||||
/* Append 1111, pad with 10*1 up to buffer boundary, LSB first. */
|
||||
nw = (C->nb + 7)/8;
|
||||
assert(0 < nw);
|
||||
assert(nw <= rw);
|
||||
C->A[rw - nw] ^= (uint64_t)0x1f << (8*(8*nw - C->nb));
|
||||
C->A[rw - 1] ^= 0x8000000000000000ULL;
|
||||
|
||||
/* Permute, reveal first rw words of state, repeat. */
|
||||
while (8*rw <= d) {
|
||||
keccakf1600(C->A);
|
||||
for (iw = 0; iw < rw; iw++)
|
||||
le64enc(h + 8*iw, C->A[iw]);
|
||||
h += 8*iw;
|
||||
d -= 8*iw;
|
||||
}
|
||||
|
||||
/*
|
||||
* If 8*rw (the output rate in bytes) does not divide d, more
|
||||
* words are wanted: permute again and reveal a little more.
|
||||
*/
|
||||
if (0 < d) {
|
||||
keccakf1600(C->A);
|
||||
for (iw = 0; iw < d/8; iw++)
|
||||
le64enc(h + 8*iw, C->A[iw]);
|
||||
h += 8*iw;
|
||||
d -= 8*iw;
|
||||
|
||||
/*
|
||||
* If 8 does not divide d, more bytes are wanted:
|
||||
* reveal them.
|
||||
*/
|
||||
if (0 < d) {
|
||||
uint64_t T = C->A[iw];
|
||||
do {
|
||||
*h++ = T & 0xff;
|
||||
T >>= 8;
|
||||
} while (--d);
|
||||
}
|
||||
}
|
||||
|
||||
(void)explicit_memset(C->A, 0, sizeof C->A);
|
||||
C->nb = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SHA3_224_Init(SHA3_224_CTX *C)
|
||||
{
|
||||
|
||||
sha3_init(&C->C224, sha3_rate(SHA3_224_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
SHA3_224_Update(SHA3_224_CTX *C, const uint8_t *data, size_t len)
|
||||
{
|
||||
|
||||
sha3_update(&C->C224, data, len, sha3_rate(SHA3_224_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
SHA3_224_Final(uint8_t h[SHA3_224_DIGEST_LENGTH], SHA3_224_CTX *C)
|
||||
{
|
||||
|
||||
sha3_final(h, SHA3_224_DIGEST_LENGTH, &C->C224,
|
||||
sha3_rate(SHA3_224_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
SHA3_256_Init(SHA3_256_CTX *C)
|
||||
{
|
||||
|
||||
sha3_init(&C->C256, sha3_rate(SHA3_256_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
SHA3_256_Update(SHA3_256_CTX *C, const uint8_t *data, size_t len)
|
||||
{
|
||||
|
||||
sha3_update(&C->C256, data, len, sha3_rate(SHA3_256_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
SHA3_256_Final(uint8_t h[SHA3_256_DIGEST_LENGTH], SHA3_256_CTX *C)
|
||||
{
|
||||
|
||||
sha3_final(h, SHA3_256_DIGEST_LENGTH, &C->C256,
|
||||
sha3_rate(SHA3_256_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
SHA3_384_Init(SHA3_384_CTX *C)
|
||||
{
|
||||
|
||||
sha3_init(&C->C384, sha3_rate(SHA3_384_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
SHA3_384_Update(SHA3_384_CTX *C, const uint8_t *data, size_t len)
|
||||
{
|
||||
|
||||
sha3_update(&C->C384, data, len, sha3_rate(SHA3_384_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
SHA3_384_Final(uint8_t h[SHA3_384_DIGEST_LENGTH], SHA3_384_CTX *C)
|
||||
{
|
||||
|
||||
sha3_final(h, SHA3_384_DIGEST_LENGTH, &C->C384,
|
||||
sha3_rate(SHA3_384_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
SHA3_512_Init(SHA3_512_CTX *C)
|
||||
{
|
||||
|
||||
sha3_init(&C->C512, sha3_rate(SHA3_512_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
SHA3_512_Update(SHA3_512_CTX *C, const uint8_t *data, size_t len)
|
||||
{
|
||||
|
||||
sha3_update(&C->C512, data, len, sha3_rate(SHA3_512_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
SHA3_512_Final(uint8_t h[SHA3_512_DIGEST_LENGTH], SHA3_512_CTX *C)
|
||||
{
|
||||
|
||||
sha3_final(h, SHA3_512_DIGEST_LENGTH, &C->C512,
|
||||
sha3_rate(SHA3_512_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
SHAKE128_Init(SHAKE128_CTX *C)
|
||||
{
|
||||
|
||||
sha3_init(&C->C128, sha3_rate(128/8));
|
||||
}
|
||||
|
||||
void
|
||||
SHAKE128_Update(SHAKE128_CTX *C, const uint8_t *data, size_t len)
|
||||
{
|
||||
|
||||
sha3_update(&C->C128, data, len, sha3_rate(128/8));
|
||||
}
|
||||
|
||||
void
|
||||
SHAKE128_Final(uint8_t *h, size_t d, SHAKE128_CTX *C)
|
||||
{
|
||||
|
||||
shake_final(h, d, &C->C128, sha3_rate(128/8));
|
||||
}
|
||||
|
||||
void
|
||||
SHAKE256_Init(SHAKE256_CTX *C)
|
||||
{
|
||||
|
||||
sha3_init(&C->C256, sha3_rate(256/8));
|
||||
}
|
||||
|
||||
void
|
||||
SHAKE256_Update(SHAKE256_CTX *C, const uint8_t *data, size_t len)
|
||||
{
|
||||
|
||||
sha3_update(&C->C256, data, len, sha3_rate(256/8));
|
||||
}
|
||||
|
||||
void
|
||||
SHAKE256_Final(uint8_t *h, size_t d, SHAKE256_CTX *C)
|
||||
{
|
||||
|
||||
shake_final(h, d, &C->C256, sha3_rate(256/8));
|
||||
}
|
||||
|
||||
void
|
||||
KECCAK_256_Final(uint8_t h[SHA3_256_DIGEST_LENGTH], SHA3_256_CTX *C)
|
||||
{
|
||||
|
||||
keccak_final(h, SHA3_256_DIGEST_LENGTH, &C->C256,
|
||||
sha3_rate(SHA3_256_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
KECCAK_384_Final(uint8_t h[SHA3_384_DIGEST_LENGTH], SHA3_384_CTX *C)
|
||||
{
|
||||
|
||||
keccak_final(h, SHA3_384_DIGEST_LENGTH, &C->C384,
|
||||
sha3_rate(SHA3_384_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
void
|
||||
KECCAK_512_Final(uint8_t h[SHA3_512_DIGEST_LENGTH], SHA3_512_CTX *C)
|
||||
{
|
||||
|
||||
keccak_final(h, SHA3_512_DIGEST_LENGTH, &C->C512,
|
||||
sha3_rate(SHA3_512_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
static void
|
||||
sha3_selftest_prng(void *buf, size_t len, uint32_t seed)
|
||||
{
|
||||
uint8_t *p = buf;
|
||||
size_t n = len;
|
||||
uint32_t t, a, b;
|
||||
|
||||
a = 0xdead4bad * seed;
|
||||
b = 1;
|
||||
|
||||
while (n--) {
|
||||
t = a + b;
|
||||
*p++ = t >> 24;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SHA3_Selftest(void)
|
||||
{
|
||||
const uint8_t d224_0[] = { /* SHA3-224(0-bit) */
|
||||
0x6b,0x4e,0x03,0x42,0x36,0x67,0xdb,0xb7,
|
||||
0x3b,0x6e,0x15,0x45,0x4f,0x0e,0xb1,0xab,
|
||||
0xd4,0x59,0x7f,0x9a,0x1b,0x07,0x8e,0x3f,
|
||||
0x5b,0x5a,0x6b,0xc7,
|
||||
};
|
||||
const uint8_t d256_0[] = { /* SHA3-256(0-bit) */
|
||||
0xa7,0xff,0xc6,0xf8,0xbf,0x1e,0xd7,0x66,
|
||||
0x51,0xc1,0x47,0x56,0xa0,0x61,0xd6,0x62,
|
||||
0xf5,0x80,0xff,0x4d,0xe4,0x3b,0x49,0xfa,
|
||||
0x82,0xd8,0x0a,0x4b,0x80,0xf8,0x43,0x4a,
|
||||
};
|
||||
const uint8_t d384_0[] = { /* SHA3-384(0-bit) */
|
||||
0x0c,0x63,0xa7,0x5b,0x84,0x5e,0x4f,0x7d,
|
||||
0x01,0x10,0x7d,0x85,0x2e,0x4c,0x24,0x85,
|
||||
0xc5,0x1a,0x50,0xaa,0xaa,0x94,0xfc,0x61,
|
||||
0x99,0x5e,0x71,0xbb,0xee,0x98,0x3a,0x2a,
|
||||
0xc3,0x71,0x38,0x31,0x26,0x4a,0xdb,0x47,
|
||||
0xfb,0x6b,0xd1,0xe0,0x58,0xd5,0xf0,0x04,
|
||||
};
|
||||
const uint8_t d512_0[] = { /* SHA3-512(0-bit) */
|
||||
0xa6,0x9f,0x73,0xcc,0xa2,0x3a,0x9a,0xc5,
|
||||
0xc8,0xb5,0x67,0xdc,0x18,0x5a,0x75,0x6e,
|
||||
0x97,0xc9,0x82,0x16,0x4f,0xe2,0x58,0x59,
|
||||
0xe0,0xd1,0xdc,0xc1,0x47,0x5c,0x80,0xa6,
|
||||
0x15,0xb2,0x12,0x3a,0xf1,0xf5,0xf9,0x4c,
|
||||
0x11,0xe3,0xe9,0x40,0x2c,0x3a,0xc5,0x58,
|
||||
0xf5,0x00,0x19,0x9d,0x95,0xb6,0xd3,0xe3,
|
||||
0x01,0x75,0x85,0x86,0x28,0x1d,0xcd,0x26,
|
||||
};
|
||||
const uint8_t shake128_0_41[] = { /* SHAKE128(0-bit, 41) */
|
||||
0x7f,0x9c,0x2b,0xa4,0xe8,0x8f,0x82,0x7d,
|
||||
0x61,0x60,0x45,0x50,0x76,0x05,0x85,0x3e,
|
||||
0xd7,0x3b,0x80,0x93,0xf6,0xef,0xbc,0x88,
|
||||
0xeb,0x1a,0x6e,0xac,0xfa,0x66,0xef,0x26,
|
||||
0x3c,0xb1,0xee,0xa9,0x88,0x00,0x4b,0x93,0x10,
|
||||
};
|
||||
const uint8_t shake256_0_73[] = { /* SHAKE256(0-bit, 73) */
|
||||
0x46,0xb9,0xdd,0x2b,0x0b,0xa8,0x8d,0x13,
|
||||
0x23,0x3b,0x3f,0xeb,0x74,0x3e,0xeb,0x24,
|
||||
0x3f,0xcd,0x52,0xea,0x62,0xb8,0x1b,0x82,
|
||||
0xb5,0x0c,0x27,0x64,0x6e,0xd5,0x76,0x2f,
|
||||
0xd7,0x5d,0xc4,0xdd,0xd8,0xc0,0xf2,0x00,
|
||||
0xcb,0x05,0x01,0x9d,0x67,0xb5,0x92,0xf6,
|
||||
0xfc,0x82,0x1c,0x49,0x47,0x9a,0xb4,0x86,
|
||||
0x40,0x29,0x2e,0xac,0xb3,0xb7,0xc4,0xbe,
|
||||
0x14,0x1e,0x96,0x61,0x6f,0xb1,0x39,0x57,0x69,
|
||||
};
|
||||
const uint8_t d224_1600[] = { /* SHA3-224(200 * 0xa3) */
|
||||
0x93,0x76,0x81,0x6a,0xba,0x50,0x3f,0x72,
|
||||
0xf9,0x6c,0xe7,0xeb,0x65,0xac,0x09,0x5d,
|
||||
0xee,0xe3,0xbe,0x4b,0xf9,0xbb,0xc2,0xa1,
|
||||
0xcb,0x7e,0x11,0xe0,
|
||||
};
|
||||
const uint8_t d256_1600[] = { /* SHA3-256(200 * 0xa3) */
|
||||
0x79,0xf3,0x8a,0xde,0xc5,0xc2,0x03,0x07,
|
||||
0xa9,0x8e,0xf7,0x6e,0x83,0x24,0xaf,0xbf,
|
||||
0xd4,0x6c,0xfd,0x81,0xb2,0x2e,0x39,0x73,
|
||||
0xc6,0x5f,0xa1,0xbd,0x9d,0xe3,0x17,0x87,
|
||||
};
|
||||
const uint8_t d384_1600[] = { /* SHA3-384(200 * 0xa3) */
|
||||
0x18,0x81,0xde,0x2c,0xa7,0xe4,0x1e,0xf9,
|
||||
0x5d,0xc4,0x73,0x2b,0x8f,0x5f,0x00,0x2b,
|
||||
0x18,0x9c,0xc1,0xe4,0x2b,0x74,0x16,0x8e,
|
||||
0xd1,0x73,0x26,0x49,0xce,0x1d,0xbc,0xdd,
|
||||
0x76,0x19,0x7a,0x31,0xfd,0x55,0xee,0x98,
|
||||
0x9f,0x2d,0x70,0x50,0xdd,0x47,0x3e,0x8f,
|
||||
};
|
||||
const uint8_t d512_1600[] = { /* SHA3-512(200 * 0xa3) */
|
||||
0xe7,0x6d,0xfa,0xd2,0x20,0x84,0xa8,0xb1,
|
||||
0x46,0x7f,0xcf,0x2f,0xfa,0x58,0x36,0x1b,
|
||||
0xec,0x76,0x28,0xed,0xf5,0xf3,0xfd,0xc0,
|
||||
0xe4,0x80,0x5d,0xc4,0x8c,0xae,0xec,0xa8,
|
||||
0x1b,0x7c,0x13,0xc3,0x0a,0xdf,0x52,0xa3,
|
||||
0x65,0x95,0x84,0x73,0x9a,0x2d,0xf4,0x6b,
|
||||
0xe5,0x89,0xc5,0x1c,0xa1,0xa4,0xa8,0x41,
|
||||
0x6d,0xf6,0x54,0x5a,0x1c,0xe8,0xba,0x00,
|
||||
};
|
||||
const uint8_t shake128_1600_41[] = { /* SHAKE128(200 * 0xa3, 41) */
|
||||
0x13,0x1a,0xb8,0xd2,0xb5,0x94,0x94,0x6b,
|
||||
0x9c,0x81,0x33,0x3f,0x9b,0xb6,0xe0,0xce,
|
||||
0x75,0xc3,0xb9,0x31,0x04,0xfa,0x34,0x69,
|
||||
0xd3,0x91,0x74,0x57,0x38,0x5d,0xa0,0x37,
|
||||
0xcf,0x23,0x2e,0xf7,0x16,0x4a,0x6d,0x1e,0xb4,
|
||||
};
|
||||
const uint8_t shake256_1600_73[] = { /* SHAKE256(200 * 0xa3, 73) */
|
||||
0xcd,0x8a,0x92,0x0e,0xd1,0x41,0xaa,0x04,
|
||||
0x07,0xa2,0x2d,0x59,0x28,0x86,0x52,0xe9,
|
||||
0xd9,0xf1,0xa7,0xee,0x0c,0x1e,0x7c,0x1c,
|
||||
0xa6,0x99,0x42,0x4d,0xa8,0x4a,0x90,0x4d,
|
||||
0x2d,0x70,0x0c,0xaa,0xe7,0x39,0x6e,0xce,
|
||||
0x96,0x60,0x44,0x40,0x57,0x7d,0xa4,0xf3,
|
||||
0xaa,0x22,0xae,0xb8,0x85,0x7f,0x96,0x1c,
|
||||
0x4c,0xd8,0xe0,0x6f,0x0a,0xe6,0x61,0x0b,
|
||||
0x10,0x48,0xa7,0xf6,0x4e,0x10,0x74,0xcd,0x62,
|
||||
};
|
||||
const uint8_t d0[] = {
|
||||
0x6c,0x02,0x1a,0xc6,0x65,0xaf,0x80,0xfb,
|
||||
0x52,0xe6,0x2d,0x27,0xe5,0x02,0x88,0x84,
|
||||
0xec,0x1c,0x0c,0xe7,0x0b,0x94,0x55,0x83,
|
||||
0x19,0xf2,0xbf,0x09,0x86,0xeb,0x1a,0xbb,
|
||||
0xc3,0x0d,0x1c,0xef,0x22,0xfe,0xc5,0x4c,
|
||||
0x45,0x90,0x66,0x14,0x00,0x6e,0xc8,0x79,
|
||||
0xdf,0x1e,0x02,0xbd,0x75,0xe9,0x60,0xd8,
|
||||
0x60,0x39,0x85,0xc9,0xc4,0xee,0x33,0xab,
|
||||
};
|
||||
const unsigned mlen[6] = { 0, 3, 128, 129, 255, 1024 };
|
||||
uint8_t m[1024], d[73];
|
||||
SHA3_224_CTX sha3224;
|
||||
SHA3_256_CTX sha3256;
|
||||
SHA3_384_CTX sha3384;
|
||||
SHA3_512_CTX sha3512;
|
||||
SHAKE128_CTX shake128;
|
||||
SHAKE256_CTX shake256;
|
||||
SHA3_512_CTX ctx;
|
||||
unsigned mi;
|
||||
|
||||
/*
|
||||
* NIST test vectors from
|
||||
* <http://csrc.nist.gov/groups/ST/toolkit/examples.html#aHashing>:
|
||||
* 0-bit, 1600-bit repeated 0xa3 (= 0b10100011).
|
||||
*/
|
||||
SHA3_224_Init(&sha3224);
|
||||
SHA3_224_Final(d, &sha3224);
|
||||
if (memcmp(d, d224_0, 28) != 0)
|
||||
return -1;
|
||||
SHA3_256_Init(&sha3256);
|
||||
SHA3_256_Final(d, &sha3256);
|
||||
if (memcmp(d, d256_0, 32) != 0)
|
||||
return -1;
|
||||
SHA3_384_Init(&sha3384);
|
||||
SHA3_384_Final(d, &sha3384);
|
||||
if (memcmp(d, d384_0, 48) != 0)
|
||||
return -1;
|
||||
SHA3_512_Init(&sha3512);
|
||||
SHA3_512_Final(d, &sha3512);
|
||||
if (memcmp(d, d512_0, 64) != 0)
|
||||
return -1;
|
||||
SHAKE128_Init(&shake128);
|
||||
SHAKE128_Final(d, 41, &shake128);
|
||||
if (memcmp(d, shake128_0_41, 41) != 0)
|
||||
return -1;
|
||||
SHAKE256_Init(&shake256);
|
||||
SHAKE256_Final(d, 73, &shake256);
|
||||
if (memcmp(d, shake256_0_73, 73) != 0)
|
||||
return -1;
|
||||
|
||||
(void)memset(m, 0xa3, 200);
|
||||
SHA3_224_Init(&sha3224);
|
||||
SHA3_224_Update(&sha3224, m, 200);
|
||||
SHA3_224_Final(d, &sha3224);
|
||||
if (memcmp(d, d224_1600, 28) != 0)
|
||||
return -1;
|
||||
SHA3_256_Init(&sha3256);
|
||||
SHA3_256_Update(&sha3256, m, 200);
|
||||
SHA3_256_Final(d, &sha3256);
|
||||
if (memcmp(d, d256_1600, 32) != 0)
|
||||
return -1;
|
||||
SHA3_384_Init(&sha3384);
|
||||
SHA3_384_Update(&sha3384, m, 200);
|
||||
SHA3_384_Final(d, &sha3384);
|
||||
if (memcmp(d, d384_1600, 48) != 0)
|
||||
return -1;
|
||||
SHA3_512_Init(&sha3512);
|
||||
SHA3_512_Update(&sha3512, m, 200);
|
||||
SHA3_512_Final(d, &sha3512);
|
||||
if (memcmp(d, d512_1600, 64) != 0)
|
||||
return -1;
|
||||
SHAKE128_Init(&shake128);
|
||||
SHAKE128_Update(&shake128, m, 200);
|
||||
SHAKE128_Final(d, 41, &shake128);
|
||||
if (memcmp(d, shake128_1600_41, 41) != 0)
|
||||
return -1;
|
||||
SHAKE256_Init(&shake256);
|
||||
SHAKE256_Update(&shake256, m, 200);
|
||||
SHAKE256_Final(d, 73, &shake256);
|
||||
if (memcmp(d, shake256_1600_73, 73) != 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Hand-crufted test vectors with unaligned message lengths.
|
||||
*/
|
||||
SHA3_512_Init(&ctx);
|
||||
for (mi = 0; mi < 6; mi++) {
|
||||
sha3_selftest_prng(m, mlen[mi], (224/8)*mlen[mi]);
|
||||
SHA3_224_Init(&sha3224);
|
||||
SHA3_224_Update(&sha3224, m, mlen[mi]);
|
||||
SHA3_224_Final(d, &sha3224);
|
||||
SHA3_512_Update(&ctx, d, 224/8);
|
||||
}
|
||||
for (mi = 0; mi < 6; mi++) {
|
||||
sha3_selftest_prng(m, mlen[mi], (256/8)*mlen[mi]);
|
||||
SHA3_256_Init(&sha3256);
|
||||
SHA3_256_Update(&sha3256, m, mlen[mi]);
|
||||
SHA3_256_Final(d, &sha3256);
|
||||
SHA3_512_Update(&ctx, d, 256/8);
|
||||
}
|
||||
for (mi = 0; mi < 6; mi++) {
|
||||
sha3_selftest_prng(m, mlen[mi], (384/8)*mlen[mi]);
|
||||
SHA3_384_Init(&sha3384);
|
||||
SHA3_384_Update(&sha3384, m, mlen[mi]);
|
||||
SHA3_384_Final(d, &sha3384);
|
||||
SHA3_512_Update(&ctx, d, 384/8);
|
||||
}
|
||||
for (mi = 0; mi < 6; mi++) {
|
||||
sha3_selftest_prng(m, mlen[mi], (512/8)*mlen[mi]);
|
||||
SHA3_512_Init(&sha3512);
|
||||
SHA3_512_Update(&sha3512, m, mlen[mi]);
|
||||
SHA3_512_Final(d, &sha3512);
|
||||
SHA3_512_Update(&ctx, d, 512/8);
|
||||
}
|
||||
SHA3_512_Final(d, &ctx);
|
||||
if (memcmp(d, d0, 64) != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
88
sha3/sha3.h
Normal file
88
sha3/sha3.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Taylor R. Campbell
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SHA3_H
|
||||
#define SHA3_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct sha3 {
|
||||
uint64_t A[25];
|
||||
unsigned nb; /* number of bytes remaining to fill buffer */
|
||||
};
|
||||
|
||||
typedef struct { struct sha3 C224; } SHA3_224_CTX;
|
||||
typedef struct { struct sha3 C256; } SHA3_256_CTX;
|
||||
typedef struct { struct sha3 C384; } SHA3_384_CTX;
|
||||
typedef struct { struct sha3 C512; } SHA3_512_CTX;
|
||||
typedef struct { struct sha3 C128; } SHAKE128_CTX;
|
||||
typedef struct { struct sha3 C256; } SHAKE256_CTX;
|
||||
|
||||
#define SHA3_224_DIGEST_LENGTH 28
|
||||
#define SHA3_256_DIGEST_LENGTH 32
|
||||
#define SHA3_384_DIGEST_LENGTH 48
|
||||
#define SHA3_512_DIGEST_LENGTH 64
|
||||
|
||||
void SHA3_224_Init(SHA3_224_CTX *);
|
||||
void SHA3_224_Update(SHA3_224_CTX *, const uint8_t *, size_t);
|
||||
void SHA3_224_Final(uint8_t[SHA3_224_DIGEST_LENGTH], SHA3_224_CTX *);
|
||||
|
||||
void SHA3_256_Init(SHA3_256_CTX *);
|
||||
void SHA3_256_Update(SHA3_256_CTX *, const uint8_t *, size_t);
|
||||
void SHA3_256_Final(uint8_t[SHA3_256_DIGEST_LENGTH], SHA3_256_CTX *);
|
||||
|
||||
void SHA3_384_Init(SHA3_384_CTX *);
|
||||
void SHA3_384_Update(SHA3_384_CTX *, const uint8_t *, size_t);
|
||||
void SHA3_384_Final(uint8_t[SHA3_384_DIGEST_LENGTH], SHA3_384_CTX *);
|
||||
|
||||
void SHA3_512_Init(SHA3_512_CTX *);
|
||||
void SHA3_512_Update(SHA3_512_CTX *, const uint8_t *, size_t);
|
||||
void SHA3_512_Final(uint8_t[SHA3_512_DIGEST_LENGTH], SHA3_512_CTX *);
|
||||
|
||||
void SHAKE128_Init(SHAKE128_CTX *);
|
||||
void SHAKE128_Update(SHAKE128_CTX *, const uint8_t *, size_t);
|
||||
void SHAKE128_Final(uint8_t *, size_t, SHAKE128_CTX *);
|
||||
|
||||
void SHAKE256_Init(SHAKE256_CTX *);
|
||||
void SHAKE256_Update(SHAKE256_CTX *, const uint8_t *, size_t);
|
||||
void SHAKE256_Final(uint8_t *, size_t, SHAKE256_CTX *);
|
||||
|
||||
#define KECCAK_256_Init SHA3_256_Init
|
||||
#define KECCAK_256_Update SHA3_256_Update
|
||||
void KECCAK_256_Final(uint8_t[SHA3_256_DIGEST_LENGTH], SHA3_256_CTX *);
|
||||
|
||||
#define KECCAK_384_Init SHA3_384_Init
|
||||
#define KECCAK_384_Update SHA3_384_Update
|
||||
void KECCAK_384_Final(uint8_t[SHA3_384_DIGEST_LENGTH], SHA3_384_CTX *);
|
||||
|
||||
#define KECCAK_512_Init SHA3_512_Init
|
||||
#define KECCAK_512_Update SHA3_512_Update
|
||||
void KECCAK_512_Final(uint8_t[SHA3_512_DIGEST_LENGTH], SHA3_512_CTX *);
|
||||
|
||||
int SHA3_Selftest(void);
|
||||
|
||||
#endif /* SHA3_H */
|
Reference in New Issue
Block a user