mirror of
https://github.com/albertobsd/keyhunt.git
synced 2025-09-18 11:51:24 +02:00
bPtable create by secp256k1 first test
This commit is contained in:
14
Makefile
14
Makefile
@@ -1,13 +1,19 @@
|
||||
default:
|
||||
gcc -O3 -c bloom/bloom.c -o bloom.o
|
||||
gcc -O3 -c sha256/sha256.c -o sha256.o
|
||||
g++ -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 xxhash/xxhash.c -o xxhash.o
|
||||
gcc -O3 -c keyhunt.c -o keyhunt.o -lm
|
||||
gcc -o keyhunt keyhunt.o base58.o rmd160.o sha256.o bloom.o xxhash.o -lgmp -lm -lpthread
|
||||
gcc -O3 hexcharstoraw.c -o hexcharstoraw -lm
|
||||
g++ -O3 -c util.c -o util.o
|
||||
g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/Int.cpp -o Int.o
|
||||
g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/Point.cpp -o Point.o
|
||||
g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/SECP256K1.cpp -o SECP256K1.o
|
||||
g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/IntMod.cpp -o IntMod.o
|
||||
g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/Random.cpp -o Random.o
|
||||
g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/IntGroup.cpp -o IntGroup.o
|
||||
g++ -o keyhunt keyhunt.c base58.o rmd160.o sha256.o bloom.o xxhash.o util.o Int.o Point.o SECP256K1.o IntMod.o Random.o IntGroup.o -lgmp -lm -lpthread
|
||||
gcc -O3 hexcharstoraw.c -o hexcharstoraw util.o -lm
|
||||
gcc -o bPfile bPfile.c -lgmp -lm
|
||||
clean:
|
||||
rm -r *.o
|
||||
|
235
keyhunt.c
235
keyhunt.c
@@ -18,6 +18,11 @@ email: alberto.bsd@gmail.com
|
||||
#include "sha256/sha256.h"
|
||||
#include "bloom/bloom.h"
|
||||
#include "sha3/sha3.h"
|
||||
|
||||
#include "secp256k1/SECP256k1.h"
|
||||
#include "secp256k1/Point.h"
|
||||
#include "secp256k1/Int.h"
|
||||
|
||||
#include "util.h"
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
@@ -39,7 +44,7 @@ email: alberto.bsd@gmail.com
|
||||
#define SEARCH_BOTH 2
|
||||
|
||||
|
||||
struct Point {
|
||||
struct strPoint {
|
||||
mpz_t x;
|
||||
mpz_t y;
|
||||
};
|
||||
@@ -88,12 +93,12 @@ const char *EC_constant_N = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD
|
||||
const char *EC_constant_P = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f";
|
||||
const char *EC_constant_Gx = "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798";
|
||||
const char *EC_constant_Gy = "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8";
|
||||
struct Point DoublingG[256];
|
||||
struct strPoint DoublingG[256];
|
||||
|
||||
void Point_Doubling(struct Point *P, struct Point *R);
|
||||
void Point_Addition(struct Point *P, struct Point *Q, struct Point *R);
|
||||
void Scalar_Multiplication(struct Point P, struct Point *R, mpz_t m);
|
||||
void Point_Negation(struct Point *A, struct Point *S);
|
||||
void Point_Doubling(struct strPoint *P, struct strPoint *R);
|
||||
void Point_Addition(struct strPoint *P, struct strPoint *Q, struct strPoint *R);
|
||||
void Scalar_Multiplication(struct strPoint P, struct strPoint *R, mpz_t m);
|
||||
void Point_Negation(struct strPoint *A, struct strPoint *S);
|
||||
int searchbinary(struct address_value *buffer,char *data,int64_t _N);
|
||||
void sleep_ms(int milliseconds);
|
||||
|
||||
@@ -115,7 +120,7 @@ int64_t bsgs_partition(struct bsgs_xvalue *arr, int64_t n);
|
||||
|
||||
|
||||
int bsgs_searchbinary(struct bsgs_xvalue *arr,char *data,int64_t _N,uint64_t *r_value);
|
||||
int bsgs_secondcheck(mpz_t start_range,uint32_t a,struct Point *target,mpz_t *private);
|
||||
int bsgs_secondcheck(mpz_t start_range,uint32_t a,struct strPoint *target,mpz_t *privatekey);
|
||||
|
||||
void *thread_process(void *vargp);
|
||||
void *thread_process_bsgs(void *vargp);
|
||||
@@ -124,7 +129,7 @@ void *thread_bPload(void *vargp);
|
||||
void *thread_bPloadFile(void *vargp);
|
||||
void *thread_pub2rmd(void *vargp);
|
||||
|
||||
void init_doublingG(struct Point *P);
|
||||
void init_doublingG(struct strPoint *P);
|
||||
char *publickeytohashrmd160(char *pkey,int length);
|
||||
char *pubkeytopubaddress(char *pkey,int length);
|
||||
//char *pubkeytopubaddress_eth(char *pkey,int length);
|
||||
@@ -147,7 +152,7 @@ pthread_mutex_t bsgs_thread;
|
||||
struct Elliptic_Curve EC;
|
||||
struct bloom dummybloom;
|
||||
struct bloom bloom;
|
||||
struct Point G;
|
||||
struct strPoint G;
|
||||
|
||||
unsigned int *steps = NULL;
|
||||
unsigned int *ends = NULL;
|
||||
@@ -192,7 +197,7 @@ uint64_t BSGS_BUFFERREGISTERLENGTH = 36;
|
||||
BSGS Variables
|
||||
*/
|
||||
int *bsgs_found;
|
||||
struct Point *OriginalPointsBSGS;
|
||||
struct strPoint *OriginalPointsBSGS;
|
||||
struct bsgs_xvalue *bPtable;
|
||||
struct address_value *addressTable;
|
||||
struct bloom bloom_bP[256];
|
||||
@@ -212,19 +217,22 @@ mpz_t BSGS_M; //M is squareroot(N)
|
||||
mpz_t BSGS_M2;
|
||||
mpz_t TWO;
|
||||
mpz_t MPZAUX;
|
||||
struct Point BSGS_P; //Original P is actually G, but this P value change over time for calculations
|
||||
struct Point BSGS_MP; //MP values this is m * P
|
||||
struct Point BSGS_MP2; //MP values this is m2 * P
|
||||
struct Point *BSGS_AMP;
|
||||
struct Point *BSGS_AMP2;
|
||||
struct strPoint BSGS_P; //Original P is actually G, but this P value change over time for calculations
|
||||
struct strPoint BSGS_MP; //MP values this is m * P
|
||||
struct strPoint BSGS_MP2; //MP values this is m2 * P
|
||||
struct strPoint *BSGS_AMP;
|
||||
struct strPoint *BSGS_AMP2;
|
||||
|
||||
struct Point point_temp,point_temp2; //Temp value for some process
|
||||
struct strPoint point_temp,point_temp2; //Temp value for some process
|
||||
|
||||
mpz_t n_range_start;
|
||||
mpz_t n_range_end;
|
||||
mpz_t n_range_diff;
|
||||
mpz_t n_range_aux;
|
||||
|
||||
|
||||
Secp256K1 *secp;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char buffer[1024];
|
||||
char temporal[65];
|
||||
@@ -242,8 +250,12 @@ int main(int argc, char **argv) {
|
||||
struct bPload *temp;
|
||||
int c;
|
||||
|
||||
secp = new Secp256K1();
|
||||
secp->Init();
|
||||
|
||||
gmp_randinit_mt(state);
|
||||
gmp_randseed_ui(state, ((int)clock()) + ((int)time(NULL)) );
|
||||
gmp_randseed_ui(state, ((int)clock()) + ((int)time(NULL)));
|
||||
|
||||
mpz_init_set_str(EC.p, EC_constant_P, 16);
|
||||
mpz_init_set_str(EC.n, EC_constant_N, 16);
|
||||
mpz_init_set_str(G.x , EC_constant_Gx, 16);
|
||||
@@ -565,7 +577,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
N = 0;
|
||||
if(FLAGMODE != MODE_BSGS) {
|
||||
aux = malloc(1000);
|
||||
aux =(char*) malloc(1000);
|
||||
if(aux == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
}
|
||||
@@ -639,17 +651,17 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
fseek(fd,0,SEEK_SET);
|
||||
|
||||
printf("[+] Allocating memory for %"PRIu64" elements: %.2f MB\n",N,(double)(((double) sizeof(struct address_value)*N)/(double)1048576));
|
||||
printf("[+] Allocating memory for %" PRIu64 " elements: %.2f MB\n",N,(double)(((double) sizeof(struct address_value)*N)/(double)1048576));
|
||||
i = 0;
|
||||
do {
|
||||
addressTable = malloc(sizeof(struct address_value)*N);
|
||||
addressTable = (struct address_value*) malloc(sizeof(struct address_value)*N);
|
||||
i++;
|
||||
} while(addressTable == NULL && i < 10);
|
||||
if(addressTable == NULL) {
|
||||
fprintf(stderr,"[E] Can't alloc memory for %"PRIu64" elements\n",N);
|
||||
fprintf(stderr,"[E] Can't alloc memory for %" PRIu64 " elements\n",N);
|
||||
exit(0);
|
||||
}
|
||||
printf("[+] Initializing bloom filter for %"PRIu64" elements.\n",N);
|
||||
printf("[+] Initializing bloom filter for %" PRIu64 " elements.\n",N);
|
||||
if(N <= 1000) {
|
||||
if(bloom_init2(&bloom,1000,0.00001) == 1){
|
||||
fprintf(stderr,"[E] error bloom_init for 10000 elements.\n");
|
||||
@@ -667,7 +679,7 @@ int main(int argc, char **argv) {
|
||||
i = 0;
|
||||
switch (FLAGMODE) {
|
||||
case MODE_ADDRESS:
|
||||
aux = malloc(2*MAXLENGTHADDRESS);
|
||||
aux =(char*) malloc(2*MAXLENGTHADDRESS);
|
||||
if(aux == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
exit(0);
|
||||
@@ -690,7 +702,7 @@ int main(int argc, char **argv) {
|
||||
break;
|
||||
case MODE_XPOINT:
|
||||
if(FLAGRAWDATA) {
|
||||
aux = malloc(MAXLENGTHADDRESS);
|
||||
aux = (char*)malloc(MAXLENGTHADDRESS);
|
||||
if(aux == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
exit(0);
|
||||
@@ -704,7 +716,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
aux = malloc(5*MAXLENGTHADDRESS);
|
||||
aux = (char*) malloc(5*MAXLENGTHADDRESS);
|
||||
if(aux == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
exit(0);
|
||||
@@ -722,7 +734,7 @@ int main(int argc, char **argv) {
|
||||
if(isValidHex(hextemp)) {
|
||||
switch(lenaux) {
|
||||
case 64: /*X value*/
|
||||
r = hexs2bin(aux,rawvalue);
|
||||
r = hexs2bin(aux,(uint8_t*) rawvalue);
|
||||
if(r) {
|
||||
memcpy(addressTable[i].value,rawvalue,20);
|
||||
bloom_add(&bloom,rawvalue,MAXLENGTHADDRESS);
|
||||
@@ -732,7 +744,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
break;
|
||||
case 66: /*Compress publickey*/
|
||||
r = hexs2bin(aux+2,rawvalue);
|
||||
r = hexs2bin(aux+2, (uint8_t*)rawvalue);
|
||||
if(r) {
|
||||
memcpy(addressTable[i].value,rawvalue,20);
|
||||
bloom_add(&bloom,rawvalue,MAXLENGTHADDRESS);
|
||||
@@ -744,7 +756,7 @@ int main(int argc, char **argv) {
|
||||
case 130: /* Uncompress publickey length*/
|
||||
memset(temporal,0,65);
|
||||
memcpy(temporal,aux+2,64);
|
||||
r = hexs2bin(temporal,rawvalue);
|
||||
r = hexs2bin(temporal, (uint8_t*) rawvalue);
|
||||
if(r) {
|
||||
memcpy(addressTable[i].value,rawvalue,20);
|
||||
bloom_add(&bloom,rawvalue,MAXLENGTHADDRESS);
|
||||
@@ -775,7 +787,7 @@ int main(int argc, char **argv) {
|
||||
case MODE_PUB2RMD:
|
||||
case MODE_RMD160:
|
||||
if(FLAGRAWDATA) {
|
||||
aux = malloc(MAXLENGTHADDRESS);
|
||||
aux = (char*) malloc(MAXLENGTHADDRESS);
|
||||
if(aux == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
exit(0);
|
||||
@@ -789,7 +801,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
aux = malloc(3*MAXLENGTHADDRESS);
|
||||
aux = (char*) malloc(3*MAXLENGTHADDRESS);
|
||||
if(aux == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
exit(0);
|
||||
@@ -831,18 +843,18 @@ int main(int argc, char **argv) {
|
||||
printf("[+] Bloomfilter completed\n");
|
||||
if(FLAGALREADYSORTED) {
|
||||
printf("[+] File mark already sorted, skipping sort proccess\n");
|
||||
printf("[+] %"PRIu64" values were loaded\n",N);
|
||||
printf("[+] %" PRIu64 " values were loaded\n",N);
|
||||
_sort(addressTable,N);
|
||||
}
|
||||
else {
|
||||
printf("[+] Sorting data\n");
|
||||
_sort(addressTable,N);
|
||||
printf("[+] %"PRIu64" values were loaded and sorted\n",N);
|
||||
printf("[+] %" PRIu64 " values were loaded and sorted\n",N);
|
||||
}
|
||||
}
|
||||
if(FLAGMODE == MODE_BSGS) {
|
||||
DEBUGCOUNT = N_SECUENTIAL_MAX ;
|
||||
aux = malloc(1024);
|
||||
aux = (char*) malloc(1024);
|
||||
if(aux == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
exit(0);
|
||||
@@ -864,10 +876,10 @@ int main(int argc, char **argv) {
|
||||
fprintf(stderr,"[E] There is no valid data in the file\n");
|
||||
exit(0);
|
||||
}
|
||||
bsgs_found = calloc(N,sizeof(int));
|
||||
OriginalPointsBSGS = malloc(N*sizeof(struct Point));
|
||||
pointx_str = malloc(65);
|
||||
pointy_str = malloc(65);
|
||||
bsgs_found = (int*) calloc(N,sizeof(int));
|
||||
OriginalPointsBSGS = (struct strPoint*) malloc(N*sizeof(struct strPoint));
|
||||
pointx_str = (char*) malloc(65);
|
||||
pointy_str = (char*) malloc(65);
|
||||
if(OriginalPointsBSGS == NULL || pointy_str == NULL || pointx_str == NULL || bsgs_found == NULL) {
|
||||
fprintf(stderr,"[E] error malloc()\n");
|
||||
exit(0);
|
||||
@@ -1051,7 +1063,7 @@ int main(int argc, char **argv) {
|
||||
bsgs_aux = mpz_get_ui(BSGS_AUX);
|
||||
DEBUGCOUNT = (uint64_t)((uint64_t)bsgs_m * (uint64_t)bsgs_aux);
|
||||
|
||||
printf("[+] Setting N up to %"PRIu64".\n",DEBUGCOUNT);
|
||||
printf("[+] Setting N up to %" PRIu64 ".\n",DEBUGCOUNT);
|
||||
|
||||
itemsbloom = ((uint64_t)(bsgs_m/256)) > 1000 ? (uint64_t)(bsgs_m/256) : 1000;
|
||||
itemsbloom2 = bsgs_m2 > 1000 ? bsgs_m : 1000;
|
||||
@@ -1076,7 +1088,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
if(continuebloom == 1) {
|
||||
if(bloom_loadcustom(&bloom_bPx2nd,"bPx2nd") == 1) {
|
||||
if(bloom_loadcustom(&bloom_bPx2nd,(char*)"bPx2nd") == 1) {
|
||||
continuebloom == 0;
|
||||
}
|
||||
else {
|
||||
@@ -1106,7 +1118,7 @@ int main(int argc, char **argv) {
|
||||
*/
|
||||
for(i=0; i< 256; i++) {
|
||||
if(bloom_init2(&bloom_bP[i],itemsbloom,0.000001) == 1){
|
||||
fprintf(stderr,"[E] error bloom_init [%"PRIu64"]\n",i);
|
||||
fprintf(stderr,"[E] error bloom_init [%" PRIu64 "]\n",i);
|
||||
exit(0);
|
||||
}
|
||||
bloom_bP_totalbytes += bloom_bP[i].bytes;
|
||||
@@ -1133,16 +1145,16 @@ int main(int argc, char **argv) {
|
||||
Scalar_Multiplication(G,&BSGS_MP,BSGS_M);
|
||||
Scalar_Multiplication(G,&BSGS_MP2,BSGS_M2);
|
||||
|
||||
printf("[+] Allocating %.1f MB for %"PRIu64" aMP Points\n",(double)(((double)(bsgs_aux*sizeof(struct Point)))/(double)1048576),bsgs_aux);
|
||||
printf("[+] Allocating %.1f MB for %" PRIu64 " aMP Points\n",(double)(((double)(bsgs_aux*sizeof(struct strPoint)))/(double)1048576),bsgs_aux);
|
||||
i = 0;
|
||||
BSGS_AMP = malloc((uint64_t)((uint64_t)bsgs_aux*(uint64_t)sizeof(struct Point)));
|
||||
BSGS_AMP = (struct strPoint*) malloc((uint64_t)((uint64_t)bsgs_aux*(uint64_t)sizeof(struct strPoint)));
|
||||
if(BSGS_AMP == NULL) {
|
||||
printf("[E] error malloc()\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//printf("[+] Allocating %.1f MB for aMP Points (2nd)\n",(float)(((uint64_t)(bsgs_m2*sizeof(struct Point)))/(uint64_t)1048576));
|
||||
BSGS_AMP2 = malloc((uint64_t)((uint64_t)bsgs_m2*(uint64_t)sizeof(struct Point)));
|
||||
//printf("[+] Allocating %.1f MB for aMP Points (2nd)\n",(float)(((uint64_t)(bsgs_m2*sizeof(struct strPoint)))/(uint64_t)1048576));
|
||||
BSGS_AMP2 = (struct strPoint*) malloc((uint64_t)((uint64_t)bsgs_m2*(uint64_t)sizeof(struct strPoint)));
|
||||
if(BSGS_AMP2 == NULL) {
|
||||
printf("[E] error malloc()\n");
|
||||
exit(0);
|
||||
@@ -1185,7 +1197,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("[+] Precalculating %"PRIu64" aMP points\n",bsgs_aux);
|
||||
printf("[+] Precalculating %" PRIu64 " aMP points\n",bsgs_aux);
|
||||
mpz_set(point_temp.x,BSGS_MP.x);
|
||||
mpz_set(point_temp.y,BSGS_MP.y);
|
||||
for(i = 0; i < bsgs_aux; i++) {
|
||||
@@ -1209,9 +1221,9 @@ int main(int argc, char **argv) {
|
||||
mpz_set(point_temp.x,point_temp2.x);
|
||||
mpz_set(point_temp.y,point_temp2.y);
|
||||
}
|
||||
printf("[+] Allocating %.2f MB for %"PRIu64 " bP Points\n",(double)((double)((uint64_t)bsgs_m2*(uint64_t)sizeof(struct bsgs_xvalue))/(double)1048576),bsgs_m2);
|
||||
printf("[+] Allocating %.2f MB for %" PRIu64 " bP Points\n",(double)((double)((uint64_t)bsgs_m2*(uint64_t)sizeof(struct bsgs_xvalue))/(double)1048576),bsgs_m2);
|
||||
//printf("[+] Allocating %.2f MB for bP Points\n",(float)((uint64_t)((uint64_t)bsgs_m*(uint64_t)sizeof(struct bsgs_xvalue))/(uint64_t)1048576));
|
||||
bPtable = calloc(bsgs_m2,sizeof(struct bsgs_xvalue));
|
||||
bPtable = (struct bsgs_xvalue*) calloc(bsgs_m2,sizeof(struct bsgs_xvalue));
|
||||
if(bPtable == NULL) {
|
||||
printf("[E] error malloc()\n");
|
||||
exit(0);
|
||||
@@ -1221,7 +1233,7 @@ int main(int argc, char **argv) {
|
||||
BASE = 0;
|
||||
PERTHREAD = bsgs_m /NTHREADS;
|
||||
PERTHREAD_R = bsgs_m % NTHREADS;
|
||||
temp = calloc(NTHREADS,sizeof(struct bPload));
|
||||
temp = (struct bPload *) calloc(NTHREADS,sizeof(struct bPload));
|
||||
tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t));
|
||||
|
||||
if(FLAGPRECALCUTED_P_FILE) {
|
||||
@@ -1284,7 +1296,7 @@ int main(int argc, char **argv) {
|
||||
tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t));
|
||||
DEBUGCOUNT = (uint64_t)((uint64_t)bsgs_m * (uint64_t)bsgs_aux);
|
||||
for(i= 0;i < NTHREADS; i++) {
|
||||
tt = malloc(sizeof(struct tothread));
|
||||
tt = (tothread*) malloc(sizeof(struct tothread));
|
||||
tt->nt = i;
|
||||
if(FLAGRANDOM) {
|
||||
s = pthread_create(&tid[i],NULL,thread_process_bsgs_random,(void *)tt);
|
||||
@@ -1306,7 +1318,7 @@ int main(int argc, char **argv) {
|
||||
tid = (pthread_t *) calloc(NTHREADS,sizeof(pthread_t));
|
||||
|
||||
for(i= 0;i < NTHREADS; i++) {
|
||||
tt = malloc(sizeof(struct tothread));
|
||||
tt = (tothread*) malloc(sizeof(struct tothread));
|
||||
tt->nt = i;
|
||||
steps[i] = 0;
|
||||
switch(FLAGMODE) {
|
||||
@@ -1329,7 +1341,7 @@ int main(int argc, char **argv) {
|
||||
mpz_init(total);
|
||||
mpz_init(pretotal);
|
||||
mpz_init(debugcount_mpz);
|
||||
sprintf(temporal,"%"PRIu64,DEBUGCOUNT);
|
||||
sprintf(temporal,"%" PRIu64 ,DEBUGCOUNT);
|
||||
//printf("[I] Debug count : %s\n",temporal);
|
||||
mpz_set_str(debugcount_mpz,temporal,10);
|
||||
seconds = 0;
|
||||
@@ -1358,10 +1370,10 @@ int main(int argc, char **argv) {
|
||||
mpz_fdiv_q_ui(pretotal,total,seconds);
|
||||
pthread_mutex_lock(&bsgs_thread);
|
||||
if(THREADOUTPUT == 1) {
|
||||
gmp_sprintf(buffer,"\nTotal %Zu keys in %"PRIu64 " seconds: %Zu keys/s\r",total,seconds,pretotal);
|
||||
gmp_sprintf(buffer,"\nTotal %Zu keys in %" PRIu64 " seconds: %Zu keys/s\r",total,seconds,pretotal);
|
||||
}
|
||||
else {
|
||||
gmp_sprintf(buffer,"\rTotal %Zu keys in %"PRIu64" seconds: %Zu keys/s\r",total,seconds,pretotal);
|
||||
gmp_sprintf(buffer,"\rTotal %Zu keys in %" PRIu64 " seconds: %Zu keys/s\r",total,seconds,pretotal);
|
||||
}
|
||||
printf("%s",buffer);
|
||||
fflush(stdout);
|
||||
@@ -1373,7 +1385,7 @@ int main(int argc, char **argv) {
|
||||
}while(continue_flag);
|
||||
}
|
||||
|
||||
void Point_Doubling(struct Point *P, struct Point *R) {
|
||||
void Point_Doubling(struct strPoint *P, struct strPoint *R) {
|
||||
mpz_t slope, temp;
|
||||
mpz_init(temp);
|
||||
mpz_init(slope);
|
||||
@@ -1400,7 +1412,7 @@ void Point_Doubling(struct Point *P, struct Point *R) {
|
||||
mpz_clear(slope);
|
||||
}
|
||||
|
||||
void Point_Addition(struct Point *P, struct Point *Q, struct Point *R) {
|
||||
void Point_Addition(struct strPoint *P, struct strPoint *Q, struct strPoint *R) {
|
||||
mpz_t PA_temp,PA_slope;
|
||||
mpz_init(PA_temp);
|
||||
mpz_init(PA_slope);
|
||||
@@ -1453,8 +1465,8 @@ void Point_Addition(struct Point *P, struct Point *Q, struct Point *R) {
|
||||
mpz_clear(PA_slope);
|
||||
}
|
||||
|
||||
void Scalar_Multiplication(struct Point P, struct Point *R, mpz_t m) {
|
||||
struct Point SM_T,SM_Q;
|
||||
void Scalar_Multiplication(struct strPoint P, struct strPoint *R, mpz_t m) {
|
||||
struct strPoint SM_T,SM_Q;
|
||||
int no_of_bits, i;
|
||||
no_of_bits = mpz_sizeinbase(m, 2);
|
||||
mpz_init_set_ui(SM_Q.x,0);
|
||||
@@ -1482,7 +1494,7 @@ void Scalar_Multiplication(struct Point P, struct Point *R, mpz_t m) {
|
||||
mpz_clear(SM_Q.y);
|
||||
}
|
||||
|
||||
void Point_Negation(struct Point *A, struct Point *S) {
|
||||
void Point_Negation(struct strPoint *A, struct strPoint *S) {
|
||||
mpz_sub(S->y, EC.p, A->y);
|
||||
mpz_set(S->x, A->x);
|
||||
}
|
||||
@@ -1490,7 +1502,7 @@ void Point_Negation(struct Point *A, struct Point *S) {
|
||||
/*
|
||||
Precalculate G Doublings for Scalar_Multiplication
|
||||
*/
|
||||
void init_doublingG(struct Point *P) {
|
||||
void init_doublingG(struct strPoint *P) {
|
||||
int i = 0;
|
||||
mpz_init(DoublingG[i].x);
|
||||
mpz_init(DoublingG[i].y);
|
||||
@@ -1527,8 +1539,8 @@ char *pubkeytopubaddress_eth(char *pkey,int length) {
|
||||
*/
|
||||
|
||||
char *pubkeytopubaddress(char *pkey,int length) {
|
||||
char *pubaddress = calloc(MAXLENGTHADDRESS+10,1);
|
||||
char *digest = calloc(60,1);
|
||||
char *pubaddress = (char*) calloc(MAXLENGTHADDRESS+10,1);
|
||||
char *digest = (char*) calloc(60,1);
|
||||
size_t pubaddress_size = MAXLENGTHADDRESS+10;
|
||||
if(pubaddress == NULL || digest == NULL) {
|
||||
fprintf(stderr,"error malloc()\n");
|
||||
@@ -1553,8 +1565,8 @@ char *pubkeytopubaddress(char *pkey,int length) {
|
||||
}
|
||||
|
||||
char *publickeytohashrmd160(char *pkey,int length) {
|
||||
char *hash160 = malloc(20);
|
||||
char *digest = malloc(32);
|
||||
char *hash160 = (char*) malloc(20);
|
||||
char *digest = (char*) malloc(32);
|
||||
if(hash160 == NULL || digest == NULL) {
|
||||
fprintf(stderr,"error malloc()\n");
|
||||
exit(0);
|
||||
@@ -1597,7 +1609,7 @@ int searchbinary(struct address_value *buffer,char *data,int64_t _N) {
|
||||
|
||||
void *thread_process(void *vargp) {
|
||||
struct tothread *tt;
|
||||
struct Point R,temporal;
|
||||
struct strPoint R,temporal;
|
||||
uint64_t count = 0;
|
||||
int r,thread_number,found,continue_flag = 1;
|
||||
char public_key_compressed[33],public_key_uncompressed[65],hexstrpoint[65];
|
||||
@@ -1679,7 +1691,7 @@ void *thread_process(void *vargp) {
|
||||
if(FLAGVANITY) {
|
||||
if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
if(strncmp(public_address_uncompressed,vanity,len_vanity) == 0) {
|
||||
hextemp = malloc(65);
|
||||
hextemp = (char*) malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
vanityKeys = fopen("vanitykeys.txt","a+");
|
||||
if(vanityKeys != NULL) {
|
||||
@@ -1692,7 +1704,7 @@ void *thread_process(void *vargp) {
|
||||
}
|
||||
if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){
|
||||
if(strncmp(public_address_compressed,vanity,len_vanity) == 0) {
|
||||
hextemp = malloc(65);
|
||||
hextemp = (char*) malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
vanityKeys = fopen("vanitykeys.txt","a+");
|
||||
if(vanityKeys != NULL) {
|
||||
@@ -1710,7 +1722,7 @@ void *thread_process(void *vargp) {
|
||||
r = searchbinary(addressTable,public_address_compressed,N);
|
||||
if(r) {
|
||||
found++;
|
||||
hextemp = malloc(65);
|
||||
hextemp = (char*) malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_compressed_hex = tohex(public_key_compressed,33);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
@@ -1734,7 +1746,7 @@ void *thread_process(void *vargp) {
|
||||
r = searchbinary(addressTable,public_address_uncompressed,N);
|
||||
if(r) {
|
||||
found++;
|
||||
hextemp = malloc(65);
|
||||
hextemp = (char*) malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_uncompressed_hex = tohex(public_key_uncompressed,65);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
@@ -1761,7 +1773,7 @@ void *thread_process(void *vargp) {
|
||||
if(r) {
|
||||
r = searchbinary(addressTable,public_address_uncompressed,N);
|
||||
if(r) {
|
||||
hextemp = malloc(65);
|
||||
hextemp = (char*) malloc(65);
|
||||
mpz_get_str(hextemp,16,key_mpz);
|
||||
public_key_uncompressed_hex = tohex(public_key_uncompressed+1,64);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
@@ -1800,7 +1812,7 @@ void *thread_process(void *vargp) {
|
||||
r = searchbinary(addressTable,publickeyhashrmd160_compress,N);
|
||||
if(r) {
|
||||
found++;
|
||||
hextemp = malloc(65);
|
||||
hextemp = (char*) malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_compressed_hex = tohex(public_key_compressed,33);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
@@ -1823,7 +1835,7 @@ void *thread_process(void *vargp) {
|
||||
r = searchbinary(addressTable,publickeyhashrmd160_uncompress,N);
|
||||
if(r) {
|
||||
found++;
|
||||
hextemp = malloc(65);
|
||||
hextemp = (char*) malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_uncompressed_hex = tohex(public_key_uncompressed,65);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
@@ -1847,7 +1859,7 @@ void *thread_process(void *vargp) {
|
||||
r = searchbinary(addressTable,public_key_compressed+1,N);
|
||||
if(r) {
|
||||
found++;
|
||||
hextemp = malloc(65);
|
||||
hextemp = (char*) malloc(65);
|
||||
gmp_sprintf(hextemp,"%0.64Zx",key_mpz);
|
||||
public_key_compressed_hex = tohex(public_key_compressed,33);
|
||||
pthread_mutex_lock(&write_keys);
|
||||
@@ -2124,7 +2136,7 @@ void *thread_process_bsgs(void *vargp) {
|
||||
char *aux_c;
|
||||
mpz_t base_key,keyfound;
|
||||
FILE *filekey;
|
||||
struct Point base_point,point_aux,point_aux2,point_found,BSGS_S,BSGS_Q,BSGS_Q_AMP;
|
||||
struct strPoint base_point,point_aux,point_aux2,point_found,BSGS_S,BSGS_Q,BSGS_Q_AMP;
|
||||
uint32_t i,j,k,r,salir,thread_number,bloom_counter =0;
|
||||
tt = (struct tothread *)vargp;
|
||||
thread_number = tt->nt;
|
||||
@@ -2245,7 +2257,7 @@ void *thread_process_bsgs(void *vargp) {
|
||||
mpz_set(base_key,BSGS_CURRENT);
|
||||
mpz_add(BSGS_CURRENT,BSGS_CURRENT,BSGS_N);
|
||||
pthread_mutex_unlock(&bsgs_thread);
|
||||
if(FLAGDEBUG ) printf("%u of %"PRIu64"\n",bloom_counter,(uint64_t)(bsgs_aux*bsgs_point_number));
|
||||
if(FLAGDEBUG ) printf("%u of %" PRIu64 "\n",bloom_counter,(uint64_t)(bsgs_aux*bsgs_point_number));
|
||||
bloom_counter = 0;
|
||||
}
|
||||
|
||||
@@ -2272,7 +2284,7 @@ void *thread_process_bsgs_random(void *vargp) {
|
||||
char *aux_c;
|
||||
mpz_t base_key,keyfound;
|
||||
FILE *filekey;
|
||||
struct Point base_point,point_aux,point_aux2,point_found,BSGS_S,BSGS_Q,BSGS_Q_AMP;
|
||||
struct strPoint base_point,point_aux,point_aux2,point_found,BSGS_S,BSGS_Q,BSGS_Q_AMP;
|
||||
mpz_t n_range_random;
|
||||
uint32_t i,j,k,r,salir,thread_number,bloom_counter = 0;
|
||||
tt = (struct tothread *)vargp;
|
||||
@@ -2392,7 +2404,7 @@ void *thread_process_bsgs_random(void *vargp) {
|
||||
mpz_urandomm (n_range_random,state,n_range_diff);
|
||||
mpz_add(base_key,n_range_start,n_range_random);
|
||||
pthread_mutex_unlock(&bsgs_thread);
|
||||
if(FLAGDEBUG ) printf("%u of %"PRIu64"\n",bloom_counter,(uint64_t)(bsgs_aux*bsgs_point_number));
|
||||
if(FLAGDEBUG ) printf("%u of %" PRIu64 "\n",bloom_counter,(uint64_t)(bsgs_aux*bsgs_point_number));
|
||||
bloom_counter = 0;
|
||||
}
|
||||
mpz_clear(BSGS_Q.x);
|
||||
@@ -2418,12 +2430,12 @@ void *thread_process_bsgs_random(void *vargp) {
|
||||
This funtion is made with the especific purpouse to USE a smaller bPTable in RAM.
|
||||
This new and small bPtable is around ~ squareroot( K *squareroot(N))
|
||||
*/
|
||||
int bsgs_secondcheck(mpz_t start_range,uint32_t a,struct Point *target,mpz_t *private) {
|
||||
int bsgs_secondcheck(mpz_t start_range,uint32_t a,struct strPoint *target,mpz_t *privatekey) {
|
||||
uint64_t j = 0;
|
||||
int i = 0,found = 0,r = 0;
|
||||
mpz_t base_key;
|
||||
struct Point base_point,point_aux;
|
||||
struct Point BSGS_Q, BSGS_S,BSGS_Q_AMP;
|
||||
struct strPoint base_point,point_aux;
|
||||
struct strPoint BSGS_Q, BSGS_S,BSGS_Q_AMP;
|
||||
char pubkey[131],xpoint_str[65],xpoint_raw[32];
|
||||
|
||||
mpz_init(base_key);
|
||||
@@ -2461,21 +2473,21 @@ int bsgs_secondcheck(mpz_t start_range,uint32_t a,struct Point *target,mpz_t *pr
|
||||
//printf("bsgs_searchbinary: %s\n",r ? "yes":"no");
|
||||
//printf("Current i: %u j: %llu, m: %llu\n",i,j,bsgs_m2);
|
||||
if(r) {
|
||||
mpz_set(*private,BSGS_M2);
|
||||
mpz_mul_ui(*private,*private,i);
|
||||
mpz_add_ui(*private,*private,j+1);
|
||||
mpz_add(*private,*private,base_key);
|
||||
Scalar_Multiplication(G,&point_aux,*private);
|
||||
//gmp_printf("private 1: %0.64Zx\n",*private);
|
||||
mpz_set(*privatekey,BSGS_M2);
|
||||
mpz_mul_ui(*privatekey,*privatekey,i);
|
||||
mpz_add_ui(*privatekey,*privatekey,j+1);
|
||||
mpz_add(*privatekey,*privatekey,base_key);
|
||||
Scalar_Multiplication(G,&point_aux,*privatekey);
|
||||
//gmp_printf("privatekey 1: %0.64Zx\n",*privatekey);
|
||||
if(mpz_cmp(point_aux.x,target->x) == 0) {
|
||||
found = 1;
|
||||
}
|
||||
else {
|
||||
mpz_set(*private,BSGS_M2);
|
||||
mpz_mul_ui(*private,*private,i);
|
||||
mpz_sub_ui(*private,*private,j+1);
|
||||
mpz_add(*private,*private,base_key);
|
||||
//gmp_printf("private 2: %0.64Zx\n",*private);
|
||||
mpz_set(*privatekey,BSGS_M2);
|
||||
mpz_mul_ui(*privatekey,*privatekey,i);
|
||||
mpz_sub_ui(*privatekey,*privatekey,j+1);
|
||||
mpz_add(*privatekey,*privatekey,base_key);
|
||||
//gmp_printf("privatekey 2: %0.64Zx\n",*privatekey);
|
||||
if(mpz_cmp(point_aux.x,target->x) == 0) {
|
||||
found = 1;
|
||||
}
|
||||
@@ -2487,7 +2499,6 @@ int bsgs_secondcheck(mpz_t start_range,uint32_t a,struct Point *target,mpz_t *pr
|
||||
mpz_set(BSGS_S.y,BSGS_Q_AMP.y);
|
||||
i++;
|
||||
}while(i < 20 && !found);
|
||||
|
||||
mpz_clear(base_key);
|
||||
mpz_clear(base_point.x);
|
||||
mpz_clear(base_point.y);
|
||||
@@ -2503,27 +2514,25 @@ int bsgs_secondcheck(mpz_t start_range,uint32_t a,struct Point *target,mpz_t *pr
|
||||
}
|
||||
|
||||
void *thread_bPload(void *vargp) {
|
||||
char *hextemp;
|
||||
char hexvalue[65],rawvalue[32];
|
||||
struct bPload *tt;
|
||||
struct Point P,temp;
|
||||
mpz_t base;
|
||||
uint32_t j;
|
||||
uint64_t i;
|
||||
Int keybase;
|
||||
Point P;
|
||||
tt = (struct bPload *)vargp;
|
||||
mpz_init(base);
|
||||
mpz_init(P.x);
|
||||
mpz_init(P.y);
|
||||
mpz_init(temp.x);
|
||||
mpz_init(temp.y);
|
||||
mpz_set_ui(base,tt->from);
|
||||
Scalar_Multiplication(G,&P,base);
|
||||
keybase.SetInt64(tt->from);
|
||||
P = secp->ComputePublicKey(&keybase);
|
||||
i = tt->from -1;
|
||||
j = tt->from -1;
|
||||
do {
|
||||
mpz_set(temp.x,P.x);
|
||||
mpz_set(temp.y,P.y);
|
||||
gmp_sprintf(hexvalue,"%0.64Zx",P.x);
|
||||
hexs2bin(hexvalue,(unsigned char*) rawvalue );
|
||||
P.x.Get32Bytes((unsigned char*)rawvalue);
|
||||
/*
|
||||
hextemp = tohex(rawvalue,32);
|
||||
printf("%s\n",hextemp);
|
||||
free(hextemp);
|
||||
*/
|
||||
if(i < bsgs_m2) {
|
||||
memcpy(bPtable[j].value,rawvalue+16,BSGS_XVALUE_RAM);
|
||||
bPtable[j].index = j;
|
||||
@@ -2531,15 +2540,17 @@ void *thread_bPload(void *vargp) {
|
||||
j++;
|
||||
}
|
||||
bloom_add(&bloom_bP[((uint8_t)rawvalue[0])], rawvalue ,BSGS_BUFFERXPOINTLENGTH);
|
||||
Point_Addition(&G,&temp,&P);
|
||||
if(secp->G.equals(P)) {
|
||||
//printf("Is G\n");
|
||||
P = secp->DoubleDirect(P);
|
||||
}
|
||||
else {
|
||||
//printf("Not G\n");
|
||||
P = secp->NextKey(P);
|
||||
}
|
||||
i++;
|
||||
tt->counter++;
|
||||
} while( i < tt->to );
|
||||
mpz_clear(base);
|
||||
mpz_clear(P.x);
|
||||
mpz_clear(P.y);
|
||||
mpz_clear(temp.x);
|
||||
mpz_clear(temp.y);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
@@ -2558,7 +2569,7 @@ void *thread_bPloadFile(void *vargp) {
|
||||
i = tt->from -1;
|
||||
j = tt->from -1;
|
||||
if(fseek(fd,(uint64_t)(i*32),SEEK_SET) != 0) {
|
||||
fprintf(stderr,"Can't seek the file at index %"PRIu64", offset %"PRIu64"\n",i,(uint64_t)(i*32));
|
||||
fprintf(stderr,"Can't seek the file at index %" PRIu64 ", offset %" PRIu64 "\n",i,(uint64_t)(i*32));
|
||||
exit(0);
|
||||
}
|
||||
do {
|
||||
@@ -2628,7 +2639,7 @@ void *thread_pub2rmd(void *vargp) {
|
||||
}
|
||||
}
|
||||
if(pub2rmd_continue) {
|
||||
temphex = malloc(65);
|
||||
temphex = (char*) malloc(65);
|
||||
gmp_sprintf(temphex,"%0.64Zx",key_mpz);
|
||||
hexs2bin(temphex,pub.X.data8);
|
||||
free(temphex);
|
||||
|
1057
secp256k1/Int.cpp
Normal file
1057
secp256k1/Int.cpp
Normal file
File diff suppressed because it is too large
Load Diff
295
secp256k1/Int.h
Normal file
295
secp256k1/Int.h
Normal file
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* This file is part of the BSGS distribution (https://github.com/JeanLucPons/BSGS).
|
||||
* Copyright (c) 2020 Jean Luc PONS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Big integer class (Fixed size)
|
||||
|
||||
#ifndef BIGINTH
|
||||
#define BIGINTH
|
||||
|
||||
#include "Random.h"
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
// We need 1 extra block for Knuth div algorithm , Montgomery multiplication and ModInv
|
||||
#define BISIZE 256
|
||||
|
||||
#if BISIZE==256
|
||||
#define NB64BLOCK 5
|
||||
#define NB32BLOCK 10
|
||||
#elif BISIZE==512
|
||||
#define NB64BLOCK 9
|
||||
#define NB32BLOCK 18
|
||||
#else
|
||||
#error Unsuported size
|
||||
#endif
|
||||
|
||||
class Int {
|
||||
|
||||
public:
|
||||
|
||||
Int();
|
||||
Int(int64_t i64);
|
||||
Int(uint64_t u64);
|
||||
Int(Int *a);
|
||||
|
||||
// Op
|
||||
void Add(uint64_t a);
|
||||
void Add(Int *a);
|
||||
void Add(Int *a,Int *b);
|
||||
void AddOne();
|
||||
void Sub(uint64_t a);
|
||||
void Sub(Int *a);
|
||||
void Sub(Int *a, Int *b);
|
||||
void SubOne();
|
||||
void Mult(Int *a);
|
||||
void Mult(uint64_t a);
|
||||
void IMult(int64_t a);
|
||||
void Mult(Int *a,uint64_t b);
|
||||
void IMult(Int *a, int64_t b);
|
||||
void Mult(Int *a,Int *b);
|
||||
void Div(Int *a,Int *mod = NULL);
|
||||
void MultModN(Int *a, Int *b, Int *n);
|
||||
void Neg();
|
||||
void Abs();
|
||||
|
||||
// Right shift (signed)
|
||||
void ShiftR(uint32_t n);
|
||||
void ShiftR32Bit();
|
||||
void ShiftR64Bit();
|
||||
// Left shift
|
||||
void ShiftL(uint32_t n);
|
||||
void ShiftL32Bit();
|
||||
void ShiftL64Bit();
|
||||
|
||||
// Comp
|
||||
bool IsGreater(Int *a);
|
||||
bool IsGreaterOrEqual(Int *a);
|
||||
bool IsLowerOrEqual(Int *a);
|
||||
bool IsLower(Int *a);
|
||||
bool IsEqual(Int *a);
|
||||
bool IsZero();
|
||||
bool IsOne();
|
||||
bool IsStrictPositive();
|
||||
bool IsPositive();
|
||||
bool IsNegative();
|
||||
bool IsEven();
|
||||
bool IsOdd();
|
||||
|
||||
// Modular arithmetic
|
||||
|
||||
// Setup field
|
||||
// n is the field characteristic
|
||||
// R used in Montgomery mult (R = 2^size(n))
|
||||
// R2 = R^2, R3 = R^3, R4 = R^4
|
||||
static void SetupField(Int *n, Int *R = NULL, Int *R2 = NULL, Int *R3 = NULL, Int *R4 = NULL);
|
||||
static Int *GetR(); // Return R
|
||||
static Int *GetR2(); // Return R2
|
||||
static Int *GetR3(); // Return R3
|
||||
static Int *GetR4(); // Return R4
|
||||
static Int* GetFieldCharacteristic(); // Return field characteristic
|
||||
|
||||
void GCD(Int *a); // this <- GCD(this,a)
|
||||
void Mod(Int *n); // this <- this (mod n)
|
||||
void ModInv(); // this <- this^-1 (mod n)
|
||||
void MontgomeryMult(Int *a,Int *b); // this <- a*b*R^-1 (mod n)
|
||||
void MontgomeryMult(Int *a); // this <- this*a*R^-1 (mod n)
|
||||
void ModAdd(Int *a); // this <- this+a (mod n) [0<a<P]
|
||||
void ModAdd(Int *a,Int *b); // this <- a+b (mod n) [0<a,b<P]
|
||||
void ModAdd(uint64_t a); // this <- this+a (mod n) [0<a<P]
|
||||
void ModSub(Int *a); // this <- this-a (mod n) [0<a<P]
|
||||
void ModSub(Int *a, Int *b); // this <- a-b (mod n) [0<a,b<P]
|
||||
void ModSub(uint64_t a); // this <- this-a (mod n) [0<a<P]
|
||||
void ModMul(Int *a,Int *b); // this <- a*b (mod n)
|
||||
void ModMul(Int *a); // this <- this*b (mod n)
|
||||
void ModSquare(Int *a); // this <- a^2 (mod n)
|
||||
void ModCube(Int *a); // this <- a^3 (mod n)
|
||||
void ModDouble(); // this <- 2*this (mod n)
|
||||
void ModExp(Int *e); // this <- this^e (mod n)
|
||||
void ModNeg(); // this <- -this (mod n)
|
||||
void ModSqrt(); // this <- +/-sqrt(this) (mod n)
|
||||
bool HasSqrt(); // true if this admit a square root
|
||||
|
||||
// Specific SecpK1
|
||||
static void InitK1(Int *order);
|
||||
void ModMulK1(Int *a, Int *b);
|
||||
void ModMulK1(Int *a);
|
||||
void ModMulK1order(Int *a);
|
||||
void ModSquareK1(Int *a);
|
||||
void ModAddK1order(Int *a,Int *b);
|
||||
|
||||
// Size
|
||||
int GetSize();
|
||||
int GetBitLength();
|
||||
|
||||
// Setter
|
||||
void SetInt64(uint64_t value);
|
||||
void SetInt32(uint32_t value);
|
||||
void Set(Int *a);
|
||||
void SetBase10(char *value);
|
||||
void SetBase16(char *value);
|
||||
void SetBaseN(int n,char *charset,char *value);
|
||||
void SetByte(int n,unsigned char byte);
|
||||
void SetDWord(int n, uint32_t b);
|
||||
void SetQWord(int n,uint64_t b);
|
||||
void Rand(int nbit);
|
||||
void Set32Bytes(unsigned char *bytes);
|
||||
void MaskByte(int n);
|
||||
|
||||
// Getter
|
||||
uint32_t GetInt32();
|
||||
int GetBit(uint32_t n);
|
||||
unsigned char GetByte(int n);
|
||||
void Get32Bytes(unsigned char *buff);
|
||||
|
||||
char* GetBase2();
|
||||
char* GetBase10();
|
||||
char* GetBase16();
|
||||
char* GetBaseN(int n,char *charset);
|
||||
char* GetBlockStr();
|
||||
char* GetC64Str(int nbDigit);
|
||||
|
||||
// Check function
|
||||
//static void Check();
|
||||
|
||||
/*
|
||||
// Align to 16 bytes boundary
|
||||
union {
|
||||
__declspec(align(16)) uint32_t bits[NB32BLOCK];
|
||||
__declspec(align(16)) uint64_t bits64[NB64BLOCK];
|
||||
};
|
||||
*/
|
||||
union {
|
||||
uint32_t bits[NB32BLOCK];
|
||||
uint64_t bits64[NB64BLOCK];
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
void ShiftL32BitAndSub(Int *a,int n);
|
||||
uint64_t AddC(Int *a);
|
||||
void AddAndShift(Int *a, Int *b,uint64_t cH);
|
||||
void Mult(Int *a, uint32_t b);
|
||||
int GetLowestBit();
|
||||
void CLEAR();
|
||||
void CLEARFF();
|
||||
|
||||
|
||||
};
|
||||
|
||||
// Inline routines
|
||||
|
||||
#ifndef WIN64
|
||||
|
||||
// Missing intrinsics
|
||||
static uint64_t inline _umul128(uint64_t a, uint64_t b, uint64_t *h) {
|
||||
uint64_t rhi;
|
||||
uint64_t rlo;
|
||||
__asm__( "mulq %[b];" :"=d"(rhi),"=a"(rlo) :"1"(a),[b]"rm"(b));
|
||||
*h = rhi;
|
||||
return rlo;
|
||||
}
|
||||
|
||||
static uint64_t inline __shiftright128(uint64_t a, uint64_t b,unsigned char n) {
|
||||
uint64_t c;
|
||||
__asm__ ("movq %1,%0;shrdq %3,%2,%0;" : "=D"(c) : "r"(a),"r"(b),"c"(n));
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static uint64_t inline __shiftleft128(uint64_t a, uint64_t b,unsigned char n) {
|
||||
uint64_t c;
|
||||
__asm__ ("movq %1,%0;shldq %3,%2,%0;" : "=D"(c) : "r"(b),"r"(a),"c"(n));
|
||||
return c;
|
||||
}
|
||||
|
||||
#define _subborrow_u64(a,b,c,d) __builtin_ia32_sbb_u64(a,b,c,(long long unsigned int*)d);
|
||||
#define _addcarry_u64(a,b,c,d) __builtin_ia32_addcarryx_u64(a,b,c,(long long unsigned int*)d);
|
||||
#define _byteswap_uint64 __builtin_bswap64
|
||||
#else
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
static void inline imm_mul(uint64_t *x, uint64_t y, uint64_t *dst) {
|
||||
|
||||
unsigned char c = 0;
|
||||
uint64_t h, carry;
|
||||
dst[0] = _umul128(x[0], y, &h); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[1], y, &h), carry, dst + 1); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[2], y, &h), carry, dst + 2); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[3], y, &h), carry, dst + 3); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[4], y, &h), carry, dst + 4); carry = h;
|
||||
#if NB64BLOCK > 5
|
||||
c = _addcarry_u64(c, _umul128(x[5], y, &h), carry, dst + 5); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[6], y, &h), carry, dst + 6); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[7], y, &h), carry, dst + 7); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[8], y, &h), carry, dst + 8); carry = h;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void inline imm_umul(uint64_t *x, uint64_t y, uint64_t *dst) {
|
||||
|
||||
// Assume that x[NB64BLOCK-1] is 0
|
||||
unsigned char c = 0;
|
||||
uint64_t h, carry;
|
||||
dst[0] = _umul128(x[0], y, &h); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[1], y, &h), carry, dst + 1); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[2], y, &h), carry, dst + 2); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[3], y, &h), carry, dst + 3); carry = h;
|
||||
#if NB64BLOCK > 5
|
||||
c = _addcarry_u64(c, _umul128(x[4], y, &h), carry, dst + 4); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[5], y, &h), carry, dst + 5); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[6], y, &h), carry, dst + 6); carry = h;
|
||||
c = _addcarry_u64(c, _umul128(x[7], y, &h), carry, dst + 7); carry = h;
|
||||
#endif
|
||||
_addcarry_u64(c, 0ULL, carry, dst + (NB64BLOCK - 1));
|
||||
|
||||
}
|
||||
|
||||
static void inline shiftR(unsigned char n, uint64_t *d) {
|
||||
|
||||
d[0] = __shiftright128(d[0], d[1], n);
|
||||
d[1] = __shiftright128(d[1], d[2], n);
|
||||
d[2] = __shiftright128(d[2], d[3], n);
|
||||
d[3] = __shiftright128(d[3], d[4], n);
|
||||
#if NB64BLOCK > 5
|
||||
d[4] = __shiftright128(d[4], d[5], n);
|
||||
d[5] = __shiftright128(d[5], d[6], n);
|
||||
d[6] = __shiftright128(d[6], d[7], n);
|
||||
d[7] = __shiftright128(d[7], d[8], n);
|
||||
#endif
|
||||
d[NB64BLOCK-1] = ((int64_t)d[NB64BLOCK-1]) >> n;
|
||||
|
||||
}
|
||||
|
||||
static void inline shiftL(unsigned char n, uint64_t *d) {
|
||||
|
||||
#if NB64BLOCK > 5
|
||||
d[8] = __shiftleft128(d[7], d[8], n);
|
||||
d[7] = __shiftleft128(d[6], d[7], n);
|
||||
d[6] = __shiftleft128(d[5], d[6], n);
|
||||
d[5] = __shiftleft128(d[4], d[5], n);
|
||||
#endif
|
||||
d[4] = __shiftleft128(d[3], d[4], n);
|
||||
d[3] = __shiftleft128(d[2], d[3], n);
|
||||
d[2] = __shiftleft128(d[1], d[2], n);
|
||||
d[1] = __shiftleft128(d[0], d[1], n);
|
||||
d[0] = d[0] << n;
|
||||
|
||||
}
|
||||
|
||||
#endif // BIGINTH
|
58
secp256k1/IntGroup.cpp
Normal file
58
secp256k1/IntGroup.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of the BSGS distribution (https://github.com/JeanLucPons/BSGS).
|
||||
* Copyright (c) 2020 Jean Luc PONS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "IntGroup.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
IntGroup::IntGroup(int size) {
|
||||
this->size = size;
|
||||
subp = (Int *)malloc(size * sizeof(Int));
|
||||
}
|
||||
|
||||
IntGroup::~IntGroup() {
|
||||
free(subp);
|
||||
}
|
||||
|
||||
void IntGroup::Set(Int *pts) {
|
||||
ints = pts;
|
||||
}
|
||||
|
||||
// Compute modular inversion of the whole group
|
||||
void IntGroup::ModInv() {
|
||||
|
||||
Int newValue;
|
||||
Int inverse;
|
||||
|
||||
subp[0].Set(&ints[0]);
|
||||
for (int i = 1; i < size; i++) {
|
||||
subp[i].ModMulK1(&subp[i - 1], &ints[i]);
|
||||
}
|
||||
|
||||
// Do the inversion
|
||||
inverse.Set(&subp[size - 1]);
|
||||
inverse.ModInv();
|
||||
|
||||
for (int i = size - 1; i > 0; i--) {
|
||||
newValue.ModMulK1(&subp[i - 1], &inverse);
|
||||
inverse.ModMulK1(&ints[i]);
|
||||
ints[i].Set(&newValue);
|
||||
}
|
||||
|
||||
ints[0].Set(&inverse);
|
||||
|
||||
}
|
41
secp256k1/IntGroup.h
Normal file
41
secp256k1/IntGroup.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is part of the BSGS distribution (https://github.com/JeanLucPons/BSGS).
|
||||
* Copyright (c) 2020 Jean Luc PONS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INTGROUPH
|
||||
#define INTGROUPH
|
||||
|
||||
#include "Int.h"
|
||||
#include <vector>
|
||||
|
||||
class IntGroup {
|
||||
|
||||
public:
|
||||
|
||||
IntGroup(int size);
|
||||
~IntGroup();
|
||||
void Set(Int *pts);
|
||||
void ModInv();
|
||||
|
||||
private:
|
||||
|
||||
Int *ints;
|
||||
Int *subp;
|
||||
int size;
|
||||
|
||||
};
|
||||
|
||||
#endif // INTGROUPCPUH
|
1169
secp256k1/IntMod.cpp
Normal file
1169
secp256k1/IntMod.cpp
Normal file
File diff suppressed because it is too large
Load Diff
89
secp256k1/Point.cpp
Normal file
89
secp256k1/Point.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* This file is part of the BSGS distribution (https://github.com/JeanLucPons/BSGS).
|
||||
* Copyright (c) 2020 Jean Luc PONS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Point.h"
|
||||
|
||||
Point::Point() {
|
||||
}
|
||||
|
||||
Point::Point(const Point &p) {
|
||||
x.Set((Int *)&p.x);
|
||||
y.Set((Int *)&p.y);
|
||||
z.Set((Int *)&p.z);
|
||||
}
|
||||
|
||||
Point::Point(Int *cx,Int *cy,Int *cz) {
|
||||
x.Set(cx);
|
||||
y.Set(cy);
|
||||
z.Set(cz);
|
||||
}
|
||||
|
||||
Point::Point(Int *cx, Int *cz) {
|
||||
x.Set(cx);
|
||||
z.Set(cz);
|
||||
}
|
||||
|
||||
void Point::Clear() {
|
||||
x.SetInt32(0);
|
||||
y.SetInt32(0);
|
||||
z.SetInt32(0);
|
||||
}
|
||||
|
||||
void Point::Set(Int *cx, Int *cy,Int *cz) {
|
||||
x.Set(cx);
|
||||
y.Set(cy);
|
||||
z.Set(cz);
|
||||
}
|
||||
|
||||
Point::~Point() {
|
||||
}
|
||||
|
||||
void Point::Set(Point &p) {
|
||||
x.Set(&p.x);
|
||||
y.Set(&p.y);
|
||||
}
|
||||
|
||||
bool Point::isZero() {
|
||||
return x.IsZero() && y.IsZero();
|
||||
}
|
||||
|
||||
void Point::Reduce() {
|
||||
|
||||
Int i(&z);
|
||||
i.ModInv();
|
||||
x.ModMul(&x,&i);
|
||||
y.ModMul(&y,&i);
|
||||
z.SetInt32(1);
|
||||
|
||||
}
|
||||
|
||||
bool Point::equals(Point &p) {
|
||||
return x.IsEqual(&p.x) && y.IsEqual(&p.y) && z.IsEqual(&p.z);
|
||||
}
|
||||
|
||||
/*
|
||||
std::string Point::toString() {
|
||||
|
||||
std::string ret;
|
||||
ret = "X=" + x.GetBase16() + "\n";
|
||||
ret += "Y=" + y.GetBase16() + "\n";
|
||||
ret += "Z=" + z.GetBase16() + "\n";
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
*/
|
46
secp256k1/Point.h
Normal file
46
secp256k1/Point.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of the BSGS distribution (https://github.com/JeanLucPons/BSGS).
|
||||
* Copyright (c) 2020 Jean Luc PONS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef POINTH
|
||||
#define POINTH
|
||||
|
||||
#include "Int.h"
|
||||
|
||||
class Point {
|
||||
|
||||
public:
|
||||
|
||||
Point();
|
||||
Point(Int *cx,Int *cy,Int *cz);
|
||||
Point(Int *cx, Int *cz);
|
||||
Point(const Point &p);
|
||||
~Point();
|
||||
bool isZero();
|
||||
bool equals(Point &p);
|
||||
void Set(Point &p);
|
||||
void Set(Int *cx, Int *cy,Int *cz);
|
||||
void Clear();
|
||||
void Reduce();
|
||||
//std::string toString();
|
||||
|
||||
Int x;
|
||||
Int y;
|
||||
Int z;
|
||||
|
||||
};
|
||||
|
||||
#endif // POINTH
|
117
secp256k1/Random.cpp
Normal file
117
secp256k1/Random.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* This file is part of the BSGS distribution (https://github.com/JeanLucPons/BSGS).
|
||||
* Copyright (c) 2020 Jean Luc PONS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Random.h"
|
||||
|
||||
#define RK_STATE_LEN 624
|
||||
|
||||
/* State of the RNG */
|
||||
typedef struct rk_state_
|
||||
{
|
||||
unsigned long key[RK_STATE_LEN];
|
||||
int pos;
|
||||
} rk_state;
|
||||
|
||||
rk_state localState;
|
||||
|
||||
/* Maximum generated random value */
|
||||
#define RK_MAX 0xFFFFFFFFUL
|
||||
|
||||
void rk_seed(unsigned long seed, rk_state *state)
|
||||
{
|
||||
int pos;
|
||||
seed &= 0xffffffffUL;
|
||||
|
||||
/* Knuth's PRNG as used in the Mersenne Twister reference implementation */
|
||||
for (pos=0; pos<RK_STATE_LEN; pos++)
|
||||
{
|
||||
state->key[pos] = seed;
|
||||
seed = (1812433253UL * (seed ^ (seed >> 30)) + pos + 1) & 0xffffffffUL;
|
||||
}
|
||||
|
||||
state->pos = RK_STATE_LEN;
|
||||
}
|
||||
|
||||
/* Magic Mersenne Twister constants */
|
||||
#define N 624
|
||||
#define M 397
|
||||
#define MATRIX_A 0x9908b0dfUL
|
||||
#define UPPER_MASK 0x80000000UL
|
||||
#define LOWER_MASK 0x7fffffffUL
|
||||
|
||||
#ifdef WIN32
|
||||
// Disable "unary minus operator applied to unsigned type, result still unsigned" warning.
|
||||
#pragma warning(disable : 4146)
|
||||
#endif
|
||||
|
||||
/* Slightly optimised reference implementation of the Mersenne Twister */
|
||||
inline unsigned long rk_random(rk_state *state)
|
||||
{
|
||||
unsigned long y;
|
||||
|
||||
if (state->pos == RK_STATE_LEN)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<N-M;i++)
|
||||
{
|
||||
y = (state->key[i] & UPPER_MASK) | (state->key[i+1] & LOWER_MASK);
|
||||
state->key[i] = state->key[i+M] ^ (y>>1) ^ (-(y & 1) & MATRIX_A);
|
||||
}
|
||||
for (;i<N-1;i++)
|
||||
{
|
||||
y = (state->key[i] & UPPER_MASK) | (state->key[i+1] & LOWER_MASK);
|
||||
state->key[i] = state->key[i+(M-N)] ^ (y>>1) ^ (-(y & 1) & MATRIX_A);
|
||||
}
|
||||
y = (state->key[N-1] & UPPER_MASK) | (state->key[0] & LOWER_MASK);
|
||||
state->key[N-1] = state->key[M-1] ^ (y>>1) ^ (-(y & 1) & MATRIX_A);
|
||||
|
||||
state->pos = 0;
|
||||
}
|
||||
|
||||
y = state->key[state->pos++];
|
||||
|
||||
/* Tempering */
|
||||
y ^= (y >> 11);
|
||||
y ^= (y << 7) & 0x9d2c5680UL;
|
||||
y ^= (y << 15) & 0xefc60000UL;
|
||||
y ^= (y >> 18);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
inline double rk_double(rk_state *state)
|
||||
{
|
||||
/* shifts : 67108864 = 0x4000000, 9007199254740992 = 0x20000000000000 */
|
||||
long a = rk_random(state) >> 5, b = rk_random(state) >> 6;
|
||||
return (a * 67108864.0 + b) / 9007199254740992.0;
|
||||
}
|
||||
|
||||
// Initialise the random generator with the specified seed
|
||||
void rseed(unsigned long seed) {
|
||||
rk_seed(seed,&localState);
|
||||
//srand(seed);
|
||||
}
|
||||
|
||||
unsigned long rndl() {
|
||||
return rk_random(&localState);
|
||||
}
|
||||
|
||||
// Returns a uniform distributed double value in the interval ]0,1[
|
||||
double rnd() {
|
||||
return rk_double(&localState);
|
||||
}
|
25
secp256k1/Random.h
Normal file
25
secp256k1/Random.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* This file is part of the BSGS distribution (https://github.com/JeanLucPons/BSGS).
|
||||
* Copyright (c) 2020 Jean Luc PONS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RANDOM_H
|
||||
#define RANDOM_H
|
||||
|
||||
double rnd();
|
||||
unsigned long rndl();
|
||||
void rseed(unsigned long seed);
|
||||
|
||||
#endif
|
422
secp256k1/SECP256K1.cpp
Normal file
422
secp256k1/SECP256K1.cpp
Normal file
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* This file is part of the BSGS distribution (https://github.com/JeanLucPons/BSGS).
|
||||
* Copyright (c) 2020 Jean Luc PONS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include "SECP256k1.h"
|
||||
#include "util.h"
|
||||
|
||||
Secp256K1::Secp256K1() {
|
||||
}
|
||||
|
||||
void Secp256K1::Init() {
|
||||
// Prime for the finite field
|
||||
Int P;
|
||||
P.SetBase16("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F");
|
||||
|
||||
// Set up field
|
||||
Int::SetupField(&P);
|
||||
|
||||
// Generator point and order
|
||||
G.x.SetBase16("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798");
|
||||
G.y.SetBase16("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
|
||||
G.z.SetInt32(1);
|
||||
order.SetBase16("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
|
||||
|
||||
Int::InitK1(&order);
|
||||
|
||||
// Compute Generator table
|
||||
Point N(G);
|
||||
for(int i = 0; i < 32; i++) {
|
||||
GTable[i * 256] = N;
|
||||
N = DoubleDirect(N);
|
||||
for (int j = 1; j < 255; j++) {
|
||||
GTable[i * 256 + j] = N;
|
||||
N = AddDirect(N, GTable[i * 256]);
|
||||
}
|
||||
GTable[i * 256 + 255] = N; // Dummy point for check function
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Secp256K1::~Secp256K1() {
|
||||
}
|
||||
|
||||
Point Secp256K1::ComputePublicKey(Int *privKey) {
|
||||
int i = 0;
|
||||
uint8_t b;
|
||||
Point Q;
|
||||
Q.Clear();
|
||||
// Search first significant byte
|
||||
for (i = 0; i < 32; i++) {
|
||||
b = privKey->GetByte(i);
|
||||
if(b)
|
||||
break;
|
||||
}
|
||||
Q = GTable[256 * i + (b-1)];
|
||||
i++;
|
||||
|
||||
for(; i < 32; i++) {
|
||||
b = privKey->GetByte(i);
|
||||
if(b)
|
||||
Q = Add2(Q, GTable[256 * i + (b-1)]);
|
||||
}
|
||||
Q.Reduce();
|
||||
return Q;
|
||||
}
|
||||
|
||||
Point Secp256K1::NextKey(Point &key) {
|
||||
// Input key must be reduced and different from G
|
||||
// in order to use AddDirect
|
||||
return AddDirect(key,G);
|
||||
}
|
||||
|
||||
uint8_t Secp256K1::GetByte(char *str, int idx) {
|
||||
char tmp[3];
|
||||
int val;
|
||||
tmp[0] = str[2 * idx];
|
||||
tmp[1] = str[2 * idx + 1];
|
||||
tmp[2] = 0;
|
||||
if (sscanf(tmp, "%X", &val) != 1) {
|
||||
printf("ParsePublicKeyHex: Error invalid public key specified (unexpected hexadecimal digit)\n");
|
||||
exit(-1);
|
||||
}
|
||||
return (uint8_t)val;
|
||||
}
|
||||
|
||||
bool Secp256K1::ParsePublicKeyHex(char *str,Point &ret,bool &isCompressed) {
|
||||
int len = strlen(str);
|
||||
ret.Clear();
|
||||
if (len < 2) {
|
||||
printf("ParsePublicKeyHex: Error invalid public key specified (66 or 130 character length)\n");
|
||||
return false;
|
||||
}
|
||||
uint8_t type = GetByte(str, 0);
|
||||
switch (type) {
|
||||
case 0x02:
|
||||
if (len != 66) {
|
||||
printf("ParsePublicKeyHex: Error invalid public key specified (66 character length)\n");
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
ret.x.SetByte(31 - i, GetByte(str, i + 1));
|
||||
ret.y = GetY(ret.x, true);
|
||||
isCompressed = true;
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
if (len != 66) {
|
||||
printf("ParsePublicKeyHex: Error invalid public key specified (66 character length)\n");
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
ret.x.SetByte(31 - i, GetByte(str, i + 1));
|
||||
ret.y = GetY(ret.x, false);
|
||||
isCompressed = true;
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
if (len != 130) {
|
||||
printf("ParsePublicKeyHex: Error invalid public key specified (130 character length)\n");
|
||||
exit(-1);
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
ret.x.SetByte(31 - i, GetByte(str, i + 1));
|
||||
for (int i = 0; i < 32; i++)
|
||||
ret.y.SetByte(31 - i, GetByte(str, i + 33));
|
||||
isCompressed = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ParsePublicKeyHex: Error invalid public key specified (Unexpected prefix (only 02,03 or 04 allowed)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ret.z.SetInt32(1);
|
||||
|
||||
if (!EC(ret)) {
|
||||
printf("ParsePublicKeyHex: Error invalid public key specified (Not lie on elliptic curve)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char* Secp256K1::GetPublicKeyHex(bool compressed, Point &pubKey) {
|
||||
unsigned char publicKeyBytes[128];
|
||||
char *ret;
|
||||
if (!compressed) {
|
||||
//Uncompressed public key
|
||||
publicKeyBytes[0] = 0x4;
|
||||
pubKey.x.Get32Bytes(publicKeyBytes + 1);
|
||||
pubKey.y.Get32Bytes(publicKeyBytes + 33);
|
||||
ret = (char*) tohex((char*)publicKeyBytes,65);
|
||||
}
|
||||
else {
|
||||
// Compressed public key
|
||||
publicKeyBytes[0] = pubKey.y.IsEven() ? 0x2 : 0x3;
|
||||
pubKey.x.Get32Bytes(publicKeyBytes + 1);
|
||||
ret = (char*) tohex((char*)publicKeyBytes,33);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Point Secp256K1::AddDirect(Point &p1,Point &p2) {
|
||||
Int _s;
|
||||
Int _p;
|
||||
Int dy;
|
||||
Int dx;
|
||||
Point r;
|
||||
r.z.SetInt32(1);
|
||||
|
||||
dy.ModSub(&p2.y,&p1.y);
|
||||
dx.ModSub(&p2.x,&p1.x);
|
||||
dx.ModInv();
|
||||
_s.ModMulK1(&dy,&dx); // s = (p2.y-p1.y)*inverse(p2.x-p1.x);
|
||||
|
||||
_p.ModSquareK1(&_s); // _p = pow2(s)
|
||||
|
||||
r.x.ModSub(&_p,&p1.x);
|
||||
r.x.ModSub(&p2.x); // rx = pow2(s) - p1.x - p2.x;
|
||||
|
||||
r.y.ModSub(&p2.x,&r.x);
|
||||
r.y.ModMulK1(&_s);
|
||||
r.y.ModSub(&p2.y); // ry = - p2.y - s*(ret.x-p2.x);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
Point Secp256K1::Add2(Point &p1, Point &p2) {
|
||||
// P2.z = 1
|
||||
Int u;
|
||||
Int v;
|
||||
Int u1;
|
||||
Int v1;
|
||||
Int vs2;
|
||||
Int vs3;
|
||||
Int us2;
|
||||
Int a;
|
||||
Int us2w;
|
||||
Int vs2v2;
|
||||
Int vs3u2;
|
||||
Int _2vs2v2;
|
||||
Point r;
|
||||
u1.ModMulK1(&p2.y, &p1.z);
|
||||
v1.ModMulK1(&p2.x, &p1.z);
|
||||
u.ModSub(&u1, &p1.y);
|
||||
v.ModSub(&v1, &p1.x);
|
||||
us2.ModSquareK1(&u);
|
||||
vs2.ModSquareK1(&v);
|
||||
vs3.ModMulK1(&vs2, &v);
|
||||
us2w.ModMulK1(&us2, &p1.z);
|
||||
vs2v2.ModMulK1(&vs2, &p1.x);
|
||||
_2vs2v2.ModAdd(&vs2v2, &vs2v2);
|
||||
a.ModSub(&us2w, &vs3);
|
||||
a.ModSub(&_2vs2v2);
|
||||
|
||||
r.x.ModMulK1(&v, &a);
|
||||
|
||||
vs3u2.ModMulK1(&vs3, &p1.y);
|
||||
r.y.ModSub(&vs2v2, &a);
|
||||
r.y.ModMulK1(&r.y, &u);
|
||||
r.y.ModSub(&vs3u2);
|
||||
|
||||
r.z.ModMulK1(&vs3, &p1.z);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
Point Secp256K1::Add(Point &p1,Point &p2) {
|
||||
Int u;
|
||||
Int v;
|
||||
Int u1;
|
||||
Int u2;
|
||||
Int v1;
|
||||
Int v2;
|
||||
Int vs2;
|
||||
Int vs3;
|
||||
Int us2;
|
||||
Int w;
|
||||
Int a;
|
||||
Int us2w;
|
||||
Int vs2v2;
|
||||
Int vs3u2;
|
||||
Int _2vs2v2;
|
||||
Int x3;
|
||||
Int vs3y1;
|
||||
Point r;
|
||||
|
||||
/*
|
||||
U1 = Y2 * Z1
|
||||
U2 = Y1 * Z2
|
||||
V1 = X2 * Z1
|
||||
V2 = X1 * Z2
|
||||
if (V1 == V2)
|
||||
if (U1 != U2)
|
||||
return POINT_AT_INFINITY
|
||||
else
|
||||
return POINT_DOUBLE(X1, Y1, Z1)
|
||||
U = U1 - U2
|
||||
V = V1 - V2
|
||||
W = Z1 * Z2
|
||||
A = U ^ 2 * W - V ^ 3 - 2 * V ^ 2 * V2
|
||||
X3 = V * A
|
||||
Y3 = U * (V ^ 2 * V2 - A) - V ^ 3 * U2
|
||||
Z3 = V ^ 3 * W
|
||||
return (X3, Y3, Z3)
|
||||
*/
|
||||
|
||||
u1.ModMulK1(&p2.y,&p1.z);
|
||||
u2.ModMulK1(&p1.y,&p2.z);
|
||||
v1.ModMulK1(&p2.x,&p1.z);
|
||||
v2.ModMulK1(&p1.x,&p2.z);
|
||||
u.ModSub(&u1,&u2);
|
||||
v.ModSub(&v1,&v2);
|
||||
w.ModMulK1(&p1.z,&p2.z);
|
||||
us2.ModSquareK1(&u);
|
||||
vs2.ModSquareK1(&v);
|
||||
vs3.ModMulK1(&vs2,&v);
|
||||
us2w.ModMulK1(&us2,&w);
|
||||
vs2v2.ModMulK1(&vs2,&v2);
|
||||
_2vs2v2.ModAdd(&vs2v2,&vs2v2);
|
||||
a.ModSub(&us2w,&vs3);
|
||||
a.ModSub(&_2vs2v2);
|
||||
|
||||
r.x.ModMulK1(&v,&a);
|
||||
|
||||
vs3u2.ModMulK1(&vs3,&u2);
|
||||
r.y.ModSub(&vs2v2,&a);
|
||||
r.y.ModMulK1(&r.y,&u);
|
||||
r.y.ModSub(&vs3u2);
|
||||
|
||||
r.z.ModMulK1(&vs3,&w);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
Point Secp256K1::DoubleDirect(Point &p) {
|
||||
Int _s;
|
||||
Int _p;
|
||||
Int a;
|
||||
Point r;
|
||||
r.z.SetInt32(1);
|
||||
_s.ModMulK1(&p.x,&p.x);
|
||||
_p.ModAdd(&_s,&_s);
|
||||
_p.ModAdd(&_s);
|
||||
|
||||
a.ModAdd(&p.y,&p.y);
|
||||
a.ModInv();
|
||||
_s.ModMulK1(&_p,&a); // s = (3*pow2(p.x))*inverse(2*p.y);
|
||||
|
||||
_p.ModMulK1(&_s,&_s);
|
||||
a.ModAdd(&p.x,&p.x);
|
||||
a.ModNeg();
|
||||
r.x.ModAdd(&a,&_p); // rx = pow2(s) + neg(2*p.x);
|
||||
|
||||
a.ModSub(&r.x,&p.x);
|
||||
|
||||
_p.ModMulK1(&a,&_s);
|
||||
r.y.ModAdd(&_p,&p.y);
|
||||
r.y.ModNeg(); // ry = neg(p.y + s*(ret.x+neg(p.x)));
|
||||
return r;
|
||||
}
|
||||
|
||||
Point Secp256K1::Double(Point &p) {
|
||||
/*
|
||||
if (Y == 0)
|
||||
return POINT_AT_INFINITY
|
||||
W = a * Z ^ 2 + 3 * X ^ 2
|
||||
S = Y * Z
|
||||
B = X * Y*S
|
||||
H = W ^ 2 - 8 * B
|
||||
X' = 2*H*S
|
||||
Y' = W*(4*B - H) - 8*Y^2*S^2
|
||||
Z' = 8*S^3
|
||||
return (X', Y', Z')
|
||||
*/
|
||||
Int z2;
|
||||
Int x2;
|
||||
Int _3x2;
|
||||
Int w;
|
||||
Int s;
|
||||
Int s2;
|
||||
Int b;
|
||||
Int _8b;
|
||||
Int _8y2s2;
|
||||
Int y2;
|
||||
Int h;
|
||||
Point r;
|
||||
z2.ModSquareK1(&p.z);
|
||||
z2.SetInt32(0); // a=0
|
||||
x2.ModSquareK1(&p.x);
|
||||
_3x2.ModAdd(&x2,&x2);
|
||||
_3x2.ModAdd(&x2);
|
||||
w.ModAdd(&z2,&_3x2);
|
||||
s.ModMulK1(&p.y,&p.z);
|
||||
b.ModMulK1(&p.y,&s);
|
||||
b.ModMulK1(&p.x);
|
||||
h.ModSquareK1(&w);
|
||||
_8b.ModAdd(&b,&b);
|
||||
_8b.ModDouble();
|
||||
_8b.ModDouble();
|
||||
h.ModSub(&_8b);
|
||||
r.x.ModMulK1(&h,&s);
|
||||
r.x.ModAdd(&r.x);
|
||||
s2.ModSquareK1(&s);
|
||||
y2.ModSquareK1(&p.y);
|
||||
_8y2s2.ModMulK1(&y2,&s2);
|
||||
_8y2s2.ModDouble();
|
||||
_8y2s2.ModDouble();
|
||||
_8y2s2.ModDouble();
|
||||
r.y.ModAdd(&b,&b);
|
||||
r.y.ModAdd(&r.y,&r.y);
|
||||
r.y.ModSub(&h);
|
||||
r.y.ModMulK1(&w);
|
||||
r.y.ModSub(&_8y2s2);
|
||||
r.z.ModMulK1(&s2,&s);
|
||||
r.z.ModDouble();
|
||||
r.z.ModDouble();
|
||||
r.z.ModDouble();
|
||||
return r;
|
||||
}
|
||||
|
||||
Int Secp256K1::GetY(Int x,bool isEven) {
|
||||
Int _s;
|
||||
Int _p;
|
||||
_s.ModSquareK1(&x);
|
||||
_p.ModMulK1(&_s,&x);
|
||||
_p.ModAdd(7);
|
||||
_p.ModSqrt();
|
||||
if(!_p.IsEven() && isEven) {
|
||||
_p.ModNeg();
|
||||
}
|
||||
else if(_p.IsEven() && !isEven) {
|
||||
_p.ModNeg();
|
||||
}
|
||||
return _p;
|
||||
}
|
||||
|
||||
bool Secp256K1::EC(Point &p) {
|
||||
Int _s;
|
||||
Int _p;
|
||||
_s.ModSquareK1(&p.x);
|
||||
_p.ModMulK1(&_s,&p.x);
|
||||
_p.ModAdd(7);
|
||||
_s.ModMulK1(&p.y,&p.y);
|
||||
_s.ModSub(&_p);
|
||||
return _s.IsZero(); // ( ((pow2(y) - (pow3(x) + 7)) % P) == 0 );
|
||||
}
|
55
secp256k1/SECP256k1.h
Normal file
55
secp256k1/SECP256k1.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of the BSGS distribution (https://github.com/JeanLucPons/BSGS).
|
||||
* Copyright (c) 2020 Jean Luc PONS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SECP256K1H
|
||||
#define SECP256K1H
|
||||
|
||||
#include "Point.h"
|
||||
#include <vector>
|
||||
|
||||
class Secp256K1 {
|
||||
|
||||
public:
|
||||
|
||||
Secp256K1();
|
||||
~Secp256K1();
|
||||
void Init();
|
||||
Point ComputePublicKey(Int *privKey);
|
||||
Point NextKey(Point &key);
|
||||
bool EC(Point &p);
|
||||
|
||||
char* GetPublicKeyHex(bool compressed, Point &p);
|
||||
bool ParsePublicKeyHex(char *str,Point &p,bool &isCompressed);
|
||||
|
||||
Point Add(Point &p1, Point &p2);
|
||||
Point Add2(Point &p1, Point &p2);
|
||||
Point AddDirect(Point &p1, Point &p2);
|
||||
Point Double(Point &p);
|
||||
Point DoubleDirect(Point &p);
|
||||
|
||||
Point G; // Generator
|
||||
Int order; // Curve order
|
||||
|
||||
private:
|
||||
|
||||
uint8_t GetByte(char *str,int idx);
|
||||
Int GetY(Int x, bool isEven);
|
||||
Point GTable[256*32]; // Generator table
|
||||
|
||||
};
|
||||
|
||||
#endif // SECP256K1H
|
BIN
secp256k1/test
Executable file
BIN
secp256k1/test
Executable file
Binary file not shown.
42
secp256k1/test.c
Normal file
42
secp256k1/test.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
gcc -o test test.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <cstring>
|
||||
#include "SECP256k1.h"
|
||||
#include "Point.h"
|
||||
#include "Int.h"
|
||||
|
||||
#include "util.h"
|
||||
|
||||
Secp256K1 *secp;
|
||||
|
||||
int main() {
|
||||
char dst[32];
|
||||
Int key;
|
||||
char *test;
|
||||
secp = new Secp256K1();
|
||||
key = new Int();
|
||||
secp->Init();
|
||||
Point punto;
|
||||
bool parity;
|
||||
if(secp->ParsePublicKeyHex((char*)"04ceb6cbbcdbdf5ef7150682150f4ce2c6f4807b349827dcdbdd1f2efa885a26302b195386bea3f5f002dc033b92cfc2c9e71b586302b09cfe535e1ff290b1b5ac",punto,parity)) {
|
||||
test = punto.x.GetBase16();
|
||||
printf("%s\n",test);
|
||||
free(test);
|
||||
test = punto.y.GetBase16();
|
||||
printf("%s\n",test);
|
||||
free(test);
|
||||
}
|
||||
else {
|
||||
printf("Is not a valid point");
|
||||
}
|
||||
printf("%i\n",sizeof(Point));
|
||||
punto.x.Get32Bytes((unsigned char*)dst);
|
||||
test = tohex(dst,32);
|
||||
printf("%s\n",test);
|
||||
free(test);
|
||||
}
|
167
secp256k1/util.c
Normal file
167
secp256k1/util.c
Normal file
@@ -0,0 +1,167 @@
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
|
||||
char *ltrim(char *str, const char *seps) {
|
||||
size_t totrim;
|
||||
if (seps == NULL) {
|
||||
seps = "\t\n\v\f\r ";
|
||||
}
|
||||
totrim = strspn(str, seps);
|
||||
if (totrim > 0) {
|
||||
size_t len = strlen(str);
|
||||
if (totrim == len) {
|
||||
str[0] = '\0';
|
||||
}
|
||||
else {
|
||||
memmove(str, str + totrim, len + 1 - totrim);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
char *rtrim(char *str, const char *seps) {
|
||||
int i;
|
||||
if (seps == NULL) {
|
||||
seps = "\t\n\v\f\r ";
|
||||
}
|
||||
i = strlen(str) - 1;
|
||||
while (i >= 0 && strchr(seps, str[i]) != NULL) {
|
||||
str[i] = '\0';
|
||||
i--;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
char *trim(char *str, const char *seps) {
|
||||
return ltrim(rtrim(str, seps), seps);
|
||||
}
|
||||
|
||||
int indexOf(char *s,const char **array,int length_array) {
|
||||
int index = -1,i,continuar = 1;
|
||||
for(i = 0; i <length_array && continuar; i++) {
|
||||
if(strcmp(s,array[i]) == 0) {
|
||||
index = i;
|
||||
continuar = 0;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
char *nextToken(Tokenizer *t) {
|
||||
if(t->current < t->n) {
|
||||
t->current++;
|
||||
return t->tokens[t->current-1];
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
int hasMoreTokens(Tokenizer *t) {
|
||||
return (t->current < t->n);
|
||||
}
|
||||
|
||||
void stringtokenizer(char *data,Tokenizer *t) {
|
||||
char *token;
|
||||
t->tokens = NULL;
|
||||
t->n = 0;
|
||||
t->current = 0;
|
||||
trim(data,"\t\n\r :");
|
||||
token = strtok(data," \t");
|
||||
while(token != NULL) {
|
||||
t->n++;
|
||||
t->tokens = (char**) realloc(t->tokens,sizeof(char*)*t->n);
|
||||
if(t->tokens == NULL) {
|
||||
printf("Out of memory\n");
|
||||
exit(0);
|
||||
}
|
||||
t->tokens[t->n - 1] = token;
|
||||
token = strtok(NULL," \t");
|
||||
}
|
||||
}
|
||||
|
||||
void freetokenizer(Tokenizer *t) {
|
||||
if(t->n > 0) {
|
||||
free(t->tokens);
|
||||
}
|
||||
memset(t,0,sizeof(Tokenizer));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Aux function to get the hexvalues of the data
|
||||
*/
|
||||
char *tohex(char *ptr,int length){
|
||||
char *buffer;
|
||||
int offset = 0;
|
||||
unsigned char c;
|
||||
buffer = (char *) malloc((length * 2)+1);
|
||||
for (int i = 0; i <length; i++) {
|
||||
c = ptr[i];
|
||||
sprintf((char*) (buffer + offset),"%.2x",c);
|
||||
offset+=2;
|
||||
}
|
||||
buffer[length*2] = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int hexs2bin(char *hex, unsigned char *out) {
|
||||
int len;
|
||||
char b1;
|
||||
char b2;
|
||||
int i;
|
||||
|
||||
if (hex == NULL || *hex == '\0' || out == NULL)
|
||||
return 0;
|
||||
|
||||
len = strlen(hex);
|
||||
if (len % 2 != 0)
|
||||
return 0;
|
||||
len /= 2;
|
||||
|
||||
memset(out, 'A', len);
|
||||
for (i=0; i<len; i++) {
|
||||
if (!hexchr2bin(hex[i*2], &b1) || !hexchr2bin(hex[i*2+1], &b2)) {
|
||||
return 0;
|
||||
}
|
||||
out[i] = (b1 << 4) | b2;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int hexchr2bin(const char hex, char *out) {
|
||||
if (out == NULL)
|
||||
return 0;
|
||||
|
||||
if (hex >= '0' && hex <= '9') {
|
||||
*out = hex - '0';
|
||||
} else if (hex >= 'A' && hex <= 'F') {
|
||||
*out = hex - 'A' + 10;
|
||||
} else if (hex >= 'a' && hex <= 'f') {
|
||||
*out = hex - 'a' + 10;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void addItemList(char *data, List *l) {
|
||||
l->data = (char**) realloc(l->data,sizeof(char*)* (l->n +1));
|
||||
l->data[l->n] = data;
|
||||
l->n++;
|
||||
}
|
||||
|
||||
int isValidHex(char *data) {
|
||||
char c;
|
||||
int len,i,valid = 1;
|
||||
len = strlen(data);
|
||||
for(i = 0 ; i < len && valid ;i++ ) {
|
||||
c = data[i];
|
||||
valid = ( (c >= '0' && c <='9') || (c >= 'A' && c <='F' ) || (c >= 'a' && c <='f' ) );
|
||||
}
|
||||
return valid;
|
||||
}
|
30
secp256k1/util.h
Normal file
30
secp256k1/util.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef CUSTOMUTILH
|
||||
#define CUSTOMUTILH
|
||||
|
||||
typedef struct str_list {
|
||||
int n;
|
||||
char **data;
|
||||
int *lengths;
|
||||
}List;
|
||||
|
||||
typedef struct str_tokenizer {
|
||||
int current;
|
||||
int n;
|
||||
char **tokens;
|
||||
}Tokenizer;
|
||||
|
||||
char *ltrim(char *str, const char *seps);
|
||||
char *rtrim(char *str, const char *seps);
|
||||
char *trim(char *str, const char *seps);
|
||||
int indexOf(char *s,const char **array,int length_array);
|
||||
|
||||
int hexchr2bin(char hex, char *out);
|
||||
int hexs2bin(char *hex, unsigned char *out);
|
||||
char *tohex(char *ptr,int length);
|
||||
|
||||
int hasMoreTokens(Tokenizer *t);
|
||||
char *nextToken(Tokenizer *t);
|
||||
|
||||
|
||||
|
||||
#endif // CUSTOMUTILH
|
167
util.c
Normal file
167
util.c
Normal file
@@ -0,0 +1,167 @@
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
|
||||
char *ltrim(char *str, const char *seps) {
|
||||
size_t totrim;
|
||||
if (seps == NULL) {
|
||||
seps = "\t\n\v\f\r ";
|
||||
}
|
||||
totrim = strspn(str, seps);
|
||||
if (totrim > 0) {
|
||||
size_t len = strlen(str);
|
||||
if (totrim == len) {
|
||||
str[0] = '\0';
|
||||
}
|
||||
else {
|
||||
memmove(str, str + totrim, len + 1 - totrim);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
char *rtrim(char *str, const char *seps) {
|
||||
int i;
|
||||
if (seps == NULL) {
|
||||
seps = "\t\n\v\f\r ";
|
||||
}
|
||||
i = strlen(str) - 1;
|
||||
while (i >= 0 && strchr(seps, str[i]) != NULL) {
|
||||
str[i] = '\0';
|
||||
i--;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
char *trim(char *str, const char *seps) {
|
||||
return ltrim(rtrim(str, seps), seps);
|
||||
}
|
||||
|
||||
int indexOf(char *s,const char **array,int length_array) {
|
||||
int index = -1,i,continuar = 1;
|
||||
for(i = 0; i <length_array && continuar; i++) {
|
||||
if(strcmp(s,array[i]) == 0) {
|
||||
index = i;
|
||||
continuar = 0;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
char *nextToken(Tokenizer *t) {
|
||||
if(t->current < t->n) {
|
||||
t->current++;
|
||||
return t->tokens[t->current-1];
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
int hasMoreTokens(Tokenizer *t) {
|
||||
return (t->current < t->n);
|
||||
}
|
||||
|
||||
void stringtokenizer(char *data,Tokenizer *t) {
|
||||
char *token;
|
||||
t->tokens = NULL;
|
||||
t->n = 0;
|
||||
t->current = 0;
|
||||
trim(data,"\t\n\r :");
|
||||
token = strtok(data," \t");
|
||||
while(token != NULL) {
|
||||
t->n++;
|
||||
t->tokens = (char**) realloc(t->tokens,sizeof(char*)*t->n);
|
||||
if(t->tokens == NULL) {
|
||||
printf("Out of memory\n");
|
||||
exit(0);
|
||||
}
|
||||
t->tokens[t->n - 1] = token;
|
||||
token = strtok(NULL," \t");
|
||||
}
|
||||
}
|
||||
|
||||
void freetokenizer(Tokenizer *t) {
|
||||
if(t->n > 0) {
|
||||
free(t->tokens);
|
||||
}
|
||||
memset(t,0,sizeof(Tokenizer));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Aux function to get the hexvalues of the data
|
||||
*/
|
||||
char *tohex(char *ptr,int length){
|
||||
char *buffer;
|
||||
int offset = 0;
|
||||
unsigned char c;
|
||||
buffer = (char *) malloc((length * 2)+1);
|
||||
for (int i = 0; i <length; i++) {
|
||||
c = ptr[i];
|
||||
sprintf((char*) (buffer + offset),"%.2x",c);
|
||||
offset+=2;
|
||||
}
|
||||
buffer[length*2] = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int hexs2bin(char *hex, unsigned char *out) {
|
||||
int len;
|
||||
char b1;
|
||||
char b2;
|
||||
int i;
|
||||
|
||||
if (hex == NULL || *hex == '\0' || out == NULL)
|
||||
return 0;
|
||||
|
||||
len = strlen(hex);
|
||||
if (len % 2 != 0)
|
||||
return 0;
|
||||
len /= 2;
|
||||
|
||||
memset(out, 'A', len);
|
||||
for (i=0; i<len; i++) {
|
||||
if (!hexchr2bin(hex[i*2], &b1) || !hexchr2bin(hex[i*2+1], &b2)) {
|
||||
return 0;
|
||||
}
|
||||
out[i] = (b1 << 4) | b2;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int hexchr2bin(const char hex, char *out) {
|
||||
if (out == NULL)
|
||||
return 0;
|
||||
|
||||
if (hex >= '0' && hex <= '9') {
|
||||
*out = hex - '0';
|
||||
} else if (hex >= 'A' && hex <= 'F') {
|
||||
*out = hex - 'A' + 10;
|
||||
} else if (hex >= 'a' && hex <= 'f') {
|
||||
*out = hex - 'a' + 10;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void addItemList(char *data, List *l) {
|
||||
l->data = (char**) realloc(l->data,sizeof(char*)* (l->n +1));
|
||||
l->data[l->n] = data;
|
||||
l->n++;
|
||||
}
|
||||
|
||||
int isValidHex(char *data) {
|
||||
char c;
|
||||
int len,i,valid = 1;
|
||||
len = strlen(data);
|
||||
for(i = 0 ; i < len && valid ;i++ ) {
|
||||
c = data[i];
|
||||
valid = ( (c >= '0' && c <='9') || (c >= 'A' && c <='F' ) || (c >= 'a' && c <='f' ) );
|
||||
}
|
||||
return valid;
|
||||
}
|
168
util.h
168
util.h
@@ -1,3 +1,6 @@
|
||||
#ifndef CUSTOMUTILH
|
||||
#define CUSTOMUTILH
|
||||
|
||||
typedef struct str_list {
|
||||
int n;
|
||||
char **data;
|
||||
@@ -22,165 +25,8 @@ char *tohex(char *ptr,int length);
|
||||
int hasMoreTokens(Tokenizer *t);
|
||||
char *nextToken(Tokenizer *t);
|
||||
|
||||
char *ltrim(char *str, const char *seps) {
|
||||
size_t totrim;
|
||||
if (seps == NULL) {
|
||||
seps = "\t\n\v\f\r ";
|
||||
}
|
||||
totrim = strspn(str, seps);
|
||||
if (totrim > 0) {
|
||||
size_t len = strlen(str);
|
||||
if (totrim == len) {
|
||||
str[0] = '\0';
|
||||
}
|
||||
else {
|
||||
memmove(str, str + totrim, len + 1 - totrim);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
int isValidHex(char *data);
|
||||
void freetokenizer(Tokenizer *t);
|
||||
void stringtokenizer(char *data,Tokenizer *t);
|
||||
|
||||
char *rtrim(char *str, const char *seps) {
|
||||
int i;
|
||||
if (seps == NULL) {
|
||||
seps = "\t\n\v\f\r ";
|
||||
}
|
||||
i = strlen(str) - 1;
|
||||
while (i >= 0 && strchr(seps, str[i]) != NULL) {
|
||||
str[i] = '\0';
|
||||
i--;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
char *trim(char *str, const char *seps) {
|
||||
return ltrim(rtrim(str, seps), seps);
|
||||
}
|
||||
|
||||
int indexOf(char *s,const char **array,int length_array) {
|
||||
int index = -1,i,continuar = 1;
|
||||
for(i = 0; i <length_array && continuar; i++) {
|
||||
if(strcmp(s,array[i]) == 0) {
|
||||
index = i;
|
||||
continuar = 0;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
char *nextToken(Tokenizer *t) {
|
||||
if(t->current < t->n) {
|
||||
t->current++;
|
||||
return t->tokens[t->current-1];
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
int hasMoreTokens(Tokenizer *t) {
|
||||
return (t->current < t->n);
|
||||
}
|
||||
|
||||
void stringtokenizer(char *data,Tokenizer *t) {
|
||||
char *token;
|
||||
t->tokens = NULL;
|
||||
t->n = 0;
|
||||
t->current = 0;
|
||||
trim(data,"\t\n\r ");
|
||||
token = strtok(data," \t:");
|
||||
while(token != NULL) {
|
||||
t->n++;
|
||||
t->tokens = realloc(t->tokens,sizeof(char*)*t->n);
|
||||
if(t->tokens == NULL) {
|
||||
printf("Out of memory\n");
|
||||
exit(0);
|
||||
}
|
||||
t->tokens[t->n - 1] = token;
|
||||
token = strtok(NULL," \t");
|
||||
}
|
||||
}
|
||||
|
||||
void freetokenizer(Tokenizer *t) {
|
||||
if(t->n > 0) {
|
||||
free(t-> tokens);
|
||||
}
|
||||
memset(t,0,sizeof(Tokenizer));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Aux function to get the hexvalues of the data
|
||||
*/
|
||||
|
||||
char *tohex(char *ptr,int length){
|
||||
char *buffer;
|
||||
int offset = 0;
|
||||
unsigned char c;
|
||||
buffer = (char *) malloc((length * 2)+1);
|
||||
for (int i = 0; i <length; i++) {
|
||||
c = ptr[i];
|
||||
sprintf((char*) (buffer + offset),"%.2x",c);
|
||||
offset+=2;
|
||||
}
|
||||
buffer[length*2] = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
int hexs2bin(char *hex, unsigned char *out) {
|
||||
int len;
|
||||
char b1;
|
||||
char b2;
|
||||
int i;
|
||||
|
||||
if (hex == NULL || *hex == '\0' || out == NULL)
|
||||
return 0;
|
||||
|
||||
len = strlen(hex);
|
||||
if (len % 2 != 0)
|
||||
return 0;
|
||||
len /= 2;
|
||||
|
||||
memset(out, 'A', len);
|
||||
for (i=0; i<len; i++) {
|
||||
if (!hexchr2bin(hex[i*2], &b1) || !hexchr2bin(hex[i*2+1], &b2)) {
|
||||
return 0;
|
||||
}
|
||||
out[i] = (b1 << 4) | b2;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int hexchr2bin(const char hex, char *out) {
|
||||
if (out == NULL)
|
||||
return 0;
|
||||
|
||||
if (hex >= '0' && hex <= '9') {
|
||||
*out = hex - '0';
|
||||
} else if (hex >= 'A' && hex <= 'F') {
|
||||
*out = hex - 'A' + 10;
|
||||
} else if (hex >= 'a' && hex <= 'f') {
|
||||
*out = hex - 'a' + 10;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void addItemList(char *data, List *l) {
|
||||
l->data = realloc(l->data,sizeof(char*)* (l->n +1));
|
||||
l->data[l->n] = data;
|
||||
l->n++;
|
||||
}
|
||||
|
||||
int isValidHex(char *data) {
|
||||
char c;
|
||||
int len,i,valid = 1;
|
||||
len = strlen(data);
|
||||
for(i = 0 ; i < len && valid ;i++ ) {
|
||||
c = data[i];
|
||||
valid = ( (c >= '0' && c <='9') || (c >= 'A' && c <='F' ) || (c >= 'a' && c <='f' ) );
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
#endif // CUSTOMUTILH
|
||||
|
Reference in New Issue
Block a user