mirror of
https://github.com/albertobsd/keyhunt.git
synced 2025-03-17 13:21:46 +01:00
added keyhunt_legacy.cpp legacy version, check README.md
This commit is contained in:
parent
ee1f920b2f
commit
a94643171a
@ -2,7 +2,8 @@
|
||||
- fixed some variables names
|
||||
- fixed bug in addvanity (realloc problem with dirty memory)
|
||||
- Added option -6 to skip SHA256 checksum when you read the files (Improved startup process)
|
||||
- Added warning when you Endomorphism and BSGS, THEY DON'T WORK together!
|
||||
- Added warning when you Endomorphism and BSGS, THEY DON'T WORK together!
|
||||
- Legacy version for ARM processor and other systems
|
||||
|
||||
# Version 0.2.230430 Satoshi Quest
|
||||
- fixed typos in README
|
||||
|
17
Makefile
17
Makefile
@ -20,4 +20,19 @@ default:
|
||||
g++ -m64 -march=native -mtune=native -mssse3 -Wno-unused-result -Wno-write-strings -Ofast -ftree-vectorize -o keyhunt keyhunt.cpp base58.o rmd160.o hash/ripemd160.o hash/ripemd160_sse.o hash/sha256.o hash/sha256_sse.o bloom.o oldbloom.o xxhash.o util.o Int.o Point.o SECP256K1.o IntMod.o Random.o IntGroup.o sha3.o keccak.o -lm -lpthread
|
||||
rm -r *.o
|
||||
clean:
|
||||
rm keyhunt
|
||||
rm keyhunt
|
||||
legacy:
|
||||
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -flto -c oldbloom/bloom.cpp -o oldbloom.o
|
||||
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -flto -c bloom/bloom.cpp -o bloom.o
|
||||
gcc -m64 -march=native -mtune=native -mssse3 -Wno-unused-result -Ofast -ftree-vectorize -c base58/base58.c -o base58.o
|
||||
gcc -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c xxhash/xxhash.c -o xxhash.o
|
||||
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c util.c -o util.o
|
||||
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c hashing.c -o hashing.o -lcrypto
|
||||
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c gmp256k1/Int.cpp -o Int.o -lgmp
|
||||
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c gmp256k1/Point.cpp -o Point.o -lgmp
|
||||
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c gmp256k1/GMP256K1.cpp -o GMP256K1.o -lgmp
|
||||
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -c gmp256k1/IntMod.cpp -o IntMod.o -lgmp
|
||||
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -flto -c gmp256k1/Random.cpp -o Random.o -lgmp
|
||||
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -flto -c gmp256k1/IntGroup.cpp -o IntGroup.o -lgmp
|
||||
g++ -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -Ofast -ftree-vectorize -o keyhunt keyhunt_legacy.cpp base58.o bloom.o oldbloom.o xxhash.o util.o Int.o Point.o GMP256K1.o IntMod.o IntGroup.o Random.o hashing.o -lm -lpthread -lcrypto -lgmp
|
||||
rm -r *.o
|
||||
|
14
README.md
14
README.md
@ -65,6 +65,11 @@ Please install on your system
|
||||
- git
|
||||
- build-essential
|
||||
|
||||
for legacy version also you are going to need:
|
||||
|
||||
- libssl-dev
|
||||
- libgmp-dev
|
||||
|
||||
On Debian based systems, run this commands to update your current enviroment
|
||||
and install the tools needed to compile it
|
||||
|
||||
@ -72,6 +77,8 @@ and install the tools needed to compile it
|
||||
apt update && apt upgrade
|
||||
apt install git -y
|
||||
apt install build-essential -y
|
||||
apt install libssl-dev -y
|
||||
apt install libgmp-dev -y
|
||||
```
|
||||
|
||||
To clone the repository
|
||||
@ -92,6 +99,13 @@ First compile:
|
||||
make
|
||||
```
|
||||
|
||||
if you have problems compiling the `main` version you can compile the `legacy` version
|
||||
|
||||
```
|
||||
make legacy
|
||||
```
|
||||
|
||||
|
||||
and then execute with `-h` to see the help
|
||||
|
||||
```
|
||||
|
@ -136,7 +136,6 @@ int bloom_check(struct bloom * bloom, const void * buffer, int len)
|
||||
uint64_t b = XXH64(buffer, len, a);
|
||||
uint64_t x;
|
||||
uint8_t i;
|
||||
int r;
|
||||
for (i = 0; i < bloom->hashes; i++) {
|
||||
x = (a + b*i) % bloom->bits;
|
||||
if (test_bit(bloom->bf, x)) {
|
||||
|
599
gmp256k1/GMP256K1.cpp
Normal file
599
gmp256k1/GMP256K1.cpp
Normal file
@ -0,0 +1,599 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include "GMP256K1.h"
|
||||
#include "Point.h"
|
||||
#include "../util.h"
|
||||
#include "../hashing.h"
|
||||
|
||||
Secp256K1::Secp256K1() {
|
||||
}
|
||||
|
||||
void Secp256K1::Init() {
|
||||
// Prime for the finite field
|
||||
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::Negation(Point &p) {
|
||||
Point Q;
|
||||
Q.Clear();
|
||||
Q.x.Set(&p.x);
|
||||
Q.y.Set(&this->P);
|
||||
Q.y.Sub(&p.y);
|
||||
Q.z.SetInt32(1);
|
||||
return Q;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Int Secp256K1::GetY(Int x,bool isEven) {
|
||||
Int y;
|
||||
mpz_t _s,_p,y2;
|
||||
mpz_inits(_s,_p,y2,NULL);
|
||||
mpz_pow_ui(_s,x.num,3);
|
||||
mpz_add_ui(y2,_s,7);
|
||||
mpz_mod(y2,y2,P.num);
|
||||
mpz_add_ui(_s,P.num,1);
|
||||
mpz_fdiv_q_ui(_p,_s,4);
|
||||
mpz_powm(y.num,y2,_p,P.num);
|
||||
mpz_sub(_s,P.num,y.num);
|
||||
if(mpz_tstbit(y.num, 0) == 1 && isEven){
|
||||
mpz_set(y.num,_s);
|
||||
}else if (mpz_tstbit(y.num, 0) == 0 && !isEven) {
|
||||
mpz_set(y.num,_s);
|
||||
}
|
||||
mpz_clears(_s,_p,y2,NULL);
|
||||
return y;
|
||||
}
|
||||
|
||||
Point Secp256K1::ComputePublicKey(Int *privKey) {
|
||||
//char *hextemp;
|
||||
uint8_t buffer[32];
|
||||
int i = 0;
|
||||
uint8_t b;
|
||||
Point Q;
|
||||
|
||||
Q.Clear();
|
||||
privKey->Get32Bytes(buffer);
|
||||
for (i = 0; i < 32; i++) {
|
||||
b = buffer[i];
|
||||
if(b)
|
||||
break;
|
||||
}
|
||||
if(i == 32)
|
||||
return Q;
|
||||
Q = GTable[256 * (31 - i) + (b-1)];
|
||||
i++;
|
||||
for(; i < 32; i++) {
|
||||
b = buffer[i];
|
||||
if(b)
|
||||
Q = Add2(Q, GTable[256 * (31 - 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);
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
bool Secp256K1::ParsePublicKeyHex(char *str,Point &ret,bool &isCompressed) {
|
||||
char tempbuffer[65];
|
||||
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;
|
||||
}
|
||||
ret.x.SetBase16(str+2);
|
||||
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;
|
||||
}
|
||||
ret.x.SetBase16(str+2);
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
strncpy(tempbuffer,str+2,64);
|
||||
tempbuffer[64] = 0x00;
|
||||
ret.x.SetBase16(tempbuffer);
|
||||
ret.x.SetBase16(str+66);
|
||||
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[65];
|
||||
char *ret = NULL;
|
||||
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() ? 0x02 : 0x03;
|
||||
pubKey.x.Get32Bytes(publicKeyBytes + 1);
|
||||
ret = (char*) tohex((char*)publicKeyBytes,33);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
The caller of this function must asuste that there are enough space in dst pointer
|
||||
*/
|
||||
void Secp256K1::GetPublicKeyHex(bool compressed, Point &pubKey,char *dst){
|
||||
unsigned char publicKeyBytes[65];
|
||||
if (!compressed) {
|
||||
//Uncompressed public key
|
||||
publicKeyBytes[0] = 0x4;
|
||||
pubKey.x.Get32Bytes(publicKeyBytes + 1);
|
||||
pubKey.y.Get32Bytes(publicKeyBytes + 33);
|
||||
tohex_dst((char*)publicKeyBytes,65,dst);
|
||||
}
|
||||
else {
|
||||
// Compressed public key
|
||||
publicKeyBytes[0] = pubKey.y.IsEven() ? 0x2 : 0x3;
|
||||
pubKey.x.Get32Bytes(publicKeyBytes + 1);
|
||||
tohex_dst((char*)publicKeyBytes,33,dst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char* Secp256K1::GetPublicKeyRaw(bool compressed, Point &pubKey) {
|
||||
char *ret = (char*) malloc(65);
|
||||
if(ret == NULL) {
|
||||
::fprintf(stderr,"Can't alloc memory\n");
|
||||
exit(0);
|
||||
}
|
||||
if (!compressed) {
|
||||
//Uncompressed public key
|
||||
ret[0] = 0x04;
|
||||
pubKey.x.Get32Bytes((unsigned char*) (ret + 1));
|
||||
pubKey.y.Get32Bytes((unsigned char*) (ret + 33));
|
||||
}
|
||||
else {
|
||||
// Compressed public key
|
||||
ret[0] = pubKey.y.IsEven() ? 0x02 : 0x03;
|
||||
pubKey.x.Get32Bytes((unsigned char*) (ret + 1));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
The caller of this function must asuste that there are enough space in dst pointer
|
||||
*/
|
||||
void Secp256K1::GetPublicKeyRaw(bool compressed, Point &pubKey,char *dst) {
|
||||
if (!compressed) {
|
||||
//Uncompressed public key
|
||||
dst[0] = 0x4;
|
||||
pubKey.x.Get32Bytes((unsigned char*) (dst + 1));
|
||||
pubKey.y.Get32Bytes((unsigned char*) (dst + 33));
|
||||
}
|
||||
else {
|
||||
// Compressed public key
|
||||
dst[0] = pubKey.y.IsEven() ? 0x2 : 0x3;
|
||||
pubKey.x.Get32Bytes((unsigned char*) (dst + 1));
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
|
||||
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::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;
|
||||
}
|
||||
|
||||
|
||||
Point Secp256K1::ScalarMultiplication(Point &P,Int *scalar) {
|
||||
Point R,Q,T,Dummy;
|
||||
int no_of_bits, loop;
|
||||
no_of_bits = scalar->GetBitLength();
|
||||
R.Clear();
|
||||
R.z.SetInt32(1);
|
||||
if(!scalar->IsZero()) {
|
||||
Q.Set(P);
|
||||
if(scalar->GetBit(0) == 1) {
|
||||
R.Set(P);
|
||||
}
|
||||
for(loop = 1; loop < no_of_bits; loop++) {
|
||||
T = Double(Q);
|
||||
Q.Set(T);
|
||||
T.Set(R);
|
||||
if(scalar->GetBit(loop)){
|
||||
R = Add(T,Q);
|
||||
}
|
||||
else {
|
||||
Dummy = Add(T,Q);
|
||||
}
|
||||
}
|
||||
}
|
||||
R.Reduce();
|
||||
return R;
|
||||
}
|
||||
|
||||
void Secp256K1::GetHash160(int type, bool compressed, Point &pubKey, unsigned char *hash) {
|
||||
unsigned char shapk[64];
|
||||
switch (type) {
|
||||
case P2PKH:
|
||||
case BECH32:
|
||||
unsigned char publicKeyBytes[128];
|
||||
|
||||
if (!compressed) {
|
||||
// Full public key
|
||||
publicKeyBytes[0] = 0x4;
|
||||
pubKey.x.Get32Bytes(publicKeyBytes + 1);
|
||||
pubKey.y.Get32Bytes(publicKeyBytes + 33);
|
||||
sha256(publicKeyBytes,65,shapk);
|
||||
} else {
|
||||
// Compressed public key
|
||||
publicKeyBytes[0] = pubKey.y.IsEven() ? 0x2 : 0x3;
|
||||
pubKey.x.Get32Bytes(publicKeyBytes + 1);
|
||||
sha256(publicKeyBytes,33,shapk);
|
||||
}
|
||||
rmd160(shapk,32,hash);
|
||||
|
||||
break;
|
||||
case P2SH:
|
||||
// Redeem Script (1 to 1 P2SH)
|
||||
unsigned char script[64];
|
||||
script[0] = 0x00; // OP_0
|
||||
script[1] = 0x14; // PUSH 20 bytes
|
||||
GetHash160(P2PKH, compressed, pubKey, script + 2);
|
||||
sha256(script, 22, shapk);
|
||||
rmd160(shapk,32,hash);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Secp256K1::GetHash160(int type,bool compressed,
|
||||
Point &k0,Point &k1,Point &k2,Point &k3,
|
||||
uint8_t *h0,uint8_t *h1,uint8_t *h2,uint8_t *h3) {
|
||||
GetHash160(type,compressed,k0,h0);
|
||||
GetHash160(type,compressed,k1,h1);
|
||||
GetHash160(type,compressed,k2,h2);
|
||||
GetHash160(type,compressed,k3,h3);
|
||||
}
|
||||
|
||||
|
||||
void Secp256K1::GetHash160_fromX(int type,unsigned char prefix,
|
||||
Int *k0,Int *k1,Int *k2,Int *k3,
|
||||
uint8_t *h0,uint8_t *h1,uint8_t *h2,uint8_t *h3) {
|
||||
unsigned char digests[4][33];
|
||||
int i;
|
||||
switch (type) {
|
||||
case P2PKH:
|
||||
|
||||
k0->Get32Bytes((unsigned char*)(digests[0] + 1));
|
||||
k1->Get32Bytes((unsigned char*)(digests[1] + 1));
|
||||
k2->Get32Bytes((unsigned char*)(digests[2] + 1));
|
||||
k3->Get32Bytes((unsigned char*)(digests[3] + 1));
|
||||
for(i = 0; i < 4; i++) {
|
||||
digests[i][0] = prefix;
|
||||
sha256(digests[i],33,digests[i]);
|
||||
}
|
||||
rmd160(digests[0],32,h0);
|
||||
rmd160(digests[1],32,h1);
|
||||
rmd160(digests[2],32,h2);
|
||||
rmd160(digests[3],32,h3);
|
||||
break;
|
||||
|
||||
case P2SH:
|
||||
fprintf(stderr,"[E] Fixme unsopported case");
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
80
gmp256k1/GMP256K1.h
Normal file
80
gmp256k1/GMP256K1.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
This file is part of the Keyhunt distribution (https://github.com/albertobsd/keyhunt).
|
||||
Copyright (c) 2020 Luis Alberto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SECP256K1H
|
||||
#define SECP256K1H
|
||||
|
||||
#include "Point.h"
|
||||
#include <vector>
|
||||
|
||||
// Address type
|
||||
#define P2PKH 0
|
||||
#define P2SH 1
|
||||
#define BECH32 2
|
||||
|
||||
|
||||
class Secp256K1 {
|
||||
|
||||
public:
|
||||
|
||||
Secp256K1();
|
||||
~Secp256K1();
|
||||
void Init();
|
||||
Point ComputePublicKey(Int *privKey);
|
||||
Point Add(Point &p1, Point &p2);
|
||||
Point Add2(Point &p1, Point &p2);
|
||||
Point NextKey(Point &key);
|
||||
bool EC(Point &p);
|
||||
|
||||
void GetHash160_fromX(int type,unsigned char prefix,
|
||||
Int *k0,Int *k1,Int *k2,Int *k3,
|
||||
uint8_t *h0,uint8_t *h1,uint8_t *h2,uint8_t *h3);
|
||||
bool ParsePublicKeyHex(char *str,Point &p,bool &isCompressed);
|
||||
Point ScalarMultiplication(Point &P,Int *scalar);
|
||||
char* GetPublicKeyHex(bool compressed, Point &p);
|
||||
void GetPublicKeyHex(bool compressed, Point &pubKey,char *dst);
|
||||
|
||||
char* GetPublicKeyRaw(bool compressed, Point &p);
|
||||
void GetPublicKeyRaw(bool compressed, Point &pubKey,char *dst);
|
||||
void GetHash160(int type,bool compressed, Point &pubKey, unsigned char *hash);
|
||||
void GetHash160(int type,bool compressed,
|
||||
Point &k0, Point &k1, Point &k2, Point &k3,
|
||||
uint8_t *h0, uint8_t *h1, uint8_t *h2, uint8_t *h3);
|
||||
|
||||
Point Negation(Point &p);
|
||||
Point Double(Point &p);
|
||||
Point DoubleDirect(Point &p);
|
||||
Point AddDirect(Point &p1, Point &p2);
|
||||
Point G; // Generator
|
||||
Int P; // Prime for the finite field
|
||||
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
|
370
gmp256k1/Int.cpp
Normal file
370
gmp256k1/Int.cpp
Normal file
@ -0,0 +1,370 @@
|
||||
/*
|
||||
* This file is part of the Keyhunt distribution (https://github.com/albertobsd/keyhunt).
|
||||
* Copyright (c) 2023 albertobsd.
|
||||
*
|
||||
* 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 (libgmp)
|
||||
|
||||
#include "Int.h"
|
||||
#include<stdio.h>
|
||||
#include<stdint.h>
|
||||
#include<string.h>
|
||||
#include<gmp.h>
|
||||
|
||||
#define U64STRINGSIZE 30
|
||||
|
||||
Int::Int() {
|
||||
mpz_init_set_ui(num,0);
|
||||
}
|
||||
|
||||
Int::Int(const int32_t i32) {
|
||||
mpz_init_set_si(num,i32);
|
||||
}
|
||||
|
||||
Int::Int(const uint32_t u32) {
|
||||
mpz_init_set_ui(num,u32);
|
||||
}
|
||||
|
||||
Int::Int(const Int *other) {
|
||||
mpz_init_set(num,other->num);
|
||||
}
|
||||
|
||||
Int::Int(const char *str) {
|
||||
mpz_init_set_str(num,str,0);
|
||||
}
|
||||
|
||||
Int::Int(const uint64_t u64) {
|
||||
char my_str_value[U64STRINGSIZE]; // 30 digits + null terminator
|
||||
snprintf(my_str_value,U64STRINGSIZE, "%lu", u64);
|
||||
mpz_init_set_str(num,my_str_value,0);
|
||||
}
|
||||
|
||||
Int::Int(const int64_t i64) {
|
||||
char my_str_value[U64STRINGSIZE]; // 30 digits + null terminator
|
||||
snprintf(my_str_value,U64STRINGSIZE,"%li", i64);
|
||||
mpz_init_set_str(num,my_str_value,0);
|
||||
}
|
||||
|
||||
Int::Int(const Int &value) {
|
||||
mpz_init_set(num,value.num);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Int::Add(const uint64_t u64) {
|
||||
mpz_t value;
|
||||
char my_str_value[U64STRINGSIZE]; // 30 digits + null terminator
|
||||
snprintf(my_str_value,U64STRINGSIZE,"%lu", u64);
|
||||
mpz_init_set_str(value,my_str_value,0);
|
||||
mpz_add(num,num,value);
|
||||
mpz_clear(value);
|
||||
}
|
||||
|
||||
void Int::Add(const uint32_t u32) {
|
||||
mpz_add_ui(num,num,u32);
|
||||
}
|
||||
|
||||
void Int::Add(const Int *a) {
|
||||
mpz_add(num,num,a->num);
|
||||
}
|
||||
|
||||
void Int::Add(const Int *a,const Int *b) {
|
||||
mpz_add(num,num,a->num);
|
||||
mpz_add(num,num,b->num);
|
||||
}
|
||||
|
||||
void Int::Sub(const uint32_t u32) {
|
||||
mpz_sub_ui(num,num,u32);
|
||||
}
|
||||
|
||||
void Int::Sub(const uint64_t u64) {
|
||||
mpz_t value;
|
||||
char my_str_value[U64STRINGSIZE]; // 30 digits + null terminator
|
||||
snprintf(my_str_value,U64STRINGSIZE,"%lu", u64);
|
||||
mpz_init_set_str(value,my_str_value,0);
|
||||
mpz_sub(num,num,value);
|
||||
mpz_clear(value);
|
||||
}
|
||||
|
||||
void Int::Sub(Int *a) {
|
||||
mpz_sub(num,num,a->num);
|
||||
}
|
||||
|
||||
void Int::Sub(Int *a, Int *b) {
|
||||
mpz_sub(num,num,a->num);
|
||||
mpz_sub(num,num,b->num);
|
||||
}
|
||||
|
||||
void Int::Mult(Int *a) {
|
||||
mpz_mul(num,num,a->num);
|
||||
}
|
||||
|
||||
void Int::Mult(uint64_t u64) {
|
||||
mpz_t value;
|
||||
char my_str_value[U64STRINGSIZE]; // 30 digits + null terminator
|
||||
snprintf(my_str_value,U64STRINGSIZE,"%lu", u64);
|
||||
mpz_init_set_str(value,my_str_value,0);
|
||||
mpz_mul(num,num,value);
|
||||
mpz_clear(value);
|
||||
}
|
||||
|
||||
void Int::IMult(int64_t i64) {
|
||||
mpz_t value;
|
||||
char my_str_value[U64STRINGSIZE]; // 30 digits + null terminator
|
||||
snprintf(my_str_value,U64STRINGSIZE,"%li", i64);
|
||||
mpz_init_set_str(value,my_str_value,0);
|
||||
mpz_mul(num,num,value);
|
||||
mpz_clear(value);
|
||||
}
|
||||
|
||||
void Int::Neg() {
|
||||
mpz_neg(num,num);
|
||||
}
|
||||
|
||||
void Int::Abs() {
|
||||
mpz_abs(num,num);
|
||||
}
|
||||
|
||||
bool Int::IsGreater(Int *a) {
|
||||
if(mpz_cmp(num,a->num) > 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Int::IsGreaterOrEqual(Int *a) {
|
||||
if(mpz_cmp(num,a->num) >= 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Int::IsLowerOrEqual(Int *a) {
|
||||
if(mpz_cmp(num,a->num) <= 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Int::IsLower(Int *a) {
|
||||
if(mpz_cmp(num,a->num) < 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Int::IsEqual(Int *a) {
|
||||
if(mpz_cmp(num,a->num) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Int::IsZero() {
|
||||
if(mpz_cmp_ui(num,0) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Int::IsOne() {
|
||||
if(mpz_cmp_ui(num,1) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Int::IsPositive() {
|
||||
if(mpz_cmp_ui(num,0) >= 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Int::IsNegative() {
|
||||
if(mpz_cmp_ui(num,0) < 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Int::IsEven() {
|
||||
if(mpz_tstbit(num,0) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Int::IsOdd() {
|
||||
if(mpz_tstbit(num,0) == 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int Int::GetSize() {
|
||||
int r = mpz_sizeinbase(num,2);
|
||||
if(r % 8 == 0)
|
||||
return (int)(r/8);
|
||||
else
|
||||
return (int)(r/8) + 1;
|
||||
}
|
||||
|
||||
int Int::GetBitLength() {
|
||||
return mpz_sizeinbase(num,2);
|
||||
}
|
||||
|
||||
uint64_t Int::GetInt64() {
|
||||
char *temp =NULL;
|
||||
uint64_t r;
|
||||
temp = mpz_get_str(NULL,10,num);
|
||||
r = strtoull(temp,NULL,10);
|
||||
free(temp);
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t Int::GetInt32() {
|
||||
return mpz_get_ui(num);
|
||||
}
|
||||
|
||||
int Int::GetBit(uint32_t n) {
|
||||
return mpz_tstbit(num,n);
|
||||
}
|
||||
|
||||
|
||||
void Int::Get32Bytes(unsigned char *buff) {
|
||||
size_t count, size = this->GetSize();
|
||||
memset(buff, 0, 32);
|
||||
mpz_export(buff + 32 - size, &count, 0, 1, 0, 0, num);
|
||||
}
|
||||
|
||||
void Int::Set32Bytes(unsigned char *buff) {
|
||||
mpz_import(num,32,0,1,0,0,buff);
|
||||
}
|
||||
|
||||
unsigned char Int::GetByte(int n) {
|
||||
unsigned char buffer[32];
|
||||
size_t count, size = this->GetSize();
|
||||
memset(buffer, 0, 32);
|
||||
mpz_export(buffer + 32 - size, &count, 0, 1, 0, 0, num);
|
||||
return buffer[n];
|
||||
}
|
||||
|
||||
/*
|
||||
void mpz_get_byte(mpz_t num, unsigned char* bytes, size_t index) {
|
||||
size_t num_bytes = (mpz_sizeinbase(num, 2) + 7) / 8; // Calculate the total number of bytes
|
||||
if (index < num_bytes) {
|
||||
mpz_export(bytes, NULL, 1, sizeof(unsigned char), 0, 0, num); // Export the mpz_t variable to bytes
|
||||
} else {
|
||||
// Handle invalid index
|
||||
printf("Error: Index out of range.\n");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
unsigned char Int::GetByte(unsigned char *buff) {
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
char* Int::GetBase2() {
|
||||
return mpz_get_str(NULL,2,num);
|
||||
}
|
||||
|
||||
char* Int::GetBase10() {
|
||||
return mpz_get_str(NULL,10,num);
|
||||
}
|
||||
|
||||
char* Int::GetBase16() {
|
||||
return mpz_get_str(NULL,16,num);
|
||||
}
|
||||
|
||||
/*
|
||||
char* Int::GetBaseN(int n,const char *charset);
|
||||
char* Int::GetBlockStr();
|
||||
char* Int::GetC64Str(int nbDigit);
|
||||
*/
|
||||
|
||||
|
||||
void Int::SetInt64(uint64_t value) {
|
||||
char my_str_value[U64STRINGSIZE]; // 30 digits + null terminator
|
||||
snprintf(my_str_value, U64STRINGSIZE, "%lu", value);
|
||||
mpz_set_str(num,my_str_value,0);
|
||||
}
|
||||
|
||||
void Int::SetInt32(const uint32_t value) {
|
||||
mpz_set_ui(num,value);
|
||||
}
|
||||
|
||||
void Int::Set(const Int* other) {
|
||||
mpz_set(num,other->num);
|
||||
}
|
||||
|
||||
void Int::Set(const char *str) {
|
||||
mpz_set_str(num,str,0);
|
||||
}
|
||||
|
||||
void Int::SetBase10(const char *str) {
|
||||
mpz_set_str(num,str,10);
|
||||
}
|
||||
|
||||
void Int::SetBase16(const char *str) {
|
||||
mpz_set_str(num,str,16);
|
||||
}
|
||||
|
||||
Int::~Int() {
|
||||
mpz_clear(num);
|
||||
}
|
||||
|
||||
// Copy assignment operator
|
||||
Int& Int::operator=(const Int& other) {
|
||||
// Check for self-assignment
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign the values from 'other' to the current object
|
||||
mpz_set(num,other.num);
|
||||
|
||||
// Return the current object
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Int::AddOne() {
|
||||
mpz_add_ui(num,num,1);
|
||||
}
|
||||
|
||||
void Int::ShiftL(uint32_t n) {
|
||||
mpz_mul_2exp(num,num,n);
|
||||
|
||||
}
|
||||
|
||||
void Int::Div(Int *a,Int *mod) {
|
||||
if(mpz_cmp(num,a->num) < 0) {
|
||||
if(mod) mpz_set(mod->num,num);
|
||||
CLEAR();
|
||||
return;
|
||||
}
|
||||
if(mpz_cmp_ui(a->num,0) == 0) {
|
||||
printf("Divide by 0!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(mpz_cmp(num,a->num) == 0) {
|
||||
if(mod) mod->CLEAR();
|
||||
mpz_set_ui(num,1);
|
||||
return;
|
||||
}
|
||||
if(mod) {
|
||||
mpz_fdiv_qr (num, mod->num, num, a->num);
|
||||
}
|
||||
else {
|
||||
mpz_fdiv_q(num,num,a->num);
|
||||
}
|
||||
}
|
||||
|
||||
void Int::CLEAR() {
|
||||
mpz_set_ui(num,0);
|
||||
}
|
153
gmp256k1/Int.h
Normal file
153
gmp256k1/Int.h
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
This file is part of the Keyhunt distribution (https://github.com/albertobsd/keyhunt).
|
||||
Copyright (c) 2020 Luis Alberto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
// Big integer class (GMP)
|
||||
|
||||
#ifndef BIGINTH
|
||||
#define BIGINTH
|
||||
|
||||
#include "Random.h"
|
||||
#include<stdlib.h>
|
||||
#include<stdint.h>
|
||||
#include<gmp.h>
|
||||
|
||||
class Int {
|
||||
public:
|
||||
mpz_t num;
|
||||
|
||||
Int();
|
||||
Int(const char*);
|
||||
Int(const int32_t);
|
||||
Int(const uint32_t);
|
||||
Int(const int64_t);
|
||||
Int(const uint64_t);
|
||||
Int(const Int*);
|
||||
Int(const Int&);
|
||||
|
||||
/* Aritmetic*/
|
||||
void Add(const uint64_t);
|
||||
void Add(const uint32_t);
|
||||
void Add(const Int*);
|
||||
void Add(const Int*,const Int*);
|
||||
void AddOne();
|
||||
void Sub(const uint64_t);
|
||||
void Sub(const uint32_t);
|
||||
void Sub(Int *);
|
||||
void Sub(Int *a, Int *b);
|
||||
void Mult(Int *);
|
||||
void Mult(uint64_t );
|
||||
void IMult(int64_t );
|
||||
|
||||
void Div(Int *a,Int *mod = NULL);
|
||||
/*
|
||||
void Mult(Int *a,uint64_t b);
|
||||
void IMult(Int *a, int64_t b);
|
||||
void Mult(Int *a,Int *b)M
|
||||
*/
|
||||
void Neg();
|
||||
void Abs();
|
||||
|
||||
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();
|
||||
|
||||
/*Setters*/
|
||||
void SetInt64(const uint64_t value);
|
||||
void SetInt32(const uint32_t value);
|
||||
void Set(const Int* other);
|
||||
void Set(const char *str);
|
||||
void SetBase10(const char *str);
|
||||
void SetBase16(const char *str);
|
||||
|
||||
// Size
|
||||
int GetSize();
|
||||
int GetBitLength();
|
||||
//
|
||||
uint64_t GetInt64();
|
||||
uint32_t GetInt32();
|
||||
int GetBit(uint32_t n);
|
||||
unsigned char GetByte(int n);
|
||||
void Get32Bytes(unsigned char *buff);
|
||||
void Set32Bytes(unsigned char *buff);
|
||||
|
||||
char* GetBase2();
|
||||
char* GetBase10();
|
||||
char* GetBase16();
|
||||
/*
|
||||
char* GetBaseN(int n,const char *charset);
|
||||
char* GetBlockStr();
|
||||
char* GetC64Str(int nbDigit);
|
||||
*/
|
||||
// Left shift
|
||||
void ShiftL(uint32_t n);
|
||||
void Mod(Int *a); // this <- this (mod a)
|
||||
|
||||
/*
|
||||
All next mod n are setup as mod P, where P = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
|
||||
*/
|
||||
void ModInv(); // this <- this^-1 (mod n)
|
||||
void ModAdd(Int *a); // this <- this+a (mod n) [0<a<P]
|
||||
void ModAdd(uint32_t 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 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); // this <- this*b (mod n)
|
||||
void ModMul(Int *a,Int *b); // this <- a*b (mod n)
|
||||
void ModNeg(); // this <- -this (mod n)
|
||||
void ModDouble(); // this <- 2*this (mod n)
|
||||
void ModSqrt(); // this <- +/-sqrt(this) (mod n)
|
||||
bool HasSqrt(); // true if this admit a square root
|
||||
|
||||
/*
|
||||
Rand functions are
|
||||
*/
|
||||
void Rand(int nbit); // return a rand number bewteen [ 2^(nbit-1) and 2^nbit
|
||||
void Rand(Int *min,Int *max); // return a rand number bewteen [min and max)
|
||||
|
||||
static void SetupField(Int *n);
|
||||
|
||||
// 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);
|
||||
|
||||
~Int();
|
||||
Int& operator=(const Int& other); // Declaration
|
||||
void CLEAR();
|
||||
|
||||
};
|
||||
#endif // BIGINTH
|
58
gmp256k1/IntGroup.cpp
Normal file
58
gmp256k1/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 *)calloc(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);
|
||||
|
||||
}
|
42
gmp256k1/IntGroup.h
Normal file
42
gmp256k1/IntGroup.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
This file is part of the Keyhunt distribution (https://github.com/albertobsd/keyhunt).
|
||||
Copyright (c) 2020 Luis Alberto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#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
|
144
gmp256k1/IntMod.cpp
Normal file
144
gmp256k1/IntMod.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
#include "Int.h"
|
||||
|
||||
static Int _P; // Field characteristic
|
||||
static Int _R2o; // R^2 for SecpK1 order modular mult
|
||||
static Int *_O; // Field Order
|
||||
|
||||
void Int::Mod(Int *A) {
|
||||
mpz_mod(num,num,A->num);
|
||||
}
|
||||
|
||||
void Int::ModInv() {
|
||||
mpz_invert(num,num,_P.num);
|
||||
}
|
||||
|
||||
void Int::ModNeg() {
|
||||
mpz_neg(num,num);
|
||||
mpz_add(num,num,_P.num);
|
||||
}
|
||||
|
||||
void Int::ModAdd(Int *a) {
|
||||
mpz_t p;
|
||||
mpz_add(num,num,a->num);
|
||||
mpz_init_set(p,num);
|
||||
mpz_sub(p,p,_P.num);
|
||||
if(mpz_cmp_ui(p,0) >= 0)
|
||||
mpz_set(num,p);
|
||||
mpz_clear(p);
|
||||
}
|
||||
|
||||
|
||||
void Int::ModAdd(uint32_t a) {
|
||||
mpz_t p;
|
||||
mpz_add_ui(num,num,a);
|
||||
mpz_init_set(p,num);
|
||||
mpz_sub(p,p,_P.num);
|
||||
if(mpz_cmp_ui(p,0) >= 0)
|
||||
mpz_set(num,p);
|
||||
mpz_clear(p);
|
||||
}
|
||||
|
||||
void Int::ModAdd(Int *a, Int *b) {
|
||||
mpz_t p;
|
||||
mpz_add(num,a->num,b->num);
|
||||
mpz_init_set(p,num);
|
||||
mpz_sub(p,p,_P.num);
|
||||
if(mpz_cmp_ui(p,0) >= 0)
|
||||
mpz_set(num,p);
|
||||
mpz_clear(p);
|
||||
}
|
||||
|
||||
void Int::ModMul(Int *a) { // this <- this*b (mod n)
|
||||
mpz_mul(num,num,a->num);
|
||||
mpz_mod(num,num,_P.num);
|
||||
}
|
||||
|
||||
void Int::ModMul(Int *a,Int *b) { // this <- a*b (mod n)
|
||||
mpz_mul(num,a->num,b->num);
|
||||
mpz_mod(num,num,_P.num);
|
||||
}
|
||||
|
||||
void Int::ModSub(Int *a) {
|
||||
mpz_sub(num,num,a->num);
|
||||
if (mpz_cmp_ui(num,0) < 0 )
|
||||
mpz_add(num,num,_P.num);
|
||||
}
|
||||
|
||||
void Int::ModSub(Int *a,Int *b) {
|
||||
mpz_sub(num,a->num,b->num);
|
||||
if (mpz_cmp_ui(num,0) < 0 )
|
||||
mpz_add(num,num,_P.num);
|
||||
}
|
||||
|
||||
void Int::ModSub(uint64_t a) {
|
||||
Int A(a);
|
||||
mpz_add(num,num,A.num);
|
||||
if (mpz_cmp_ui(num,0) < 0)
|
||||
mpz_add(num,num,_P.num);
|
||||
}
|
||||
|
||||
|
||||
void Int::ModMulK1(Int *a, Int *b) {
|
||||
mpz_mul(num,a->num,b->num);
|
||||
mpz_mod(num,num,_P.num);
|
||||
}
|
||||
|
||||
void Int::ModMulK1(Int *a) {
|
||||
mpz_mul(num,num,a->num);
|
||||
mpz_mod(num,num,_P.num);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Int::ModSquareK1(Int *a) {
|
||||
mpz_powm_ui(num,a->num,2,_P.num);
|
||||
}
|
||||
|
||||
void Int::ModDouble() {
|
||||
mpz_t p;
|
||||
mpz_add(num,num,num);
|
||||
mpz_init_set(p,num);
|
||||
mpz_sub(p,p,_P.num);
|
||||
if(mpz_cmp(p,0) > 0) {
|
||||
mpz_set(num,p);
|
||||
}
|
||||
mpz_clear(p);
|
||||
}
|
||||
|
||||
void Int::ModSqrt() {
|
||||
mpz_sqrt(num,num);
|
||||
mpz_mod(num,num,_P.num);
|
||||
}
|
||||
|
||||
bool Int::HasSqrt() {
|
||||
if(mpz_perfect_square_p(num) != 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Initializator of some Values P and N (Order) */
|
||||
|
||||
void Int::SetupField(Int *n) {
|
||||
_P.Set(n);
|
||||
}
|
||||
|
||||
void Int::InitK1(Int *order) {
|
||||
_O = order;
|
||||
_R2o.SetBase16("9D671CD581C69BC5E697F5E45BCD07C6741496C20E7CF878896CF21467D7D140");
|
||||
}
|
||||
|
||||
/* This next Opeations that have endin in order are modulo N */
|
||||
|
||||
void Int::ModMulK1order(Int *a) {
|
||||
mpz_mul(num,num,a->num);
|
||||
mpz_mod(num,num,_O->num);
|
||||
}
|
||||
|
||||
void Int::ModAddK1order(Int *a, Int *b) {
|
||||
mpz_add(num,num,a->num);
|
||||
mpz_add(num,num,b->num);
|
||||
mpz_sub(num,num,_O->num);
|
||||
if (mpz_cmp_ui(num,0) < 0 )
|
||||
mpz_add(num,num,_O->num);
|
||||
}
|
153
gmp256k1/Point.cpp
Normal file
153
gmp256k1/Point.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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"
|
||||
#include <stdio.h>
|
||||
|
||||
Point::Point() {
|
||||
|
||||
}
|
||||
|
||||
Point::Point(const Point &p) {
|
||||
|
||||
//char *ptrs[3];
|
||||
mpz_set(x.num,p.x.num);
|
||||
mpz_set(y.num,p.y.num);
|
||||
mpz_set(z.num,p.z.num);
|
||||
/*
|
||||
ptrs[0] = x.GetBase16();
|
||||
ptrs[1] = y.GetBase16();
|
||||
ptrs[2] = z.GetBase16();
|
||||
printf("Point\n");
|
||||
printf("X: %s\n",ptrs[0]);
|
||||
printf("Y: %s\n",ptrs[1]);
|
||||
printf("Z: %s\n",ptrs[2]);
|
||||
printf("End Point\n");
|
||||
for(int i = 0; i<3; i++) {
|
||||
free(ptrs[i]);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
Point::Point(Int *cx,Int *cy,Int *cz) {
|
||||
mpz_set(x.num,cx->num);
|
||||
mpz_set(y.num,cy->num);
|
||||
mpz_set(z.num,cz->num);
|
||||
}
|
||||
|
||||
/*
|
||||
Point::Point(Int *cx, Int *cz) {
|
||||
x.Set(cx);
|
||||
z.Set(cz);
|
||||
}
|
||||
*/
|
||||
|
||||
void Point::Clear() {
|
||||
mpz_set_ui(x.num,0);
|
||||
mpz_set_ui(y.num,0);
|
||||
mpz_set_ui(z.num,0);
|
||||
}
|
||||
|
||||
void Point::Set(Int *cx, Int *cy,Int *cz) {
|
||||
mpz_set(x.num,cx->num);
|
||||
mpz_set(y.num,cy->num);
|
||||
mpz_set(z.num,cz->num);
|
||||
}
|
||||
|
||||
Point::~Point() {
|
||||
|
||||
}
|
||||
|
||||
void Point::Set(Point &p) {
|
||||
mpz_set(x.num,p.x.num);
|
||||
mpz_set(y.num,p.y.num);
|
||||
mpz_set(z.num,p.z.num);
|
||||
}
|
||||
|
||||
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);
|
||||
/*
|
||||
Yes, exactly. The Reduce function you mentioned converts the point from projective coordinates back to affine coordinates.
|
||||
|
||||
In elliptic curve computations, it's often more efficient to work with projective coordinates because they allow addition and doubling operations to be performed without needing to do division operations, which are computationally expensive.
|
||||
|
||||
However, at the end of your computation, or at certain intermediate stages, you might need to convert the point back to affine coordinates. That's what this Reduce function is doing.
|
||||
|
||||
Here's what each line in Reduce is doing:
|
||||
|
||||
Int i(&z); creates an integer i from the z coordinate of the point.
|
||||
i.ModInv(); computes the modular inverse of i, effectively performing a division operation. Note that this operation is only valid if i is not zero.
|
||||
x.ModMul(&x,&i); and y.ModMul(&y,&i); multiply the x and y coordinates by the modular inverse of z, effectively dividing them by z. This converts the x and y coordinates from projective back to affine coordinates.
|
||||
z.SetInt32(1); sets the z coordinate to 1, completing the conversion to affine coordinates.
|
||||
In the end, Reduce leaves the point in the form (X/Z, Y/Z, 1), which is equivalent to (X, Y) in affine coordinates.
|
||||
*/
|
||||
}
|
||||
|
||||
bool Point::equals(Point &p) {
|
||||
return x.IsEqual(&p.x) && y.IsEqual(&p.y) && z.IsEqual(&p.z);
|
||||
}
|
||||
|
||||
// Copy assignment operator
|
||||
Point& Point::operator=(const Point& other) {
|
||||
// Check for self-assignment
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
//char *ptrs[3];
|
||||
// Assign the values from 'other' to the current object
|
||||
mpz_set(x.num,other.x.num);
|
||||
mpz_set(y.num,other.y.num);
|
||||
mpz_set(z.num,other.z.num);
|
||||
/*
|
||||
ptrs[0] = x.GetBase16();
|
||||
ptrs[1] = y.GetBase16();
|
||||
ptrs[2] = z.GetBase16();
|
||||
printf("Point\n");
|
||||
printf("X: %s\n",ptrs[0]);
|
||||
printf("Y: %s\n",ptrs[1]);
|
||||
printf("Z: %s\n",ptrs[2]);
|
||||
printf("End Point\n");
|
||||
for(int i = 0; i<3; i++) {
|
||||
free(ptrs[i]);
|
||||
}
|
||||
*/
|
||||
// Return the current object
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Point::print(const char *str) {
|
||||
char *ptrs[3];
|
||||
ptrs[0] = x.GetBase16();
|
||||
ptrs[1] = y.GetBase16();
|
||||
ptrs[2] = z.GetBase16();
|
||||
printf("Point %s\n",str);
|
||||
printf("X: %s\n",ptrs[0]);
|
||||
printf("Y: %s\n",ptrs[1]);
|
||||
printf("Z: %s\n",ptrs[2]);
|
||||
printf("End Point\n");
|
||||
for(int i = 0; i<3; i++) {
|
||||
free(ptrs[i]);
|
||||
}
|
||||
}
|
48
gmp256k1/Point.h
Normal file
48
gmp256k1/Point.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
This file is part of the Keyhunt distribution (https://github.com/albertobsd/keyhunt).
|
||||
Copyright (c) 2020 Luis Alberto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef POINTH
|
||||
#define POINTH
|
||||
|
||||
#include "Int.h"
|
||||
|
||||
class Point {
|
||||
public:
|
||||
Point();
|
||||
Point(Int *cx, Int *cy,Int *cz);
|
||||
Point& operator=(const Point& other);
|
||||
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();
|
||||
void print(const char *str);
|
||||
Int x;
|
||||
Int y;
|
||||
Int z;
|
||||
};
|
||||
|
||||
#endif // POINTH
|
94
gmp256k1/Random.cpp
Normal file
94
gmp256k1/Random.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gmp.h>
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <Windows.h>
|
||||
#include <bcrypt.h>
|
||||
#pragma comment(lib, "bcrypt.lib")
|
||||
#elif __unix__ || __unix || __APPLE__ || __MACH__ || __CYGWIN__
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <linux/random.h>
|
||||
#if defined(GRND_NONBLOCK)
|
||||
#define USE_GETRANDOM
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "Int.h"
|
||||
|
||||
static int r_state_mt_ready = 0;
|
||||
static gmp_randstate_t r_state_mt;
|
||||
|
||||
|
||||
void int_randominit() {
|
||||
if(r_state_mt_ready) {
|
||||
fprintf(stderr,"r_state_mt already initialized, file %s, line %i\n",__FILE__,__LINE__ - 1);
|
||||
exit(0);
|
||||
}
|
||||
mpz_t mpz_seed;
|
||||
int bytes_readed,bytes = 64;
|
||||
unsigned char seed[64];
|
||||
bytes_readed = random_bytes(seed, bytes);
|
||||
if(bytes_readed != bytes) {
|
||||
fprintf(stderr,"Error random_bytes(), file %s, line %i\n",__FILE__,__LINE__ - 2);
|
||||
exit(0);
|
||||
}
|
||||
mpz_init(mpz_seed);
|
||||
mpz_import(mpz_seed,bytes,1,sizeof(unsigned char),0,0,seed);
|
||||
gmp_randinit_mt(r_state_mt);
|
||||
gmp_randseed(r_state_mt,mpz_seed);
|
||||
r_state_mt_ready = 1;
|
||||
mpz_clear(mpz_seed);
|
||||
memset(seed,0,bytes);
|
||||
}
|
||||
|
||||
void Int::Rand(int nbit) {
|
||||
if(!r_state_mt_ready) {
|
||||
fprintf(stderr,"Error Rand(), file %s, line %i\n",__FILE__,__LINE__ - 1);
|
||||
exit(0);
|
||||
}
|
||||
mpz_urandomb(num,r_state_mt,nbit);
|
||||
mpz_setbit(num,nbit-1);
|
||||
}
|
||||
|
||||
void Int::Rand(Int *min,Int *max) {
|
||||
if(!r_state_mt_ready) {
|
||||
fprintf(stderr,"Error Rand(), file %s, line %i\n",__FILE__,__LINE__ - 1);
|
||||
exit(0);
|
||||
}
|
||||
Int diff(max);
|
||||
diff.Sub(min);
|
||||
this->Rand(256);
|
||||
this->Mod(&diff);
|
||||
this->Add(min);
|
||||
}
|
||||
|
||||
int random_bytes(unsigned char *buffer,int bytes) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (!BCryptGenRandom(NULL, buffer, length, BCRYPT_USE_SYSTEM_PREFERRED_RNG)) {
|
||||
fprintf(stderr,"Not BCryptGenRandom available\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else
|
||||
return bytes;
|
||||
#elif __unix__ || __unix || __APPLE__ || __MACH__ || __CYGWIN__
|
||||
#ifdef USE_GETRANDOM
|
||||
return syscall(SYS_getrandom, buffer, bytes, GRND_NONBLOCK);
|
||||
#else
|
||||
int fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
fprintf(stderr,"Not /dev/urandom available\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
ssize_t result = read(fd, buffer, bytes);
|
||||
close(fd);
|
||||
return result;
|
||||
#endif
|
||||
#else
|
||||
#error "Unsupported platform"
|
||||
#endif
|
||||
}
|
30
gmp256k1/Random.h
Normal file
30
gmp256k1/Random.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
This file is part of the Keyhunt distribution (https://github.com/albertobsd/keyhunt).
|
||||
Copyright (c) 2020 Luis Alberto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef RANDOM_H
|
||||
#define RANDOM_H
|
||||
|
||||
void int_randominit();
|
||||
int random_bytes(unsigned char *buffer,int bytes);
|
||||
|
||||
#endif
|
148
hashing.c
Normal file
148
hashing.c
Normal file
@ -0,0 +1,148 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "hashing.h"
|
||||
|
||||
int sha256(const unsigned char *data, size_t length, unsigned char *digest) {
|
||||
EVP_MD_CTX *mdctx;
|
||||
const EVP_MD *md;
|
||||
md = EVP_sha256();
|
||||
if(!md) {
|
||||
printf("Unknown message digest sha256\n");
|
||||
return 1;
|
||||
}
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
if(!mdctx) {
|
||||
printf("Failed to create new EVP_MD_CTX\n");
|
||||
return 1;
|
||||
}
|
||||
if(EVP_DigestInit_ex(mdctx, md, NULL) != 1) {
|
||||
printf("Failed to initialize EVP_Digest with sha256\n");
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 1;
|
||||
}
|
||||
if(EVP_DigestUpdate(mdctx, data, length) != 1) {
|
||||
printf("Failed to update digest\n");
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 1;
|
||||
}
|
||||
unsigned int digest_len;
|
||||
if(EVP_DigestFinal_ex(mdctx, digest, &digest_len) != 1) {
|
||||
printf("Failed to finalize digest\n");
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 1;
|
||||
}
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 0; // Success
|
||||
}
|
||||
|
||||
// Function for hashing
|
||||
int keccak(const unsigned char *data, size_t length, unsigned char *digest) {
|
||||
EVP_MD_CTX *mdctx;
|
||||
const EVP_MD *md;
|
||||
md = EVP_get_digestbyname("keccak256");
|
||||
if(!md) {
|
||||
printf("Unknown message digest keccak256\n");
|
||||
return 1;
|
||||
}
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
if(!mdctx) {
|
||||
printf("Failed to create new EVP_MD_CTX\n");
|
||||
return 1;
|
||||
}
|
||||
if(EVP_DigestInit_ex(mdctx, md, NULL) != 1) {
|
||||
printf("Failed to initialize EVP_Digest with keccak256\n");
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 1;
|
||||
}
|
||||
if(EVP_DigestUpdate(mdctx, data, length) != 1) {
|
||||
printf("Failed to update digest\n");
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 1;
|
||||
}
|
||||
unsigned int digest_len;
|
||||
if(EVP_DigestFinal_ex(mdctx, digest, &digest_len) != 1) {
|
||||
printf("Failed to finalize digest\n");
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 1;
|
||||
}
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 0; // Success
|
||||
}
|
||||
|
||||
int rmd160(const unsigned char *data, size_t length, unsigned char *digest) {
|
||||
EVP_MD_CTX *mdctx;
|
||||
const EVP_MD *md;
|
||||
md = EVP_get_digestbyname("rmd160");
|
||||
if(!md) {
|
||||
printf("Unknown message digest rmd160\n");
|
||||
return 1;
|
||||
}
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
if(!mdctx) {
|
||||
printf("Failed to create new EVP_MD_CTX\n");
|
||||
return 1;
|
||||
}
|
||||
if(EVP_DigestInit_ex(mdctx, md, NULL) != 1) {
|
||||
printf("Failed to initialize EVP_Digest with rmd160\n");
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 1;
|
||||
}
|
||||
if(EVP_DigestUpdate(mdctx, data, length) != 1) {
|
||||
printf("Failed to update digest\n");
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 1;
|
||||
}
|
||||
unsigned int digest_len;
|
||||
if(EVP_DigestFinal_ex(mdctx, digest, &digest_len) != 1) {
|
||||
printf("Failed to finalize digest\n");
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 1;
|
||||
}
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 0; // Success
|
||||
}
|
||||
|
||||
bool sha256_file(const char* file_name, uint8_t* digest) {
|
||||
FILE* file = fopen(file_name, "rb");
|
||||
if (file == NULL) {
|
||||
printf("Failed to open file: %s\n", file_name);
|
||||
return false;
|
||||
}
|
||||
uint8_t buffer[8192]; // Buffer to read file contents
|
||||
size_t bytes_read;
|
||||
EVP_MD_CTX *mdctx;
|
||||
const EVP_MD *md;
|
||||
md = EVP_sha256();
|
||||
if(!md) {
|
||||
printf("Unknown message digest sha256\n");
|
||||
return false;
|
||||
}
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
if(!mdctx) {
|
||||
printf("Failed to create new EVP_MD_CTX\n");
|
||||
return false;
|
||||
}
|
||||
if(EVP_DigestInit_ex(mdctx, md, NULL) != 1) {
|
||||
printf("Failed to initialize EVP_Digest with sha256\n");
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return false;
|
||||
}
|
||||
// Read file contents and update SHA256 context
|
||||
while ((bytes_read = fread(buffer, 1, sizeof(buffer), file)) > 0) {
|
||||
if(EVP_DigestUpdate(mdctx, buffer, bytes_read) != 1) {
|
||||
printf("Failed to update digest\n");
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
unsigned int digest_len;
|
||||
if(EVP_DigestFinal_ex(mdctx, digest, &digest_len) != 1) {
|
||||
printf("Failed to finalize digest\n");
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return 1;
|
||||
}
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
12
hashing.h
Normal file
12
hashing.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef HASHSING
|
||||
#define HASHSING
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <string.h>
|
||||
|
||||
int sha256(const unsigned char *data, size_t length, unsigned char *digest);
|
||||
int rmd160(const unsigned char *data, size_t length, unsigned char *digest);
|
||||
int keccak(const unsigned char *data, size_t length, unsigned char *digest);
|
||||
bool sha256_file(const char* file_name, unsigned char * checksum);
|
||||
|
||||
#endif // HASHSING
|
7142
keyhunt_legacy.cpp
Normal file
7142
keyhunt_legacy.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -146,7 +146,6 @@ int oldbloom_check(struct oldbloom * bloom, const void * buffer, int len)
|
||||
uint64_t b = XXH64(buffer, len, a);
|
||||
uint64_t x;
|
||||
uint8_t i;
|
||||
int r;
|
||||
for (i = 0; i < bloom->hashes; i++) {
|
||||
x = (a + b*i) % bloom->bits;
|
||||
if (oldtest_bit(bloom->bf, x)) {
|
||||
|
227
oldbloom/bloom.h
227
oldbloom/bloom.h
@ -1,227 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2019, Jyri J. Virkki
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is under BSD license. See LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef _OLDBLOOM_H
|
||||
#define _OLDBLOOM_H
|
||||
|
||||
#ifdef _WIN64
|
||||
#include <windows.h>
|
||||
#else
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Structure to keep track of one bloom filter. Caller needs to
|
||||
* allocate this and pass it to the functions below. First call for
|
||||
* every struct must be to bloom_init().
|
||||
*
|
||||
*/
|
||||
struct oldbloom
|
||||
{
|
||||
// These fields are part of the public interface of this structure.
|
||||
// Client code may read these values if desired. Client code MUST NOT
|
||||
// modify any of these.
|
||||
uint64_t entries;
|
||||
uint64_t bits;
|
||||
uint64_t bytes;
|
||||
uint8_t hashes;
|
||||
long double error;
|
||||
|
||||
// Fields below are private to the implementation. These may go away or
|
||||
// change incompatibly at any moment. Client code MUST NOT access or rely
|
||||
// on these.
|
||||
uint8_t ready;
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
double bpe;
|
||||
uint8_t checksum[32];
|
||||
uint8_t checksum_backup[32];
|
||||
uint8_t *bf;
|
||||
#ifdef _WIN64
|
||||
HANDLE mutex;
|
||||
#else
|
||||
pthread_mutex_t mutex;
|
||||
#endif
|
||||
};
|
||||
/*
|
||||
Customs
|
||||
*/
|
||||
/*
|
||||
int oldbloom_loadcustom(struct oldbloom * bloom, char * filename);
|
||||
int oldbloom_savecustom(struct oldbloom * bloom, char * filename);
|
||||
*/
|
||||
|
||||
/** ***************************************************************************
|
||||
* Initialize the bloom filter for use.
|
||||
*
|
||||
* The filter is initialized with a bit field and number of hash functions
|
||||
* according to the computations from the wikipedia entry:
|
||||
* http://en.wikipedia.org/wiki/Bloom_filter
|
||||
*
|
||||
* Optimal number of bits is:
|
||||
* bits = (entries * ln(error)) / ln(2)^2
|
||||
*
|
||||
* Optimal number of hash functions is:
|
||||
* hashes = bpe * ln(2)
|
||||
*
|
||||
* Parameters:
|
||||
* -----------
|
||||
* bloom - Pointer to an allocated struct bloom (see above).
|
||||
* entries - The expected number of entries which will be inserted.
|
||||
* Must be at least 1000 (in practice, likely much larger).
|
||||
* error - Probability of collision (as long as entries are not
|
||||
* exceeded).
|
||||
*
|
||||
* Return:
|
||||
* -------
|
||||
* 0 - on success
|
||||
* 1 - on failure
|
||||
*
|
||||
*/
|
||||
int oldbloom_init2(struct oldbloom * bloom, uint64_t entries, long double error);
|
||||
|
||||
|
||||
/**
|
||||
* DEPRECATED.
|
||||
* Kept for compatibility with libbloom v.1. To be removed in v3.0.
|
||||
*
|
||||
*/
|
||||
int oldbloom_init(struct oldbloom * bloom, uint64_t entries, long double error);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Check if the given element is in the bloom filter. Remember this may
|
||||
* return false positive if a collision occurred.
|
||||
*
|
||||
* Parameters:
|
||||
* -----------
|
||||
* bloom - Pointer to an allocated struct bloom (see above).
|
||||
* buffer - Pointer to buffer containing element to check.
|
||||
* len - Size of 'buffer'.
|
||||
*
|
||||
* Return:
|
||||
* -------
|
||||
* 0 - element is not present
|
||||
* 1 - element is present (or false positive due to collision)
|
||||
* -1 - bloom not initialized
|
||||
*
|
||||
*/
|
||||
int oldbloom_check(struct oldbloom * bloom, const void * buffer, int len);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Add the given element to the bloom filter.
|
||||
* The return code indicates if the element (or a collision) was already in,
|
||||
* so for the common check+add use case, no need to call check separately.
|
||||
*
|
||||
* Parameters:
|
||||
* -----------
|
||||
* bloom - Pointer to an allocated struct bloom (see above).
|
||||
* buffer - Pointer to buffer containing element to add.
|
||||
* len - Size of 'buffer'.
|
||||
*
|
||||
* Return:
|
||||
* -------
|
||||
* 0 - element was not present and was added
|
||||
* 1 - element (or a collision) had already been added previously
|
||||
* -1 - bloom not initialized
|
||||
*
|
||||
*/
|
||||
int oldbloom_add(struct oldbloom * bloom, const void * buffer, int len);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Print (to stdout) info about this bloom filter. Debugging aid.
|
||||
*
|
||||
*/
|
||||
void oldbloom_print(struct oldbloom * bloom);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Deallocate internal storage.
|
||||
*
|
||||
* Upon return, the bloom struct is no longer usable. You may call bloom_init
|
||||
* again on the same struct to reinitialize it again.
|
||||
*
|
||||
* Parameters:
|
||||
* -----------
|
||||
* bloom - Pointer to an allocated struct bloom (see above).
|
||||
*
|
||||
* Return: none
|
||||
*
|
||||
*/
|
||||
void oldbloom_free(struct oldbloom * bloom);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Erase internal storage.
|
||||
*
|
||||
* Erases all elements. Upon return, the bloom struct returns to its initial
|
||||
* (initialized) state.
|
||||
*
|
||||
* Parameters:
|
||||
* -----------
|
||||
* bloom - Pointer to an allocated struct bloom (see above).
|
||||
*
|
||||
* Return:
|
||||
* 0 - on success
|
||||
* 1 - on failure
|
||||
*
|
||||
*/
|
||||
int oldbloom_reset(struct oldbloom * bloom);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Save a bloom filter to a file.
|
||||
*
|
||||
* Parameters:
|
||||
* -----------
|
||||
* bloom - Pointer to an allocated struct bloom (see above).
|
||||
* filename - Create (or overwrite) bloom data to this file.
|
||||
*
|
||||
* Return:
|
||||
* 0 - on success
|
||||
* 1 - on failure
|
||||
*
|
||||
*/
|
||||
//int oldbloom_save(struct oldbloom * bloom, char * filename);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Load a bloom filter from a file.
|
||||
*
|
||||
* This functions loads a file previously saved with bloom_save().
|
||||
*
|
||||
* Parameters:
|
||||
* -----------
|
||||
* bloom - Pointer to an allocated struct bloom (see above).
|
||||
* filename - Load bloom filter data from this file.
|
||||
*
|
||||
* Return:
|
||||
* 0 - on success
|
||||
* > 0 - on failure
|
||||
*
|
||||
*/
|
||||
//int oldbloom_load(struct oldbloom * bloom, char * filename);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Returns version string compiled into library.
|
||||
*
|
||||
* Return: version string
|
||||
*
|
||||
*/
|
||||
const char * oldbloom_version();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user