added keyhunt_legacy.cpp legacy version, check README.md

This commit is contained in:
Alberto 2023-05-15 19:21:59 -06:00
parent ee1f920b2f
commit a94643171a
20 changed files with 9105 additions and 231 deletions

View File

@ -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

View File

@ -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

View File

@ -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
```

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

View File

@ -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)) {

View File

@ -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