├── img
├── hash160_col40.jpg
└── hash160_col40_asymptote.jpg
├── .gitignore
├── Random.h
├── IntGroup.h
├── hash
├── sha512.h
├── sha256.h
├── ripemd160.h
├── ripemd160.cpp
├── sha512.cpp
├── ripemd160_sse.cpp
└── sha256.cpp
├── Point.h
├── BTCCollider.sln
├── Timer.h
├── IntGroup.cpp
├── Base58.h
├── Point.cpp
├── HashTable.h
├── GPU
├── GPUEngine.h
├── GPUCompute.h
├── GPUEngine.cu
└── GPUHash.h
├── BTCCollider.vcxproj.filters
├── SECP256k1.h
├── Makefile
├── Random.cpp
├── Base58.cpp
├── Bech32.h
├── BTCCollider.h
├── Timer.cpp
├── README.md
├── Bech32.cpp
├── main.cpp
├── BTCCollider.vcxproj
├── HashTable.cpp
└── Int.h
/img/hash160_col40.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JeanLucPons/BTCCollider/HEAD/img/hash160_col40.jpg
--------------------------------------------------------------------------------
/img/hash160_col40_asymptote.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JeanLucPons/BTCCollider/HEAD/img/hash160_col40_asymptote.jpg
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | DOC/
2 | .vs/
3 | BTCCollider.vcxproj.user
4 | vc140.pdb
5 | x64/
6 | obj/
7 | .idea/
8 | CMakeLists.txt
9 | BTCCollider
10 | cmake-build-debug/
11 | *.prf
12 |
--------------------------------------------------------------------------------
/Random.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef RANDOM_H
19 | #define RANDOM_H
20 |
21 | double rnd();
22 | unsigned long rndl();
23 | void rseed(unsigned long seed);
24 |
25 | #endif
26 |
--------------------------------------------------------------------------------
/IntGroup.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef INTGROUPH
19 | #define INTGROUPH
20 |
21 | #include "Int.h"
22 | #include
23 |
24 | class IntGroup {
25 |
26 | public:
27 |
28 | IntGroup(int size);
29 | ~IntGroup();
30 | void Set(Int *pts);
31 | void ModInv();
32 |
33 | private:
34 |
35 | Int *ints;
36 | Int *subp;
37 | int size;
38 |
39 | };
40 |
41 | #endif // INTGROUPCPUH
42 |
--------------------------------------------------------------------------------
/hash/sha512.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef SHA512_H
19 | #define SHA512_H
20 | #include
21 |
22 | void sha512(unsigned char *input, int length, unsigned char *digest);
23 | void pbkdf2_hmac_sha512(uint8_t *out, size_t outlen,const uint8_t *passwd, size_t passlen,const uint8_t *salt, size_t saltlen,uint64_t iter);
24 | void hmac_sha512(unsigned char *key, int key_length, unsigned char *message, int message_length, unsigned char *digest);
25 |
26 | std::string sha512_hex(unsigned char *digest);
27 |
28 | #endif
29 |
--------------------------------------------------------------------------------
/Point.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef POINTH
19 | #define POINTH
20 |
21 | #include "Int.h"
22 |
23 | class Point {
24 |
25 | public:
26 |
27 | Point();
28 | Point(Int *cx,Int *cy,Int *cz);
29 | Point(Int *cx, Int *cz);
30 | Point(const Point &p);
31 | ~Point();
32 | bool isZero();
33 | bool equals(Point &p);
34 | void Set(Point &p);
35 | void Set(Int *cx, Int *cy,Int *cz);
36 | void Clear();
37 | void Reduce();
38 | std::string toString();
39 |
40 | Int x;
41 | Int y;
42 | Int z;
43 |
44 | };
45 |
46 | #endif // POINTH
47 |
--------------------------------------------------------------------------------
/BTCCollider.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.102
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BTCCollider", "BTCCollider.vcxproj", "{9EA67A77-3F50-4FCE-85B9-FAB635FEFB0A}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Release|x64 = Release|x64
12 | ReleaseSM30|x64 = ReleaseSM30|x64
13 | EndGlobalSection
14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
15 | {9EA67A77-3F50-4FCE-85B9-FAB635FEFB0A}.Debug|x64.ActiveCfg = Debug|x64
16 | {9EA67A77-3F50-4FCE-85B9-FAB635FEFB0A}.Debug|x64.Build.0 = Debug|x64
17 | {9EA67A77-3F50-4FCE-85B9-FAB635FEFB0A}.Release|x64.ActiveCfg = Release|x64
18 | {9EA67A77-3F50-4FCE-85B9-FAB635FEFB0A}.Release|x64.Build.0 = Release|x64
19 | {9EA67A77-3F50-4FCE-85B9-FAB635FEFB0A}.ReleaseSM30|x64.ActiveCfg = ReleaseSM30|x64
20 | {9EA67A77-3F50-4FCE-85B9-FAB635FEFB0A}.ReleaseSM30|x64.Build.0 = ReleaseSM30|x64
21 | EndGlobalSection
22 | GlobalSection(SolutionProperties) = preSolution
23 | HideSolutionNode = FALSE
24 | EndGlobalSection
25 | GlobalSection(ExtensibilityGlobals) = postSolution
26 | SolutionGuid = {6D720311-0075-4355-907B-9404246E4B51}
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/Timer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef TIMERH
19 | #define TIMERH
20 |
21 | #include
22 | #include
23 | #ifdef WIN64
24 | #include
25 | #endif
26 |
27 | class Timer {
28 |
29 | public:
30 | static void Init();
31 | static double get_tick();
32 | static void printResult(char *unit, int nbTry, double t0, double t1);
33 | static std::string getResult(char *unit, int nbTry, double t0, double t1);
34 | static int getCoreNumber();
35 | static std::string getSeed(int size);
36 | static void SleepMillis(uint32_t millis);
37 |
38 | #ifdef WIN64
39 | static LARGE_INTEGER perfTickStart;
40 | static double perfTicksPerSec;
41 | static LARGE_INTEGER qwTicksPerSec;
42 | #else
43 | static time_t tickStart;
44 | #endif
45 |
46 | };
47 |
48 | #endif // TIMERH
49 |
--------------------------------------------------------------------------------
/hash/sha256.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef SHA256_H
19 | #define SHA256_H
20 | #include
21 |
22 | void sha256(uint8_t *input,int length, uint8_t *digest);
23 | void sha256_33(uint8_t *input, uint8_t *digest);
24 | void sha256_65(uint8_t *input, uint8_t *digest);
25 | void sha256_checksum(uint8_t *input, int length, uint8_t *checksum);
26 | void sha256sse_1B(uint32_t *i0, uint32_t *i1, uint32_t *i2, uint32_t *i3,
27 | uint8_t *d0, uint8_t *d1, uint8_t *d2, uint8_t *d3);
28 | void sha256sse_2B(uint32_t *i0, uint32_t *i1, uint32_t *i2, uint32_t *i3,
29 | uint8_t *d0, uint8_t *d1, uint8_t *d2, uint8_t *d3);
30 | void sha256sse_checksum(uint32_t *i0, uint32_t *i1, uint32_t *i2, uint32_t *i3,
31 | uint8_t *d0, uint8_t *d1, uint8_t *d2, uint8_t *d3);
32 | std::string sha256_hex(unsigned char *digest);
33 | void sha256sse_test();
34 |
35 | #endif
--------------------------------------------------------------------------------
/IntGroup.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include "IntGroup.h"
19 |
20 | using namespace std;
21 |
22 | IntGroup::IntGroup(int size) {
23 | this->size = size;
24 | subp = (Int *)malloc(size * sizeof(Int));
25 | }
26 |
27 | IntGroup::~IntGroup() {
28 | free(subp);
29 | }
30 |
31 | void IntGroup::Set(Int *pts) {
32 | ints = pts;
33 | }
34 |
35 | // Compute modular inversion of the whole group
36 | void IntGroup::ModInv() {
37 |
38 | Int newValue;
39 | Int inverse;
40 |
41 | subp[0].Set(&ints[0]);
42 | for (int i = 1; i < size; i++) {
43 | subp[i].ModMulK1(&subp[i - 1], &ints[i]);
44 | }
45 |
46 | // Do the inversion
47 | inverse.Set(&subp[size - 1]);
48 | inverse.ModInv();
49 |
50 | for (int i = size - 1; i > 0; i--) {
51 | newValue.ModMulK1(&subp[i - 1], &inverse);
52 | inverse.ModMulK1(&ints[i]);
53 | ints[i].Set(&newValue);
54 | }
55 |
56 | ints[0].Set(&inverse);
57 |
58 | }
--------------------------------------------------------------------------------
/Base58.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef BASE58_H
19 | #define BASE58_H
20 |
21 | #include
22 | #include
23 |
24 | /**
25 | * Encode a byte sequence as a base58-encoded string.
26 | * pbegin and pend cannot be nullptr, unless both are.
27 | */
28 | std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend);
29 |
30 | /**
31 | * Encode a byte vector as a base58-encoded string
32 | */
33 | std::string EncodeBase58(const std::vector& vch);
34 |
35 | /**
36 | * Decode a base58-encoded string (psz) into a byte vector (vchRet).
37 | * return true if decoding is successful.
38 | * psz cannot be nullptr.
39 | */
40 | bool DecodeBase58(const char* psz, std::vector& vchRet);
41 |
42 | /**
43 | * Decode a base58-encoded string (str) into a byte vector (vchRet).
44 | * return true if decoding is successful.
45 | */
46 | bool DecodeBase58(const std::string& str, std::vector& vchRet);
47 |
48 |
49 | #endif // BASE58_H
50 |
--------------------------------------------------------------------------------
/hash/ripemd160.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef RIPEMD160_H
19 | #define RIPEMD160_H
20 |
21 | #include
22 | #include
23 | #include
24 |
25 | /** A hasher class for RIPEMD-160. */
26 | class CRIPEMD160
27 | {
28 | private:
29 | uint32_t s[5];
30 | unsigned char buf[64];
31 | uint64_t bytes;
32 |
33 | public:
34 | CRIPEMD160();
35 | void Write(const unsigned char* data, size_t len);
36 | void Finalize(unsigned char hash[20]);
37 | };
38 |
39 | void ripemd160(unsigned char *input,int length,unsigned char *digest);
40 | void ripemd160_32(unsigned char *input, unsigned char *digest);
41 | void ripemd160sse_32(uint8_t *i0, uint8_t *i1, uint8_t *i2, uint8_t *i3,
42 | uint8_t *d0, uint8_t *d1, uint8_t *d2, uint8_t *d3);
43 | void ripemd160sse_test();
44 | std::string ripemd160_hex(unsigned char *digest);
45 |
46 | static inline bool ripemd160_comp_hash(uint8_t *h0, uint8_t *h1) {
47 | uint32_t *h0i = (uint32_t *)h0;
48 | uint32_t *h1i = (uint32_t *)h1;
49 | return (h0i[0] == h1i[0]) &&
50 | (h0i[1] == h1i[1]) &&
51 | (h0i[2] == h1i[2]) &&
52 | (h0i[3] == h1i[3]) &&
53 | (h0i[4] == h1i[4]);
54 | }
55 |
56 | #endif // RIPEMD160_H
57 |
--------------------------------------------------------------------------------
/Point.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include "Point.h"
19 |
20 | Point::Point() {
21 | }
22 |
23 | Point::Point(const Point &p) {
24 | x.Set((Int *)&p.x);
25 | y.Set((Int *)&p.y);
26 | z.Set((Int *)&p.z);
27 | }
28 |
29 | Point::Point(Int *cx,Int *cy,Int *cz) {
30 | x.Set(cx);
31 | y.Set(cy);
32 | z.Set(cz);
33 | }
34 |
35 | Point::Point(Int *cx, Int *cz) {
36 | x.Set(cx);
37 | z.Set(cz);
38 | }
39 |
40 | void Point::Clear() {
41 | x.SetInt32(0);
42 | y.SetInt32(0);
43 | z.SetInt32(0);
44 | }
45 |
46 | void Point::Set(Int *cx, Int *cy,Int *cz) {
47 | x.Set(cx);
48 | y.Set(cy);
49 | z.Set(cz);
50 | }
51 |
52 | Point::~Point() {
53 | }
54 |
55 | void Point::Set(Point &p) {
56 | x.Set(&p.x);
57 | y.Set(&p.y);
58 | }
59 |
60 | bool Point::isZero() {
61 | return x.IsZero() && y.IsZero();
62 | }
63 |
64 | void Point::Reduce() {
65 |
66 | Int i(&z);
67 | i.ModInv();
68 | x.ModMul(&x,&i);
69 | y.ModMul(&y,&i);
70 | z.SetInt32(1);
71 |
72 | }
73 |
74 | bool Point::equals(Point &p) {
75 | return x.IsEqual(&p.x) && y.IsEqual(&p.y) && z.IsEqual(&p.z);
76 | }
77 |
78 | std::string Point::toString() {
79 |
80 | std::string ret;
81 | ret = "X=" + x.GetBase16() + "\n";
82 | ret += "Y=" + y.GetBase16() + "\n";
83 | ret += "Z=" + z.GetBase16() + "\n";
84 | return ret;
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/HashTable.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef HASHTABLEH
19 | #define HASHTABLEH
20 |
21 | #include
22 |
23 | #define HASH_SIZE 65536
24 |
25 | union hash160_s {
26 |
27 | uint8_t i8[20];
28 | uint16_t i16[10];
29 | uint32_t i32[5];
30 | uint64_t i64[3];
31 |
32 | };
33 |
34 |
35 | typedef union hash160_s hash160_t;
36 |
37 | typedef struct ENTRY {
38 |
39 | hash160_t start;
40 | hash160_t end;
41 |
42 | } ENTRY;
43 |
44 | typedef struct {
45 |
46 | uint32_t nbItem;
47 | uint32_t maxItem;
48 | ENTRY **items;
49 |
50 | } HASH_ENTRY;
51 |
52 | #define NO_COLLISION 0
53 | #define COLLISION 1
54 | #define FALSE_COLLISION 2
55 |
56 | class HashTable {
57 |
58 | public:
59 |
60 | HashTable();
61 | void SetParam(int n,int nbFull,uint16_t colMask);
62 | int AddHash(hash160_t *start, hash160_t *end);
63 | void SaveTable(FILE *f);
64 | void LoadTable(FILE *f);
65 | std::string GetHashStr(hash160_t *h);
66 | void PrintTable(int limit=0);
67 | int GetNbItem();
68 | int getCollisionSize(hash160_t *h1, hash160_t *h2);
69 | void getCollision(hash160_t *a, hash160_t *b, hash160_t *e);
70 | void Reset();
71 | bool hashCollide(hash160_t *h1, hash160_t *h2);
72 | int compareHash(hash160_t *h1, hash160_t *h2);
73 | bool compare(HashTable *ht);
74 | uint16_t getHash(hash160_t *h);
75 | ENTRY *CreateEntry(hash160_t *h1, hash160_t *h2);
76 | double GetSizeMB();
77 |
78 | private:
79 |
80 |
81 | HASH_ENTRY E[HASH_SIZE];
82 |
83 | int cSize;
84 | int nbFull;
85 | int totalItem;
86 | uint16_t colMask;
87 | hash160_t a;
88 | hash160_t b;
89 | hash160_t e;
90 |
91 | };
92 |
93 | #endif // HASHTABLEH
94 |
--------------------------------------------------------------------------------
/GPU/GPUEngine.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef GPUENGINEH
19 | #define GPUENGINEH
20 |
21 | #include
22 | #include "../SECP256k1.h"
23 |
24 | #define ITEM_SIZE 40
25 | #define ITEM_SIZE32 (ITEM_SIZE/4)
26 | #define _64K 65536
27 |
28 | #define GPU_AFFINE
29 | #define GPU_GRP_SIZE 128
30 | #define NB_RUN 4
31 |
32 | typedef struct {
33 | uint8_t *h1;
34 | uint8_t *h2;
35 | } ITEM;
36 |
37 | class GPUEngine {
38 |
39 | public:
40 |
41 | GPUEngine(int nbThreadGroup,int nbThreadPerGroup,int gpuId,uint32_t maxFound);
42 | ~GPUEngine();
43 | void SetMasks(uint16_t colMask,uint64_t dpMask,uint16_t nbFull);
44 | void SetKeys(Int *p);
45 | void SetSearchType(int searchType);
46 | void SetExtraPoint(bool extraPoint);
47 | bool SetStartingHashes(uint64_t *sHash, uint64_t *cHash);
48 | bool GetHashes(uint64_t *sHash, uint64_t *cHash);
49 | bool Launch(std::vector- &hashFound,bool spinWait=false);
50 | int GetNbThread();
51 | int GetGroupSize();
52 | int GetMemory();
53 |
54 | std::string deviceName;
55 |
56 | static void *AllocatePinnedMemory(size_t size);
57 | static void FreePinnedMemory(void *buff);
58 | static void PrintCudaInfo();
59 | static bool GetGridSize(int gpuId, int *x, int *y);
60 |
61 | private:
62 |
63 | bool callKernel();
64 |
65 | int nbThread;
66 | int nbThreadPerGroup;
67 | int inputHashSize;
68 | int keySize;
69 | uint64_t *inputKey;
70 | uint64_t *inputKeyPinned;
71 | uint64_t *inputHash;
72 | uint64_t *inputHashPinned;
73 | uint32_t *outputHash;
74 | uint32_t *outputHashPinned;
75 | bool initialised;
76 | uint32_t searchType;
77 | bool littleEndian;
78 | bool lostWarning;
79 | bool useExtraPoints;
80 | uint32_t maxFound;
81 | uint32_t outputSize;
82 | uint64_t dpMask;
83 | uint16_t colMask;
84 | uint16_t nbFull;
85 |
86 | };
87 |
88 | #endif // GPUENGINEH
89 |
--------------------------------------------------------------------------------
/BTCCollider.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Hash
18 |
19 |
20 | Hash
21 |
22 |
23 | Hash
24 |
25 |
26 | Hash
27 |
28 |
29 | Hash
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | GPU
45 |
46 |
47 | GPU
48 |
49 |
50 | GPU
51 |
52 |
53 | GPU
54 |
55 |
56 | Hash
57 |
58 |
59 | Hash
60 |
61 |
62 | Hash
63 |
64 |
65 |
66 |
67 | {1ccbd2a5-ee1a-4058-bb6a-8742d7d09034}
68 |
69 |
70 | {b4959bb3-deb1-4ed0-8d76-d071c0b24894}
71 |
72 |
73 |
74 |
75 | GPU
76 |
77 |
78 |
--------------------------------------------------------------------------------
/SECP256k1.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef SECP256K1H
19 | #define SECP256K1H
20 |
21 | #include "Point.h"
22 | #include
23 | #include
24 |
25 | // Address type
26 | #define P2PKH 0
27 | #define P2SH 1
28 | #define BECH32 2
29 |
30 | class Secp256K1 {
31 |
32 | public:
33 |
34 | Secp256K1();
35 | ~Secp256K1();
36 | void Init();
37 | Point ComputePublicKey(Int *privKey);
38 | Point NextKey(Point &key);
39 | void Check();
40 | bool EC(Point &p);
41 |
42 | void GetHash160(int type,bool compressed,
43 | Point &k0, Point &k1, Point &k2, Point &k3,
44 | uint8_t *h0, uint8_t *h1, uint8_t *h2, uint8_t *h3);
45 |
46 | void GetCompressedHash160(int type,
47 | Int *x0, Int *x1, Int *x2, Int *x3,
48 | bool y0Odd, bool y1Odd, bool y2Odd, bool y3Odd,
49 | uint8_t *h0, uint8_t *h1, uint8_t *h2, uint8_t *h3);
50 |
51 | void GetHash160(int type,bool compressed, Point &pubKey, unsigned char *hash);
52 |
53 | void GetCompressedHash160(int type,Int *x, bool yOdd, unsigned char *hash);
54 |
55 | std::string GetAddress(int type, bool compressed, Point &pubKey);
56 | std::string GetAddress(int type, bool compressed, unsigned char *hash160);
57 | std::vector GetAddress(int type, bool compressed, unsigned char *h1, unsigned char *h2, unsigned char *h3, unsigned char *h4);
58 | std::string GetPrivAddress(bool compressed, Int &privKey );
59 | std::string GetPublicKeyHex(bool compressed, Point &p);
60 | Point ParsePublicKeyHex(std::string str, bool &isCompressed);
61 |
62 | bool CheckPudAddress(std::string address);
63 |
64 | static Int DecodePrivateKey(char *key,bool *compressed);
65 |
66 | Point Add(Point &p1, Point &p2);
67 | Point Add2(Point &p1, Point &p2);
68 | Point AddDirect(Point &p1, Point &p2);
69 | Point Double(Point &p);
70 | Point DoubleDirect(Point &p);
71 |
72 | Point G; // Generator
73 | Int order; // Curve order
74 |
75 | private:
76 |
77 | uint8_t GetByte(std::string &str,int idx);
78 |
79 | Int GetY(Int x, bool isEven);
80 | Point GTable[256*32]; // Generator table
81 |
82 | };
83 |
84 | #endif // SECP256K1H
85 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #---------------------------------------------------------------------
2 | # Makefile for BTCCollider
3 | #
4 | # Author : Jean-Luc PONS
5 |
6 | SRC = Base58.cpp IntGroup.cpp main.cpp Random.cpp \
7 | Timer.cpp Int.cpp IntMod.cpp Point.cpp SECP256K1.cpp \
8 | BTCCollider.cpp hash/ripemd160.cpp \
9 | hash/sha256.cpp hash/sha512.cpp hash/ripemd160_sse.cpp \
10 | hash/sha256_sse.cpp Bech32.cpp HashTable.cpp
11 |
12 | OBJDIR = obj
13 |
14 | ifdef gpu
15 |
16 | OBJET = $(addprefix $(OBJDIR)/, \
17 | Base58.o IntGroup.o main.o Random.o Timer.o Int.o \
18 | IntMod.o Point.o SECP256K1.o BTCCollider.o \
19 | hash/ripemd160.o hash/sha256.o hash/sha512.o \
20 | hash/ripemd160_sse.o hash/sha256_sse.o \
21 | GPU/GPUEngine.o Bech32.o HashTable.o)
22 |
23 | else
24 |
25 | OBJET = $(addprefix $(OBJDIR)/, \
26 | Base58.o IntGroup.o main.o Random.o Timer.o Int.o \
27 | IntMod.o Point.o SECP256K1.o BTCCollider.o \
28 | hash/ripemd160.o hash/sha256.o hash/sha512.o \
29 | hash/ripemd160_sse.o hash/sha256_sse.o Bech32.o \
30 | HashTable.o )
31 |
32 | endif
33 |
34 | CXX = g++
35 | CUDA = /usr/local/cuda-8.0
36 | CXXCUDA = /usr/bin/g++-4.8
37 | NVCC = $(CUDA)/bin/nvcc
38 |
39 | ifdef gpu
40 | ifdef debug
41 | CXXFLAGS = -DWITHGPU -m64 -mssse3 -Wno-unused-result -Wno-write-strings -g -I. -I$(CUDA)/include
42 | else
43 | CXXFLAGS = -DWITHGPU -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -I. -I$(CUDA)/include
44 | endif
45 | LFLAGS = -lpthread -L$(CUDA)/lib64 -lcudart
46 | else
47 | ifdef debug
48 | CXXFLAGS = -m64 -mssse3 -Wno-unused-result -Wno-write-strings -g -I. -I$(CUDA)/include
49 | else
50 | CXXFLAGS = -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -I. -I$(CUDA)/include
51 | endif
52 | LFLAGS = -lpthread
53 | endif
54 |
55 |
56 | #--------------------------------------------------------------------
57 |
58 | ifdef gpu
59 | ifdef debug
60 | $(OBJDIR)/GPU/GPUEngine.o: GPU/GPUEngine.cu
61 | $(NVCC) -G -maxrregcount=0 --ptxas-options=-v --compile --compiler-options -fPIC -ccbin $(CXXCUDA) -m64 -g -I$(CUDA)/include -gencode=arch=compute_$(ccap),code=sm_$(ccap) -o $(OBJDIR)/GPU/GPUEngine.o -c GPU/GPUEngine.cu
62 | else
63 | $(OBJDIR)/GPU/GPUEngine.o: GPU/GPUEngine.cu
64 | $(NVCC) -maxrregcount=0 --ptxas-options=-v --compile --compiler-options -fPIC -ccbin $(CXXCUDA) -m64 -O2 -I$(CUDA)/include -gencode=arch=compute_$(ccap),code=sm_$(ccap) -o $(OBJDIR)/GPU/GPUEngine.o -c GPU/GPUEngine.cu
65 | endif
66 | endif
67 |
68 | $(OBJDIR)/%.o : %.cpp
69 | $(CXX) $(CXXFLAGS) -o $@ -c $<
70 |
71 | all: BTCCollider
72 |
73 | BTCCollider: $(OBJET)
74 | @echo Making BTCCollider...
75 | $(CXX) $(OBJET) $(LFLAGS) -o BTCCollider
76 |
77 | $(OBJET): | $(OBJDIR) $(OBJDIR)/GPU $(OBJDIR)/hash
78 |
79 | $(OBJDIR):
80 | mkdir -p $(OBJDIR)
81 |
82 | $(OBJDIR)/GPU: $(OBJDIR)
83 | cd $(OBJDIR) && mkdir -p GPU
84 |
85 | $(OBJDIR)/hash: $(OBJDIR)
86 | cd $(OBJDIR) && mkdir -p hash
87 |
88 | clean:
89 | @echo Cleaning...
90 | @rm -f obj/*.o
91 | @rm -f obj/GPU/*.o
92 | @rm -f obj/hash/*.o
93 |
94 |
--------------------------------------------------------------------------------
/Random.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include "Random.h"
19 |
20 | #define RK_STATE_LEN 624
21 |
22 | /* State of the RNG */
23 | typedef struct rk_state_
24 | {
25 | unsigned long key[RK_STATE_LEN];
26 | int pos;
27 | } rk_state;
28 |
29 | rk_state localState;
30 |
31 | /* Maximum generated random value */
32 | #define RK_MAX 0xFFFFFFFFUL
33 |
34 | void rk_seed(unsigned long seed, rk_state *state)
35 | {
36 | int pos;
37 | seed &= 0xffffffffUL;
38 |
39 | /* Knuth's PRNG as used in the Mersenne Twister reference implementation */
40 | for (pos=0; poskey[pos] = seed;
43 | seed = (1812433253UL * (seed ^ (seed >> 30)) + pos + 1) & 0xffffffffUL;
44 | }
45 |
46 | state->pos = RK_STATE_LEN;
47 | }
48 |
49 | /* Magic Mersenne Twister constants */
50 | #define N 624
51 | #define M 397
52 | #define MATRIX_A 0x9908b0dfUL
53 | #define UPPER_MASK 0x80000000UL
54 | #define LOWER_MASK 0x7fffffffUL
55 |
56 | #ifdef WIN32
57 | // Disable "unary minus operator applied to unsigned type, result still unsigned" warning.
58 | #pragma warning(disable : 4146)
59 | #endif
60 |
61 | /* Slightly optimised reference implementation of the Mersenne Twister */
62 | inline unsigned long rk_random(rk_state *state)
63 | {
64 | unsigned long y;
65 |
66 | if (state->pos == RK_STATE_LEN)
67 | {
68 | int i;
69 |
70 | for (i=0;ikey[i] & UPPER_MASK) | (state->key[i+1] & LOWER_MASK);
73 | state->key[i] = state->key[i+M] ^ (y>>1) ^ (-(y & 1) & MATRIX_A);
74 | }
75 | for (;ikey[i] & UPPER_MASK) | (state->key[i+1] & LOWER_MASK);
78 | state->key[i] = state->key[i+(M-N)] ^ (y>>1) ^ (-(y & 1) & MATRIX_A);
79 | }
80 | y = (state->key[N-1] & UPPER_MASK) | (state->key[0] & LOWER_MASK);
81 | state->key[N-1] = state->key[M-1] ^ (y>>1) ^ (-(y & 1) & MATRIX_A);
82 |
83 | state->pos = 0;
84 | }
85 |
86 | y = state->key[state->pos++];
87 |
88 | /* Tempering */
89 | y ^= (y >> 11);
90 | y ^= (y << 7) & 0x9d2c5680UL;
91 | y ^= (y << 15) & 0xefc60000UL;
92 | y ^= (y >> 18);
93 |
94 | return y;
95 | }
96 |
97 | inline double rk_double(rk_state *state)
98 | {
99 | /* shifts : 67108864 = 0x4000000, 9007199254740992 = 0x20000000000000 */
100 | long a = rk_random(state) >> 5, b = rk_random(state) >> 6;
101 | return (a * 67108864.0 + b) / 9007199254740992.0;
102 | }
103 |
104 | // Initialise the random generator with the specified seed
105 | void rseed(unsigned long seed) {
106 | rk_seed(seed,&localState);
107 | //srand(seed);
108 | }
109 |
110 | unsigned long rndl() {
111 | return rk_random(&localState);
112 | }
113 |
114 | // Returns a uniform distributed double value in the interval ]0,1[
115 | double rnd() {
116 | return rk_double(&localState);
117 | }
118 |
--------------------------------------------------------------------------------
/Base58.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include "Base58.h"
19 |
20 | #include
21 | #include
22 | #include
23 |
24 | /** All alphanumeric characters except for "0", "I", "O", and "l" */
25 | static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
26 |
27 | static const int8_t b58digits_map[] = {
28 | -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
29 | -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
30 | -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
31 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
32 | -1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,
33 | 22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,
34 | -1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,
35 | 47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
36 | };
37 |
38 | bool DecodeBase58(const char* psz, std::vector &vch) {
39 |
40 | uint8_t digits[256];
41 |
42 | // Skip and count leading '1'
43 | int zeroes = 0;
44 | while (*psz == '1') {
45 | zeroes++;
46 | psz++;
47 | }
48 |
49 | int length = (int)strlen(psz);
50 |
51 | // Process the characters
52 | int digitslen = 1;
53 | digits[0] = 0;
54 | for (int i = 0; i < length; i++) {
55 |
56 | // Decode base58 character
57 | if (psz[i] & 0x80)
58 | return false;
59 |
60 | int8_t c = b58digits_map[psz[i]];
61 | if (c < 0)
62 | return false;
63 |
64 | uint32_t carry = (uint32_t)c;
65 | for (int j = 0; j < digitslen; j++) {
66 | carry += (uint32_t)(digits[j]) * 58;
67 | digits[j] = (uint8_t)(carry % 256);
68 | carry /= 256;
69 | }
70 | while (carry > 0) {
71 | digits[digitslen++] = (uint8_t)(carry % 256);
72 | carry /= 256;
73 | }
74 |
75 | }
76 |
77 | vch.clear();
78 | vch.reserve(zeroes + digitslen);
79 | // zeros
80 | for (int i = 0; i < zeroes; i++)
81 | vch.push_back(0);
82 |
83 | // reverse
84 | for (int i = 0; i < digitslen; i++)
85 | vch.push_back(digits[digitslen - 1 - i]);
86 |
87 | return true;
88 |
89 | }
90 |
91 | std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) {
92 |
93 | std::string ret;
94 | unsigned char digits[256];
95 |
96 | // Skip leading zeroes
97 | while (pbegin != pend && *pbegin == 0) {
98 | ret.push_back('1');
99 | pbegin++;
100 | }
101 | int length = (int)(pend - pbegin);
102 |
103 | int digitslen = 1;
104 | digits[0]=0;
105 | for(int i = 0; i < length; i++) {
106 | uint32_t carry = pbegin[i];
107 | for(int j = 0; j < digitslen; j++) {
108 | carry += (uint32_t)(digits[j]) << 8;
109 | digits[j] = (unsigned char)(carry % 58);
110 | carry /= 58;
111 | }
112 | while(carry > 0) {
113 | digits[digitslen++] = (unsigned char)(carry % 58);
114 | carry /= 58;
115 | }
116 | }
117 |
118 | // reverse
119 | for(int i = 0; i < digitslen; i++)
120 | ret.push_back(pszBase58[digits[digitslen - 1 - i]]);
121 |
122 | return ret;
123 |
124 | }
125 |
126 | std::string EncodeBase58(const std::vector& vch)
127 | {
128 | return EncodeBase58(vch.data(), vch.data() + vch.size());
129 | }
130 |
131 | bool DecodeBase58(const std::string& str, std::vector& vchRet)
132 | {
133 | return DecodeBase58(str.c_str(), vchRet);
134 | }
135 |
136 |
--------------------------------------------------------------------------------
/Bech32.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017 Pieter Wuille
2 | *
3 | * Permission is hereby granted, free of charge, to any person obtaining a copy
4 | * of this software and associated documentation files (the "Software"), to deal
5 | * in the Software without restriction, including without limitation the rights
6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | * copies of the Software, and to permit persons to whom the Software is
8 | * furnished to do so, subject to the following conditions:
9 | *
10 | * The above copyright notice and this permission notice shall be included in
11 | * all copies or substantial portions of the Software.
12 | *
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | */
21 |
22 | #ifndef _SEGWIT_ADDR_H_
23 | #define _SEGWIT_ADDR_H_ 1
24 |
25 | #include
26 |
27 | /** Encode a SegWit address
28 | *
29 | * Out: output: Pointer to a buffer of size 73 + strlen(hrp) that will be
30 | * updated to contain the null-terminated address.
31 | * In: hrp: Pointer to the null-terminated human readable part to use
32 | * (chain/network specific).
33 | * ver: Version of the witness program (between 0 and 16 inclusive).
34 | * prog: Data bytes for the witness program (between 2 and 40 bytes).
35 | * prog_len: Number of data bytes in prog.
36 | * Returns 1 if successful.
37 | */
38 | int segwit_addr_encode(
39 | char *output,
40 | const char *hrp,
41 | int ver,
42 | const uint8_t *prog,
43 | size_t prog_len
44 | );
45 |
46 | /** Decode a SegWit address
47 | *
48 | * Out: ver: Pointer to an int that will be updated to contain the witness
49 | * program version (between 0 and 16 inclusive).
50 | * prog: Pointer to a buffer of size 40 that will be updated to
51 | * contain the witness program bytes.
52 | * prog_len: Pointer to a size_t that will be updated to contain the length
53 | * of bytes in prog.
54 | * hrp: Pointer to the null-terminated human readable part that is
55 | * expected (chain/network specific).
56 | * addr: Pointer to the null-terminated address.
57 | * Returns 1 if successful.
58 | */
59 | int segwit_addr_decode(
60 | int* ver,
61 | uint8_t* prog,
62 | size_t* prog_len,
63 | const char* hrp,
64 | const char* addr
65 | );
66 |
67 | /** Encode a Bech32 string
68 | *
69 | * Out: output: Pointer to a buffer of size strlen(hrp) + data_len + 8 that
70 | * will be updated to contain the null-terminated Bech32 string.
71 | * In: hrp : Pointer to the null-terminated human readable part.
72 | * data : Pointer to an array of 5-bit values.
73 | * data_len: Length of the data array.
74 | * Returns 1 if successful.
75 | */
76 | int bech32_encode(
77 | char *output,
78 | const char *hrp,
79 | const uint8_t *data,
80 | size_t data_len
81 | );
82 |
83 | /** Decode a Bech32 string
84 | *
85 | * Out: hrp: Pointer to a buffer of size strlen(input) - 6. Will be
86 | * updated to contain the null-terminated human readable part.
87 | * data: Pointer to a buffer of size strlen(input) - 8 that will
88 | * hold the encoded 5-bit data values.
89 | * data_len: Pointer to a size_t that will be updated to be the number
90 | * of entries in data.
91 | * In: input: Pointer to a null-terminated Bech32 string.
92 | * Returns 1 if succesful.
93 | */
94 | int bech32_decode(
95 | char *hrp,
96 | uint8_t *data,
97 | size_t *data_len,
98 | const char *input
99 | );
100 |
101 | int bech32_decode_nocheck(uint8_t *data, size_t *data_len, const char *input);
102 |
103 | #endif
104 |
--------------------------------------------------------------------------------
/BTCCollider.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef BTCCOLLIDERH
19 | #define BTCCOLLIDERH
20 |
21 | #include
22 | #include
23 | #include "SECP256k1.h"
24 | #include "HashTable.h"
25 | #include "IntGroup.h"
26 | #include "GPU/GPUEngine.h"
27 | #ifdef WIN64
28 | #include
29 | #endif
30 |
31 | class BTCCollider;
32 |
33 | typedef struct {
34 |
35 | BTCCollider *obj;
36 | int threadId;
37 | bool isRunning;
38 | bool hasStarted;
39 | bool isWaiting;
40 | Int localSeed;
41 | hash160_t start;
42 | hash160_t end;
43 | uint64_t nbWalk;
44 | hash160_t *x; // Starting path item
45 | hash160_t *y; // Current path item
46 |
47 | #ifdef WITHGPU
48 | int gridSizeX;
49 | int gridSizeY;
50 | int gpuId;
51 | GPUEngine *gpu;
52 | #endif
53 |
54 | } TH_PARAM;
55 |
56 | #ifdef WIN64
57 | typedef HANDLE THREAD_HANDLE;
58 | #else
59 | typedef pthread_t THREAD_HANDLE;
60 | #endif
61 |
62 | #define CPU_AFFINE
63 | //#define STATISTICS
64 |
65 | #define HASHOK(h) (((h).i8[0] & 0x80)==0)
66 | #define PUBX(i,j) pub[(i)*(65536*2) + 2*(j)]
67 | #define PUBY(i,j) pub[(i)*(65536*2) + 2*(j)+1]
68 |
69 | class BTCCollider {
70 |
71 | public:
72 |
73 | BTCCollider(Secp256K1 *secp, bool useGpu, bool stop, std::string outputFile, std::string workFile, std::string iWorkFile, uint32_t savePeriod, uint32_t n,int dp,bool extraPoint);
74 | void Search(int nbThread,std::vector gpuId,std::vector gridSize);
75 | void Check(std::vector gpuId, std::vector gridSize);
76 | void FindCollisionCPU(TH_PARAM *p);
77 | void FindCollisionGPU(TH_PARAM *p);
78 | void UndistinguishCPU(TH_PARAM *p);
79 | void InitKey(TH_PARAM *p);
80 |
81 | private:
82 |
83 | Int GetPrivKey(hash160_t x);
84 | hash160_t F(hash160_t x);
85 | bool IsDP(hash160_t x);
86 | bool IsEqual(hash160_t x1, hash160_t x2);
87 | void SetDP(int size);
88 | void FGroup(IntGroup *grp, Point *pts, Int *di, hash160_t *x);
89 | void AddGroup(IntGroup *grp, hash160_t *x, Point *p1, Int *dx, int i, uint16_t colMask);
90 | void Lock();
91 | void Unlock();
92 | void SaveWork(uint64_t totalCount,double totalTime,TH_PARAM *threads,int nbThread);
93 | void LoadWork(std::string fileName);
94 | std::string GetTimeStr(double s);
95 | Point Add(Point &p1, int n, uint16_t h);
96 |
97 | #ifdef WIN64
98 | THREAD_HANDLE LaunchThread(LPTHREAD_START_ROUTINE func,TH_PARAM *p);
99 | #else
100 | THREAD_HANDLE LaunchThread(void *(*func) (void *), TH_PARAM *p);
101 | #endif
102 | void JoinThreads(THREAD_HANDLE *handles, int nbThread);
103 | void FreeHandles(THREAD_HANDLE *handles, int nbThread);
104 |
105 | std::string GetHex(hash160_t x);
106 | void Rand(Int *seed,Int *i);
107 | void Rand(Int *seed,hash160_t *i);
108 | uint64_t getGPUCount();
109 | uint64_t getCPUCount();
110 | bool isAlive(TH_PARAM *p);
111 | bool hasStarted(TH_PARAM *p);
112 | bool isWaiting(TH_PARAM *p);
113 | void FetchWalks(hash160_t *x,hash160_t *y, uint64_t nbWalk);
114 |
115 | std::string initialSeed;
116 | Int seed;
117 | Secp256K1 *secp;
118 | HashTable hashTable;
119 | uint64_t offsetCount;
120 | double offsetTime;
121 | uint64_t counters[256];
122 | uint64_t dMask;
123 | uint32_t dpSize;
124 | int initDPSize;
125 | uint32_t colSize;
126 | int nbFull;
127 | uint16_t colMask;
128 | int nbCPUThread;
129 | int nbGPUThread;
130 | std::string outputFile;
131 | std::string workFile;
132 | int saveWorkPeriod;
133 | bool useSSE;
134 | bool useGpu;
135 | bool endOfSearch;
136 | bool saveRequest;
137 | bool extraPoints;
138 | double startTime;
139 | int CPU_GRP_SIZE;
140 | Int lambda1;
141 | Int lambda2;
142 | Int beta1;
143 | Int beta2;
144 |
145 | uint64_t nbLoadedWalk;
146 | uint64_t fetchedWalk;
147 | hash160_t *loadedX;
148 | hash160_t *loadedY;
149 |
150 | // Hash160 to key mapping
151 | Point Gp[10]; // Power of G
152 | Int Kp[10]; // Power
153 | Int *pub;
154 | Int priv[10][65536];
155 |
156 | #ifdef WIN64
157 | HANDLE ghMutex;
158 | #else
159 | pthread_mutex_t ghMutex;
160 | #endif
161 |
162 | };
163 |
164 | #endif // BTCCOLLIDERH
165 |
--------------------------------------------------------------------------------
/Timer.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include "Timer.h"
19 |
20 | static const char *prefix[] = { "","Kilo","Mega","Giga","Tera","Peta","Hexa" };
21 |
22 | #ifdef WIN64
23 |
24 | LARGE_INTEGER Timer::perfTickStart;
25 | double Timer::perfTicksPerSec;
26 | LARGE_INTEGER Timer::qwTicksPerSec;
27 | #include
28 |
29 | #else
30 |
31 | #include
32 | #include
33 | #include
34 | time_t Timer::tickStart;
35 |
36 | #endif
37 |
38 | void Timer::Init() {
39 |
40 | #ifdef WIN64
41 | QueryPerformanceFrequency(&qwTicksPerSec);
42 | QueryPerformanceCounter(&perfTickStart);
43 | perfTicksPerSec = (double)qwTicksPerSec.QuadPart;
44 | #else
45 | tickStart=time(NULL);
46 | #endif
47 |
48 | }
49 |
50 | double Timer::get_tick() {
51 |
52 | #ifdef WIN64
53 | LARGE_INTEGER t, dt;
54 | QueryPerformanceCounter(&t);
55 | dt.QuadPart = t.QuadPart - perfTickStart.QuadPart;
56 | return (double)(dt.QuadPart) / perfTicksPerSec;
57 | #else
58 | struct timeval tv;
59 | gettimeofday(&tv, NULL);
60 | return (double)(tv.tv_sec - tickStart) + (double)tv.tv_usec / 1e6;
61 | #endif
62 |
63 | }
64 |
65 | std::string Timer::getSeed(int size) {
66 |
67 | std::string ret;
68 | char tmp[3];
69 | unsigned char *buff = (unsigned char *)malloc(size);
70 |
71 | #ifdef WIN64
72 |
73 | HCRYPTPROV hCryptProv = NULL;
74 | LPCSTR UserName = "KeyContainer";
75 |
76 | if (!CryptAcquireContext(
77 | &hCryptProv, // handle to the CSP
78 | UserName, // container name
79 | NULL, // use the default provider
80 | PROV_RSA_FULL, // provider type
81 | 0)) // flag values
82 | {
83 | //-------------------------------------------------------------------
84 | // An error occurred in acquiring the context. This could mean
85 | // that the key container requested does not exist. In this case,
86 | // the function can be called again to attempt to create a new key
87 | // container. Error codes are defined in Winerror.h.
88 | if (GetLastError() == NTE_BAD_KEYSET) {
89 | if (!CryptAcquireContext(
90 | &hCryptProv,
91 | UserName,
92 | NULL,
93 | PROV_RSA_FULL,
94 | CRYPT_NEWKEYSET)) {
95 | printf("CryptAcquireContext(): Could not create a new key container.\n");
96 | exit(1);
97 | }
98 | } else {
99 | printf("CryptAcquireContext(): A cryptographic service handle could not be acquired.\n");
100 | exit(1);
101 | }
102 | }
103 |
104 | if (!CryptGenRandom(hCryptProv,size,buff)) {
105 | printf("CryptGenRandom(): Error during random sequence acquisition.\n");
106 | exit(1);
107 | }
108 |
109 | CryptReleaseContext(hCryptProv, 0);
110 |
111 | #else
112 |
113 | FILE *f = fopen("/dev/urandom","rb");
114 | if(f==NULL) {
115 | printf("Failed to open /dev/urandom %s\n", strerror( errno ));
116 | exit(1);
117 | }
118 | if( fread(buff,1,size,f)!=size ) {
119 | printf("Failed to read from /dev/urandom %s\n", strerror( errno ));
120 | exit(1);
121 | }
122 | fclose(f);
123 |
124 | #endif
125 |
126 | for (int i = 0; i < size; i++) {
127 | sprintf(tmp,"%02X",buff[i]);
128 | ret.append(tmp);
129 | }
130 |
131 | free(buff);
132 | return ret;
133 |
134 | }
135 |
136 |
137 | std::string Timer::getResult(char *unit, int nbTry, double t0, double t1) {
138 |
139 | char tmp[256];
140 | int pIdx = 0;
141 | double nbCallPerSec = (double)nbTry / (t1 - t0);
142 | while (nbCallPerSec > 1000.0 && pIdx < 5) {
143 | pIdx++;
144 | nbCallPerSec = nbCallPerSec / 1000.0;
145 | }
146 | sprintf(tmp, "%.3f %s%s/sec", nbCallPerSec, prefix[pIdx], unit);
147 | return std::string(tmp);
148 |
149 | }
150 |
151 | void Timer::printResult(char *unit, int nbTry, double t0, double t1) {
152 |
153 | printf("%s\n", getResult(unit, nbTry, t0, t1).c_str());
154 |
155 | }
156 |
157 | int Timer::getCoreNumber() {
158 |
159 | #ifdef WIN64
160 | SYSTEM_INFO sysinfo;
161 | GetSystemInfo(&sysinfo);
162 | return sysinfo.dwNumberOfProcessors;
163 | #else
164 | return (size_t)sysconf(_SC_NPROCESSORS_ONLN);
165 | #endif
166 |
167 | }
168 |
169 | void Timer::SleepMillis(uint32_t millis) {
170 |
171 | #ifdef WIN64
172 | Sleep(millis);
173 | #else
174 | usleep(millis*1000);
175 | #endif
176 |
177 | }
178 |
--------------------------------------------------------------------------------
/GPU/GPUCompute.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | // CUDA Kernel main function
19 |
20 | #ifdef GPU_AFFINE
21 |
22 | __device__ void AddGroup(uint64_t *keys, uint64_t px[GPU_GRP_SIZE][4], uint64_t py[GPU_GRP_SIZE][4], uint16_t x[GPU_GRP_SIZE][12], int i, uint16_t colMask) {
23 |
24 | uint64_t dx[GPU_GRP_SIZE][4];
25 | uint64_t dy[4];
26 | uint64_t rx[4];
27 | uint64_t _s[4];
28 | uint64_t _p[4];
29 | uint64_t _kx[4];
30 | uint64_t _ky[4];
31 | uint16_t kIdx;
32 |
33 | for (int g = 0; g < GPU_GRP_SIZE; g++) {
34 | kIdx = x[g][i] & colMask;
35 | LoadKeyX(dx[g], i, kIdx);
36 | ModSub256(dx[g],px[g]);
37 | }
38 | _ModInvGrouped(dx);
39 |
40 | for (int g = 0; g < GPU_GRP_SIZE; g++) {
41 |
42 | kIdx = x[g][i] & colMask;
43 | LoadKeyX(_kx, i, kIdx);
44 | LoadKeyY(_ky, i, kIdx);
45 |
46 | ModSub256(dy,_ky,py[g]);
47 | _ModMult(_s,dy,dx[g]);
48 | _ModSqr(_p,_s);
49 |
50 | ModSub256(rx,_p,px[g]);
51 | ModSub256(rx,_kx);
52 | ModSub256(py[g],_kx,rx);
53 | _ModMult(py[g], _s);
54 | ModSub256(py[g],_ky);
55 | Load256(px[g],rx);
56 |
57 | }
58 |
59 | }
60 |
61 | #else
62 |
63 | __device__ void Add(uint64_t p1x[4], uint64_t p1y[4], uint64_t p1z[4],
64 | uint64_t p2x[4], uint64_t p2y[4]) {
65 |
66 | uint64_t u[4];
67 | uint64_t v[4];
68 | uint64_t u1[4];
69 | uint64_t v1[4];
70 | uint64_t vs2[4];
71 | uint64_t vs3[4];
72 | uint64_t us2[4];
73 | uint64_t a[4];
74 | uint64_t us2w[4];
75 | uint64_t vs2v2[4];
76 | uint64_t vs3u2[4];
77 | uint64_t _2vs2v2[4];
78 | uint64_t rx[4];
79 | uint64_t ry[4];
80 | uint64_t rz[4];
81 |
82 | _ModMult(u1, p2y, p1z);
83 | _ModMult(v1, p2x, p1z);
84 | ModSub256(u, u1, p1y);
85 | ModSub256(v, v1, p1x);
86 | _ModSqr(us2, u);
87 | _ModSqr(vs2, v);
88 | _ModMult(vs3, vs2, v);
89 | _ModMult(us2w, us2, p1z);
90 | _ModMult(vs2v2, vs2, p1x);
91 | ModAdd256(_2vs2v2, vs2v2, vs2v2);
92 | ModSub256(a, us2w, vs3);
93 | ModSub256(a, _2vs2v2);
94 | _ModMult(rx, v, a);
95 | _ModMult(vs3u2, vs3, p1y);
96 | ModSub256(ry, vs2v2, a);
97 | _ModMult(ry, u);
98 | ModSub256(ry, vs3u2);
99 | _ModMult(rz, vs3, p1z);
100 |
101 | Load256(p1x, rx);
102 | Load256(p1y, ry);
103 | Load256(p1z, rz);
104 |
105 | }
106 |
107 | #endif
108 |
109 | // -----------------------------------------------------------------------------------------
110 |
111 | #define HASHOK(h) ((h[0] & 0x0080)==0)
112 |
113 | __device__ void ComputeHash(uint64_t *keys, uint64_t *hashes,uint32_t maxFound, uint32_t *out,uint64_t dpMask,uint16_t colMask, uint16_t nbFull, bool extraPoints) {
114 |
115 | // Perform x = F(x) for a group
116 | uint64_t px[GPU_GRP_SIZE][4];
117 | uint64_t py[GPU_GRP_SIZE][4];
118 | uint16_t x[GPU_GRP_SIZE][12];
119 |
120 | __syncthreads();
121 | LoadHash(x, hashes);
122 |
123 | for (int run = 0; run < NB_RUN; run++) {
124 |
125 | __syncthreads();
126 |
127 | #ifdef GPU_AFFINE
128 |
129 | for (int g = 0; g < GPU_GRP_SIZE; g++) {
130 | LoadKeyX(px[g], 0, x[g][0]);
131 | LoadKeyY(py[g], 0, x[g][0]);
132 | }
133 |
134 | int i;
135 | for (i = 1; i < nbFull; i++)
136 | AddGroup(keys, px, py, x, i, 0xFFFF);
137 |
138 | if (colMask)
139 | AddGroup(keys, px, py, x, i, colMask);
140 |
141 | #else
142 |
143 | uint64_t pz[GPU_GRP_SIZE][4];
144 | uint64_t _kx[4];
145 | uint64_t _ky[4];
146 |
147 | for (int g = 0; g < GPU_GRP_SIZE; g++) {
148 |
149 | LoadKeyX(px[g], 0, x[g][0]);
150 | LoadKeyY(py[g], 0, x[g][0]);
151 | Load256(pz[g],_1);
152 |
153 | int i;
154 | for (i = 1; i < nbFull; i++) {
155 | LoadKeyX(_kx, i, x[g][i]);
156 | LoadKeyY(_ky, i, x[g][i]);
157 | Add(px[g], py[g], pz[g], _kx, _ky);
158 | }
159 |
160 | if (colMask) {
161 | LoadKeyX(_kx, i, x[g][i] & colMask);
162 | LoadKeyY(_ky, i, x[g][i] & colMask);
163 | Add(px[g], py[g], pz[g], _kx, _ky);
164 | }
165 |
166 | }
167 |
168 | _ModInvGrouped(pz);
169 | for (int g = 0; g < GPU_GRP_SIZE; g++) {
170 | _ModMult(px[g], pz[g]);
171 | _ModMult(py[g], pz[g]);
172 | }
173 |
174 | #endif
175 |
176 | for (int g = 0; g < GPU_GRP_SIZE; g++) {
177 |
178 | uint8_t isOdd = (uint8_t)(py[g][0] & 0x1);
179 |
180 | __syncthreads();
181 | _GetHash160Comp(px[g], isOdd, (uint8_t *)(x[g]));
182 |
183 | if (extraPoints) {
184 |
185 | uint64_t xe1[4];
186 | uint64_t xe2[4];
187 |
188 | if (HASHOK(x[g])) goto checkdp;
189 |
190 | _GetHash160Comp(px[g], !isOdd, (uint8_t *)(x[g]));
191 | if (HASHOK(x[g])) goto checkdp;
192 |
193 | Load256(xe1, px[g]);
194 | _ModMult(xe1, _beta);
195 | _GetHash160Comp(xe1, isOdd, (uint8_t *)(x[g]));
196 | if (HASHOK(x[g])) goto checkdp;
197 |
198 | _GetHash160Comp(xe1, !isOdd, (uint8_t *)(x[g]));
199 | if (HASHOK(x[g])) goto checkdp;
200 |
201 | Load256(xe2, px[g]);
202 | _ModMult(xe2, _beta2);
203 | _GetHash160Comp(xe2, isOdd, (uint8_t *)(x[g]));
204 | if (HASHOK(x[g])) goto checkdp;
205 |
206 | _GetHash160Comp(xe2, !isOdd, (uint8_t *)(x[g]));
207 |
208 | }
209 |
210 | checkdp:
211 |
212 | if ((*((uint64_t *)x[g]) & dpMask) == 0) {
213 |
214 | // Distinguished point
215 | uint16_t s[12];
216 | LoadStartHash(s, hashes, g);
217 | uint32_t pos = atomicAdd(out, 1);
218 | if (pos < maxFound)
219 | OutputHash(s,x[g]);
220 | StoreStartHash(x[g], hashes, g);
221 |
222 | }
223 |
224 | }
225 |
226 | }
227 |
228 | __syncthreads();
229 | StoreHash(x,hashes);
230 |
231 | }
232 |
233 | __device__ void ComputeHashP2SH(uint64_t *keys, uint64_t *hashes, uint32_t maxFound, uint32_t *out, uint64_t dpMask, uint16_t colMask, uint16_t nbFull, bool extraPoints) {
234 |
235 | }
236 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BTCCollider
2 |
3 | BTCCollider generates BTC p2pkh address pair (and their corresponding private keys) that
4 | share the same prefix. It looks for a pair of distinct HASH160 starting with the same bits
5 | (a partial collision) using the so called "distinguished point" method which allows
6 | to efficiently take benefit of the birthday paradox using parallel calculations.
7 | BTCCollider supports multi GPU using CUDA and is based on VanitySearch enigne.
8 |
9 | On my hardware ( GTX 1050 Ti without CPU ):
10 |
11 | | Collision | Average time | Average time (using -e) |
12 | |----------|:-------------:|:-------------:|
13 | | 64 bits | 2min51 | 2min51 |
14 | | 80 bits | 15h30 | 14h30 |
15 | | 96 bits | 201d | 180d |
16 | | 112 bits | 165y | 145y |
17 | | 128 bits | 48744y | 42000y |
18 | | 144 bits | 1.4e7y | 1.18e7y |
19 | | 160 bits | 4e9y | 3.3e9y |
20 |
21 | # Usage
22 |
23 | ```
24 | BTCCollider [-check] [-v] [-gpu]
25 | [-gpuId gpuId1[,gpuId2,...]] [-g g1x,g1y[,g2x,g2y,...]]
26 | [-o outputfile] [-s collisionSize] [-t nbThread] [-d dpBit]
27 | [-w workfile] [-i inputWorkFile] [-wi workInterval]
28 | [-e] [-check]
29 |
30 | -v: Print version
31 | -gpu: Enable gpu calculation
32 | -o outputfile: Output results to the specified file
33 | -gpu gpuId1,gpuId2,...: List of GPU(s) to use, default is 0
34 | -g g1x,g1y,g2x,g2y,...: Specify GPU(s) kernel gridsize, default is 2*(MP),2*(Core/MP)
35 | -s: Specify size of the collision in bit (minimum 16,default is 40)
36 | -d: Specify number of leading zeros for the DP method (default is auto)
37 | -e: Enable extra points (symetry and endomorphisms), reduce needed step by sqrt(2)
38 | -t threadNumber: Specify number of CPU thread, default is number of core
39 | -w workfile: Specify file to save work into
40 | -i workfile: Specify file to load work from
41 | -wi workInterval: Periodic interval (in seconds) for saving work
42 | -l: List cuda enabled devices
43 | -check: Check CPU and GPU kernel vs CPU
44 | ```
45 |
46 | Example (Windows, Intel Core i7-4770 3.4GHz 8 multithreaded cores, GeForce GTX 1050 Ti):
47 | ```
48 | C:\C++\BTCCollider\x64\Release>BTCCollider.exe -t 6 -gpu -s 80
49 | BTCCollider v1.0
50 | Collision: 80 bits
51 | Seed: 305ABC344F924BD8B268905F99ADBD403D9A45BB220C5948731740DDE0E3A41A
52 | Initializing:Done
53 | Start Tue Jan 21 16:02:07 2020
54 | Number of CPU thread: 6
55 | Number of random walk: 2^18.59 (Max DP=20)
56 | DP size: 20 [0xFFFFF00000000000]
57 | GPU: GPU #0 GeForce GTX 1050 Ti (6x128 cores) Grid(12x256) (60.5 MB used)
58 | [27.9 Mips][GPU 24.8 Mips][Cnt 2^39.44][T 07:24:33][Tavg 13:42:43][hSize 41.3MB]
59 | Undistinguishing
60 | DP size: 10 [0xFFC0000000000000]
61 | DP size: 5 [0xF800000000000000]
62 | DP size: 2 [0xC000000000000000]
63 | DP size: 1 [0x8000000000000000]
64 | DP size: 0 [0x0000000000000000]
65 | [Collision Found: 82 bits][Cnt 2^39.44][T 07:24:40]
66 | H1=FD53BD2E39ECB0F2D6AE441DE23ED586CA57C7B3
67 | H2=FD53BD2E39ECB0F2D6AE72F3F4D6A824A065915B
68 | Priv (WIF): p2pkh:KzNuYQf9X5sbXtr5mgEeBMx7LK2K6QRK73pMWqMhVAGpoWLEowLA
69 | Priv (WIF): p2pkh:KzNuYQf9X5sbXtr5mgEeBMx7LK2K6QRFqBMftDEYHFzssVsN2Shn
70 | Add1: 1Q6UGpZ6oKmCSZF1m7W1r3pp7syt1JZwMe
71 | Add2: 1Q6UGpZ6oKmCSZFJynpzcRPJWJ2ur5Ujb5
72 | ```
73 |
74 | # Compilation
75 |
76 | ## Windows
77 |
78 | Install CUDA SDK and open BTCCollider.sln in Visual C++ 2017.\
79 | You may need to reset your *Windows SDK version* in project properties.\
80 | In Build->Configuration Manager, select the *Release* configuration.\
81 | Build and enjoy.\
82 | \
83 | Note: The current release has been compiled with CUDA SDK 10.0, if you have a different release of the CUDA SDK, you may need to update CUDA SDK paths in BTCCollider.vcxproj using a text editor. The current nvcc option are set up to architecture starting at 3.0 capability, for older hardware, add the desired compute capabilities to the list in GPUEngine.cu properties, CUDA C/C++, Device, Code Generation.
84 |
85 | ## Linux
86 |
87 | Install CUDA SDK.\
88 | Depending on the CUDA SDK version and on your Linux distribution you may need to install an older g++ (just for the CUDA SDK).\
89 | Edit the makefile and set up the good CUDA SDK path and appropriate compiler for nvcc.
90 |
91 | ```
92 | CUDA = /usr/local/cuda-8.0
93 | CXXCUDA = /usr/bin/g++-4.8
94 | ```
95 |
96 | You can enter a list of architecture (refer to nvcc documentation) if you have several GPU with different architecture. Compute capability 2.0 (Fermi) is deprecated for recent CUDA SDK.
97 | BTCCollider need to be compiled and linked with a recent gcc (>=7). The current release has been compiled with gcc 7.3.0.\
98 | Go to the BTCCollider directory. ccap is the desired compute capability.
99 |
100 | ```
101 | $ g++ -v
102 | gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
103 | $ make all (for build without CUDA support)
104 | or
105 | $ make gpu=1 ccap=20 all
106 | ```
107 | Runnig BTCCollider (Intel(R) Xeon(R) CPU, 8 cores, @ 2.93GHz, Quadro 600 (x2))
108 | ```
109 | $export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64
110 | $./BTCCollider -gpu -gpuId 0,1 -s 56
111 | BTCCollider v1.0
112 | Collision: 56 bits
113 | Seed: B820941A47BF7E47B67C1F0DEBEB5B422A8AF55497811A74D08A1CD69E6E17A4
114 | Initializing:Done
115 | Start Wed Jan 22 13:26:34 2020
116 | Number of CPU thread: 6
117 | Number of random walk: 2^14.63 (Max DP=12)
118 | DP size: 12 [0xfff0000000000000]
119 | GPU: GPU #0 Quadro 600 (2x48 cores) Grid(4x96) (43.1 MB used)
120 | GPU: GPU #1 Quadro 600 (2x48 cores) Grid(4x96) (43.1 MB used)
121 | [5.8 Mips][GPU 2.7 Mips][Cnt 2^28.61][T 01:10][Tavg 57 s][hSize 10.8MB]
122 | Undistinguishing
123 | DP size: 6 [0xfc00000000000000]
124 | DP size: 3 [0xe000000000000000]
125 | DP size: 1 [0x8000000000000000]
126 | DP size: 0 [0x0]
127 | [Collision Found: 57 bits][Cnt 2^28.62][T 01:10]
128 | H1=6E1A7D4635F2FC2BCD77CD3876D82CBC14102694
129 | H2=6E1A7D4635F2FC60D084BF846A3F9A8EC5327648
130 | Priv (WIF): p2pkh:KwYUtUYFZYiTYC1KvF5enJGmUitpL3jEAzHFmyqGFgLR9GRyVKmp
131 | Priv (WIF): p2pkh:KwYUtUYFZYiTYC1KvF5enJGmUitpL3jEAzHFUwbG1iniUEMCA8uD
132 | Add1: 1B3B4cbvZogP3Z7uNdNV4RUVDAND2qJcFJ
133 | Add2: 1B3B4cbvZogswNAiYoBYNqSUEqmq7pEd1V
134 | ```
135 |
136 | # Notes on DP method tradeoff
137 |
138 | This picture illustrates the overhead you get according to the number of random walks running in parallel and the number of distinguished bits. All experimental points (red points) are averaged over 1000 collisions.
139 | The green curve is the natural average of the birthday paradox without using DP method (DP0).
140 | The total number of iteration is the total number of evaluation of the F function of all walks.
141 | Significant overhead of memory and time (>10%) appears when dp > n/2 - log2(nbWalk) - 3, for n bits collision.
142 | BTCCollider compute DP using the following code, DP can be set manually using -d option:
143 | ```
144 | int optimalDP = (int)((double)colSize / 2.0 - log2((double)totalRW) - 2);
145 | ```
146 |
147 | 
148 |
149 | The following plots in blue show the asymtotic functions: sqrt(PI/2 * 2^40) + m*2^dp where m is the number of walk.
150 |
151 | 
152 |
153 | # License
154 |
155 | BTCCollider is licensed under GPLv3.
156 |
157 |
--------------------------------------------------------------------------------
/Bech32.cpp:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017 Pieter Wuille
2 | *
3 | * Permission is hereby granted, free of charge, to any person obtaining a copy
4 | * of this software and associated documentation files (the "Software"), to deal
5 | * in the Software without restriction, including without limitation the rights
6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | * copies of the Software, and to permit persons to whom the Software is
8 | * furnished to do so, subject to the following conditions:
9 | *
10 | * The above copyright notice and this permission notice shall be included in
11 | * all copies or substantial portions of the Software.
12 | *
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | */
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include "Bech32.h"
27 |
28 | uint32_t bech32_polymod_step(uint32_t pre) {
29 | uint8_t b = pre >> 25;
30 | return ((pre & 0x1FFFFFF) << 5) ^
31 | (-((b >> 0) & 1) & 0x3b6a57b2UL) ^
32 | (-((b >> 1) & 1) & 0x26508e6dUL) ^
33 | (-((b >> 2) & 1) & 0x1ea119faUL) ^
34 | (-((b >> 3) & 1) & 0x3d4233ddUL) ^
35 | (-((b >> 4) & 1) & 0x2a1462b3UL);
36 | }
37 |
38 | static const char* charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
39 |
40 | static const int8_t charset_rev[128] = {
41 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
42 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
43 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
44 | 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
45 | -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
46 | 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
47 | -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
48 | 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
49 | };
50 |
51 | int bech32_encode(char *output, const char *hrp, const uint8_t *data, size_t data_len) {
52 | uint32_t chk = 1;
53 | size_t i = 0;
54 | while (hrp[i] != 0) {
55 | int ch = hrp[i];
56 | if (ch < 33 || ch > 126) {
57 | return 0;
58 | }
59 |
60 | if (ch >= 'A' && ch <= 'Z') return 0;
61 | chk = bech32_polymod_step(chk) ^ (ch >> 5);
62 | ++i;
63 | }
64 | if (i + 7 + data_len > 90) return 0;
65 | chk = bech32_polymod_step(chk);
66 | while (*hrp != 0) {
67 | chk = bech32_polymod_step(chk) ^ (*hrp & 0x1f);
68 | *(output++) = *(hrp++);
69 | }
70 | *(output++) = '1';
71 | for (i = 0; i < data_len; ++i) {
72 | if (*data >> 5) return 0;
73 | chk = bech32_polymod_step(chk) ^ (*data);
74 | *(output++) = charset[*(data++)];
75 | }
76 | for (i = 0; i < 6; ++i) {
77 | chk = bech32_polymod_step(chk);
78 | }
79 | chk ^= 1;
80 | for (i = 0; i < 6; ++i) {
81 | *(output++) = charset[(chk >> ((5 - i) * 5)) & 0x1f];
82 | }
83 | *output = 0;
84 | return 1;
85 | }
86 |
87 | int bech32_decode_nocheck(uint8_t *data, size_t *data_len, const char *input) {
88 |
89 | uint8_t acc=0;
90 | uint8_t acc_len=8;
91 | size_t out_len=0;
92 |
93 | size_t input_len = strlen(input);
94 | for (int i = 0; i < input_len; i++) {
95 |
96 | if(input[i]&0x80)
97 | return false;
98 |
99 | int8_t c = charset_rev[tolower(input[i])];
100 | if(c<0)
101 | return false;
102 |
103 | if (acc_len >= 5) {
104 | acc |= c << (acc_len - 5);
105 | acc_len -= 5;
106 | } else {
107 | int shift = 5 - acc_len;
108 | data[out_len++] = acc | (c >> shift);
109 | acc_len = 8-shift;
110 | acc = c << acc_len;
111 | }
112 |
113 | }
114 |
115 | data[out_len++] = acc;
116 | *data_len = out_len;
117 |
118 | return true;
119 |
120 | }
121 |
122 | int bech32_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input) {
123 | uint32_t chk = 1;
124 | size_t i;
125 | size_t input_len = strlen(input);
126 | size_t hrp_len;
127 | int have_lower = 0, have_upper = 0;
128 | if (input_len < 8 || input_len > 90) {
129 | return 0;
130 | }
131 | *data_len = 0;
132 | while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') {
133 | ++(*data_len);
134 | }
135 | hrp_len = input_len - (1 + *data_len);
136 | if (1 + *data_len >= input_len || *data_len < 6) {
137 | return 0;
138 | }
139 | *(data_len) -= 6;
140 | for (i = 0; i < hrp_len; ++i) {
141 | int ch = input[i];
142 | if (ch < 33 || ch > 126) {
143 | return 0;
144 | }
145 | if (ch >= 'a' && ch <= 'z') {
146 | have_lower = 1;
147 | } else if (ch >= 'A' && ch <= 'Z') {
148 | have_upper = 1;
149 | ch = (ch - 'A') + 'a';
150 | }
151 | hrp[i] = ch;
152 | chk = bech32_polymod_step(chk) ^ (ch >> 5);
153 | }
154 | hrp[i] = 0;
155 | chk = bech32_polymod_step(chk);
156 | for (i = 0; i < hrp_len; ++i) {
157 | chk = bech32_polymod_step(chk) ^ (input[i] & 0x1f);
158 | }
159 | ++i;
160 | while (i < input_len) {
161 | int v = (input[i] & 0x80) ? -1 : charset_rev[(int)input[i]];
162 | if (input[i] >= 'a' && input[i] <= 'z') have_lower = 1;
163 | if (input[i] >= 'A' && input[i] <= 'Z') have_upper = 1;
164 | if (v == -1) {
165 | return 0;
166 | }
167 | chk = bech32_polymod_step(chk) ^ v;
168 | if (i + 6 < input_len) {
169 | data[i - (1 + hrp_len)] = v;
170 | }
171 | ++i;
172 | }
173 | if (have_lower && have_upper) {
174 | return 0;
175 | }
176 | return chk == 1;
177 | }
178 |
179 | static int convert_bits(uint8_t* out, size_t* outlen, int outbits, const uint8_t* in, size_t inlen, int inbits, int pad) {
180 | uint32_t val = 0;
181 | int bits = 0;
182 | uint32_t maxv = (((uint32_t)1) << outbits) - 1;
183 | while (inlen--) {
184 | val = (val << inbits) | *(in++);
185 | bits += inbits;
186 | while (bits >= outbits) {
187 | bits -= outbits;
188 | out[(*outlen)++] = (val >> bits) & maxv;
189 | }
190 | }
191 | if (pad) {
192 | if (bits) {
193 | out[(*outlen)++] = (val << (outbits - bits)) & maxv;
194 | }
195 | } else if (((val << (outbits - bits)) & maxv) || bits >= inbits) {
196 | return 0;
197 | }
198 | return 1;
199 | }
200 |
201 | int segwit_addr_encode(char *output, const char *hrp, int witver, const uint8_t *witprog, size_t witprog_len) {
202 | uint8_t data[65];
203 | size_t datalen = 0;
204 | if (witver > 16) return 0;
205 | if (witver == 0 && witprog_len != 20 && witprog_len != 32) return 0;
206 | if (witprog_len < 2 || witprog_len > 40) return 0;
207 | data[0] = witver;
208 | convert_bits(data + 1, &datalen, 5, witprog, witprog_len, 8, 1);
209 | ++datalen;
210 | return bech32_encode(output, hrp, data, datalen);
211 | }
212 |
213 | int segwit_addr_decode(int* witver, uint8_t* witdata, size_t* witdata_len, const char* hrp, const char* addr) {
214 | uint8_t data[84];
215 | char hrp_actual[84];
216 | size_t data_len;
217 | if (!bech32_decode(hrp_actual, data, &data_len, addr)) return 0;
218 | if (data_len == 0 || data_len > 65) return 0;
219 | if (strncmp(hrp, hrp_actual, 84) != 0) return 0;
220 | if (data[0] > 16) return 0;
221 | *witdata_len = 0;
222 | if (!convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) return 0;
223 | if (*witdata_len < 2 || *witdata_len > 40) return 0;
224 | if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) return 0;
225 | *witver = data[0];
226 | return 1;
227 | }
228 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include "Timer.h"
19 | #include "BTCCollider.h"
20 | #include "SECP256k1.h"
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include "hash/sha512.h"
26 | #include "hash/sha256.h"
27 |
28 | #define RELEASE "1.1"
29 |
30 | using namespace std;
31 |
32 | // ------------------------------------------------------------------------------------------
33 |
34 | void printUsage() {
35 |
36 | printf("BTCCollider [-check] [-v] [-gpu]\n");
37 | printf(" [-gpuId gpuId1[,gpuId2,...]] [-g g1x,g1y[,g2x,g2y,...]]\n");
38 | printf(" [-o outputfile] [-s collisionSize] [-t nbThread] [-d dpBit]\n");
39 | printf(" [-w workfile] [-i inputWorkFile] [-wi workInterval]\n");
40 | printf(" [-e] [-check]\n\n");
41 | printf(" -v: Print version\n");
42 | printf(" -gpu: Enable gpu calculation\n");
43 | printf(" -o outputfile: Output results to the specified file\n");
44 | printf(" -gpu gpuId1,gpuId2,...: List of GPU(s) to use, default is 0\n");
45 | printf(" -g g1x,g1y,g2x,g2y,...: Specify GPU(s) kernel gridsize, default is 2*(MP),2*(Core/MP)\n");
46 | printf(" -s: Specify size of the collision in bit (minimum 16,default is 40)\n");
47 | printf(" -d: Specify number of leading zeros for the DP method (default is auto)\n");
48 | printf(" -e: Enable extra points (symetry and endomorphisms), reduce needed step by sqrt(2)\n");
49 | printf(" -t threadNumber: Specify number of CPU thread, default is number of core\n");
50 | printf(" -w workfile: Specify file to save work into\n");
51 | printf(" -i workfile: Specify file to load work from\n");
52 | printf(" -wi workInterval: Periodic interval (in seconds) for saving work\n");
53 | printf(" -l: List cuda enabled devices\n");
54 | printf(" -check: Check CPU and GPU kernel vs CPU\n");
55 | exit(0);
56 |
57 | }
58 |
59 | // ------------------------------------------------------------------------------------------
60 |
61 | int getInt(string name,char *v) {
62 |
63 | int r;
64 |
65 | try {
66 |
67 | r = std::stoi(string(v));
68 |
69 | } catch(std::invalid_argument&) {
70 |
71 | printf("Invalid %s argument, number expected\n",name.c_str());
72 | exit(-1);
73 |
74 | }
75 |
76 | return r;
77 |
78 | }
79 |
80 | // ------------------------------------------------------------------------------------------
81 |
82 | void getInts(string name,vector &tokens, const string &text, char sep) {
83 |
84 | size_t start = 0, end = 0;
85 | tokens.clear();
86 | int item;
87 |
88 | try {
89 |
90 | while ((end = text.find(sep, start)) != string::npos) {
91 | item = std::stoi(text.substr(start, end - start));
92 | tokens.push_back(item);
93 | start = end + 1;
94 | }
95 |
96 | item = std::stoi(text.substr(start));
97 | tokens.push_back(item);
98 |
99 | } catch(std::invalid_argument &) {
100 |
101 | printf("Invalid %s argument, number expected\n",name.c_str());
102 | exit(-1);
103 |
104 | }
105 |
106 | }
107 |
108 | // ------------------------------------------------------------------------------------------
109 |
110 | int main(int argc, char* argv[]) {
111 |
112 | // Global Init
113 | Timer::Init();
114 | rseed((unsigned long)time(NULL));
115 |
116 | // Init SecpK1
117 | Secp256K1 *secp = new Secp256K1();
118 | secp->Init();
119 |
120 | int a = 1;
121 | int dp = -1;
122 | bool gpuEnable = false;
123 | bool stop = false;
124 | vector gpuId = {0};
125 | vector gridSize;
126 | string seed = "";
127 | vector prefix;
128 | string outputFile = "";
129 | int nbCPUThread = Timer::getCoreNumber();
130 | bool tSpecified = false;
131 | bool extraPts = false;
132 | bool checkFlag = false;
133 | uint32_t cSize = 40;
134 | uint64_t rekey = 0;
135 | Point startPuKey;
136 | startPuKey.Clear();
137 | string workFile = "";
138 | string iWorkFile = "";
139 | uint32_t savePeriod = 60;
140 |
141 | while (a < argc) {
142 |
143 | if (strcmp(argv[a], "-gpu")==0) {
144 | gpuEnable = true;
145 | a++;
146 | } else if (strcmp(argv[a], "-gpuId")==0) {
147 | a++;
148 | getInts("gpuId",gpuId,string(argv[a]),',');
149 | a++;
150 | } else if (strcmp(argv[a], "-stop") == 0) {
151 | stop = true;
152 | a++;
153 | } else if (strcmp(argv[a], "-v") == 0) {
154 | printf("%s\n",RELEASE);
155 | exit(0);
156 | } else if (strcmp(argv[a], "-check") == 0) {
157 | checkFlag = true;
158 | a++;
159 | } else if (strcmp(argv[a], "-l") == 0) {
160 |
161 | #ifdef WITHGPU
162 | GPUEngine::PrintCudaInfo();
163 | #else
164 | printf("GPU code not compiled, use -DWITHGPU when compiling.\n");
165 | #endif
166 | exit(0);
167 |
168 | } else if (strcmp(argv[a], "-e") == 0) {
169 | extraPts = true;
170 | a++;
171 | } else if (strcmp(argv[a], "-g") == 0) {
172 | a++;
173 | getInts("gridSize",gridSize,string(argv[a]),',');
174 | a++;
175 | } else if (strcmp(argv[a], "-o") == 0) {
176 | a++;
177 | outputFile = string(argv[a]);
178 | a++;
179 | } else if (strcmp(argv[a], "-w") == 0) {
180 | a++;
181 | workFile = string(argv[a]);
182 | a++;
183 | } else if (strcmp(argv[a], "-i") == 0) {
184 | a++;
185 | iWorkFile = string(argv[a]);
186 | a++;
187 | } else if (strcmp(argv[a], "-t") == 0) {
188 | a++;
189 | nbCPUThread = getInt("nbCPUThread",argv[a]);
190 | a++;
191 | tSpecified = true;
192 | } else if (strcmp(argv[a], "-wi") == 0) {
193 | a++;
194 | savePeriod = getInt("savePeriod", argv[a]);
195 | a++;
196 | } else if (strcmp(argv[a], "-s") == 0) {
197 | a++;
198 | cSize = getInt("collisionSize", argv[a]);
199 | if (cSize < 16 || cSize>160) {
200 | printf("Unexpected collision size [16,160] expected\n");
201 | exit(-1);
202 | }
203 | a++;
204 | } else if (strcmp(argv[a], "-d") == 0) {
205 | a++;
206 | dp = getInt("dpSize", argv[a]);
207 | a++;
208 | } else if (strcmp(argv[a], "-h") == 0) {
209 | printUsage();
210 | } else if (a == argc - 1) {
211 | prefix.push_back(string(argv[a]));
212 | a++;
213 | } else {
214 | printf("Unexpected %s argument\n",argv[a]);
215 | exit(-1);
216 | }
217 |
218 | }
219 |
220 | printf("BTCCollider v" RELEASE "\n");
221 |
222 | if(gridSize.size()==0) {
223 | for (int i = 0; i < gpuId.size(); i++) {
224 | gridSize.push_back(0);
225 | gridSize.push_back(0);
226 | }
227 | } else if(gridSize.size() != gpuId.size()*2) {
228 | printf("Invalid gridSize or gpuId argument, must have coherent size\n");
229 | exit(-1);
230 | }
231 |
232 | // Let one CPU core free per gpu is gpu is enabled
233 | // It will avoid to hang the system
234 | if( !tSpecified && nbCPUThread>1 && gpuEnable)
235 | nbCPUThread-=(int)gpuId.size();
236 | if(nbCPUThread<0)
237 | nbCPUThread = 0;
238 |
239 | BTCCollider *v = new BTCCollider(secp, gpuEnable, stop, outputFile, workFile, iWorkFile, savePeriod, cSize, dp, extraPts);
240 | if(checkFlag)
241 | v->Check(gpuId, gridSize);
242 | else
243 | v->Search(nbCPUThread,gpuId,gridSize);
244 |
245 | return 0;
246 | }
247 |
--------------------------------------------------------------------------------
/BTCCollider.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | ReleaseSM30
10 | x64
11 |
12 |
13 | Release
14 | x64
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | compute_30,sm_30
58 | compute_30,sm_30;compute_35,sm_35;compute_37,sm_37;compute_50,sm_50;compute_52,sm_52;compute_60,sm_60;compute_61,sm_61;compute_70,sm_70;compute_75,sm_75;
59 | compute_61,sm_61
60 | true
61 | true
62 | compile
63 |
64 |
65 |
66 |
67 |
68 | {9EA67A77-3F50-4FCE-85B9-FAB635FEFB0A}
69 | VanitySearch
70 | 10.0.17763.0
71 |
72 |
73 |
74 | Application
75 | true
76 | MultiByte
77 | v141
78 |
79 |
80 | Application
81 | false
82 | true
83 | MultiByte
84 | v141
85 |
86 |
87 | Application
88 | false
89 | true
90 | MultiByte
91 | v141
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | true
109 |
110 |
111 |
112 | Level3
113 | Disabled
114 | WITHGPU;_CRT_SECURE_NO_WARNINGS;WIN32;WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
115 |
116 |
117 | true
118 | Console
119 | cudart_static.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
120 |
121 |
122 | 64
123 |
124 |
125 |
126 |
127 | Level3
128 | MaxSpeed
129 | true
130 | true
131 | WITHGPU;_CRT_SECURE_NO_WARNINGS;WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
132 | AnySuitable
133 | Speed
134 |
135 |
136 | true
137 | true
138 | true
139 | Console
140 | cudart_static.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
141 |
142 |
143 | 64
144 |
145 |
146 |
147 |
148 | Level3
149 | MaxSpeed
150 | true
151 | true
152 | WITHGPU;_CRT_SECURE_NO_WARNINGS;WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
153 | StreamingSIMDExtensions2
154 |
155 |
156 | true
157 | true
158 | true
159 | Console
160 | cudart_static.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
161 |
162 |
163 | 64
164 |
165 |
166 |
167 |
168 |
169 |
170 |
--------------------------------------------------------------------------------
/HashTable.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include "HashTable.h"
19 | #include
20 | #include "Int.h"
21 | #ifndef WIN64
22 | #include
23 | #endif
24 |
25 | #define safe_free(x) if(x) {free(x);x=NULL;}
26 | #define GET(hash,id) E[hash].items[id]
27 |
28 | HashTable::HashTable() {
29 |
30 | totalItem = 0;
31 | memset(E,0,sizeof(E));
32 |
33 | }
34 |
35 | void HashTable::Reset() {
36 |
37 | for (uint32_t h = 0; h < HASH_SIZE; h++) {
38 | for(uint32_t i=0;ii16[i];
55 |
56 | if(colMask)
57 | s+=h->i16[i] & colMask;
58 |
59 | return s % HASH_SIZE;
60 |
61 | }
62 |
63 | void HashTable::SetParam(int n,int nbFull,uint16_t colMask) {
64 | this->cSize = n;
65 | this->nbFull = nbFull;
66 | this->colMask = colMask;
67 | }
68 |
69 | int HashTable::GetNbItem() {
70 | return totalItem;
71 | }
72 |
73 | ENTRY *HashTable::CreateEntry(hash160_t *h1, hash160_t *h2) {
74 | ENTRY *e = (ENTRY *)malloc(sizeof(ENTRY));
75 | e->start = *h1;
76 | e->end = *h2;
77 | return e;
78 | }
79 |
80 |
81 | void HashTable::getCollision(hash160_t *a, hash160_t *b, hash160_t *e) {
82 | *a = this->a;
83 | *b = this->b;
84 | if(e) *e = this->e;
85 | }
86 |
87 | #define ADD_ENTRY(entry) { \
88 | /* Shift the end of the index table */ \
89 | for (int i = E[h].nbItem; i > st; i--) \
90 | E[h].items[i] = E[h].items[i - 1]; \
91 | E[h].items[st] = entry; \
92 | E[h].nbItem++; \
93 | totalItem++;}
94 |
95 | int HashTable::AddHash(hash160_t *start, hash160_t *end) {
96 |
97 | uint16_t h = getHash(end);
98 |
99 | if (E[h].maxItem == 0) {
100 | E[h].maxItem = 16;
101 | E[h].items = (ENTRY **)malloc(sizeof(ENTRY *) * E[h].maxItem);
102 | }
103 |
104 | if(E[h].nbItem==0) {
105 | E[h].items[0] = CreateEntry(start, end);
106 | E[h].nbItem = 1;
107 | totalItem++;
108 | return false;
109 | }
110 |
111 | if (E[h].nbItem >= E[h].maxItem - 1) {
112 | // We need to reallocate
113 | E[h].maxItem += 16;
114 | ENTRY **nitems = (ENTRY **)malloc(sizeof(ENTRY *) * E[h].maxItem);
115 | memcpy(nitems, E[h].items, sizeof(ENTRY *) * E[h].nbItem);
116 | free(E[h].items);
117 | E[h].items = nitems;
118 | }
119 |
120 | // Search insertion position
121 | int st, ed, mi;
122 | st=0; ed = E[h].nbItem-1;
123 | while(st<=ed) {
124 | mi = (st+ed)/2;
125 | int comp = compareHash(end,&GET(h,mi)->end);
126 | if(comp<0) {
127 | ed = mi - 1;
128 | } else {
129 | st = mi + 1;
130 | }
131 | }
132 |
133 | // Collision check
134 | if (st > 0) {
135 | if (hashCollide(&GET(h, st - 1)->end, end)) {
136 | if (hashCollide(&GET(h, st - 1)->start, start)) {
137 | printf("\nFalse collision\n");
138 | return FALSE_COLLISION;
139 | }
140 | ENTRY *entry = CreateEntry(start,end);
141 | ADD_ENTRY(entry);
142 | a = GET(h, st-1)->start;
143 | b = GET(h, st)->start;
144 | e = GET(h, st)->end;
145 | return COLLISION;
146 | }
147 | }
148 | if (st < (int)E[h].nbItem ) {
149 | if (hashCollide(&GET(h, st)->end, end)) {
150 | if (hashCollide(&GET(h, st)->start, start)) {
151 | printf("\nFalse collision\n");
152 | return FALSE_COLLISION;
153 | }
154 | ENTRY *entry = CreateEntry(start, end);
155 | ADD_ENTRY(entry);
156 | a = GET(h, st)->start;
157 | b = GET(h, st+1)->start;
158 | e = GET(h, st)->end;
159 | return COLLISION;
160 | }
161 | }
162 |
163 | ENTRY *entry = CreateEntry(start, end);
164 | ADD_ENTRY(entry);
165 | return NO_COLLISION;
166 |
167 | }
168 |
169 | double HashTable::GetSizeMB() {
170 |
171 | uint64_t byte = 0;
172 | for (int h = 0; h < HASH_SIZE; h++) {
173 | if (E[h].nbItem > 0) {
174 | byte += sizeof(ENTRY *) * E[h].maxItem;
175 | byte += sizeof(ENTRY) * E[h].nbItem;
176 | }
177 | }
178 |
179 | return (double)byte / (1024.0*1024.0);
180 |
181 | }
182 |
183 |
184 | void HashTable::SaveTable(FILE *f) {
185 |
186 | for (uint32_t h = 0; h < HASH_SIZE; h++) {
187 | fwrite(&E[h].nbItem, sizeof(uint32_t), 1, f);
188 | fwrite(&E[h].maxItem, sizeof(uint32_t), 1, f);
189 | for (uint32_t i = 0; i < E[h].nbItem; i++) {
190 | fwrite(&E[h].items[i]->start, 20, 1, f);
191 | fwrite(&E[h].items[i]->end, 20, 1, f);
192 | }
193 | }
194 |
195 | }
196 |
197 | void HashTable::LoadTable(FILE *f) {
198 |
199 | Reset();
200 | for (uint32_t h = 0; h < HASH_SIZE; h++) {
201 | fread(&E[h].nbItem, sizeof(uint32_t), 1, f);
202 | fread(&E[h].maxItem, sizeof(uint32_t), 1, f);
203 | if (E[h].maxItem > 0) {
204 | // Allocate indexes
205 | E[h].items = (ENTRY **)malloc(sizeof(ENTRY *) * E[h].maxItem);
206 | }
207 | for (uint32_t i = 0; i < E[h].nbItem; i++) {
208 | ENTRY *e = (ENTRY *)malloc(sizeof(ENTRY));
209 | fread(&e->start, 20, 1, f);
210 | fread(&e->end, 20, 1, f);
211 | E[h].items[i] = e;
212 | }
213 | totalItem += E[h].nbItem;
214 | }
215 |
216 | printf("HashTable::LoadTable(): %d items loaded\n",totalItem);
217 |
218 | }
219 |
220 | std::string HashTable::GetHashStr(hash160_t *h1) {
221 |
222 | char tmp2[3];
223 | char tmp[256];
224 | tmp[0] = 0;
225 | for (int i = 0; i < 20; i++) {
226 | #ifdef WIN64
227 | sprintf_s(tmp2,3,"%02X",h1->i8[i]);
228 | #else
229 | sprintf(tmp2,"%02X",h1->i8[i]);
230 | #endif
231 | strcat(tmp,tmp2);
232 | }
233 | return std::string(tmp);
234 |
235 | }
236 |
237 | void HashTable::PrintTable(int limit) {
238 |
239 | int curItem=0;
240 | if(limit<=0) limit = totalItem;
241 |
242 | for (int h = 0; h < HASH_SIZE; h++) {
243 | if (E[h].nbItem > 0) {
244 | printf("ENTRY: %04X\n",h);
245 | for (uint32_t i = 0; i < E[h].nbItem && curItemstart).c_str());
249 | }
250 |
251 | }
252 | }
253 |
254 |
255 | }
256 |
257 | bool HashTable::compare(HashTable *ht) {
258 |
259 | if (ht->GetNbItem() != GetNbItem()) {
260 | printf("Item number not equal !\n");
261 | return false;
262 | }
263 |
264 | for (int h = 0; h < HASH_SIZE; h++) {
265 |
266 | if (ht->E[h].nbItem != E[h].nbItem) {
267 | printf("[H%04X] Item number not equal !\n",h);
268 | return false;
269 | }
270 |
271 | bool equal = true;
272 | uint32_t i = 0;
273 | while (equal && i < E[h].nbItem) {
274 | equal = (compareHash(&GET(h,i)->start , &ht->GET(h,i)->start)==0) &&
275 | (compareHash(&GET(h, i)->end, &ht->GET(h, i)->end) == 0);
276 | if(equal) i++;
277 | }
278 |
279 | if (!equal) {
280 | printf("Unexpected hash found at [%04X][%d] !\n", h,i);
281 | printf("H1 H %s\n", GetHashStr(&GET(h, i)->start).c_str());
282 | printf("H1 E %s\n", GetHashStr(&GET(h, i)->end).c_str());
283 | printf("H2 H %s\n", GetHashStr(&ht->GET(h, i)->start).c_str());
284 | printf("H2 E %s\n", GetHashStr(&ht->GET(h, i)->end).c_str());
285 | return false;
286 | }
287 |
288 | }
289 |
290 | return true;
291 |
292 | }
293 |
294 | bool HashTable::hashCollide(hash160_t *h1, hash160_t *h2) {
295 |
296 | int i=0;
297 | for(i=0;ii16[i]!=h2->i16[i])
299 | return false;
300 |
301 | if( colMask )
302 | if( (h1->i16[i] & colMask) != (h2->i16[i] & colMask) )
303 | return false;
304 |
305 | return true;
306 |
307 | }
308 |
309 | int HashTable::getCollisionSize(hash160_t *h1, hash160_t *h2) {
310 |
311 | int i;
312 | int size = 0;
313 |
314 | for (i = 0; i < 20; i++) {
315 | if (h1->i8[i] != h2->i8[i])
316 | break;
317 | size += 8;
318 | }
319 |
320 | if (i < 20) {
321 |
322 | uint8_t m = 0x80;
323 | uint8_t b1=0;
324 | uint8_t b2=0;
325 | while (b1 == b2) {
326 | b1 = h1->i8[i] & m;
327 | b2 = h2->i8[i] & m;
328 | if (b1 == b2) {
329 | size++;
330 | m = m >> 1;
331 | }
332 | }
333 |
334 | }
335 |
336 | return size;
337 |
338 | }
339 |
340 | int HashTable::compareHash(hash160_t *h1, hash160_t *h2) {
341 |
342 | uint32_t *a = h1->i32;
343 | uint32_t *b = h2->i32;
344 | int i;
345 |
346 | for(i=0;i<5;i++) {
347 | if( a[i]!=b[i] )
348 | break;
349 | }
350 |
351 | if(i<5) {
352 | #ifdef WIN64
353 | uint32_t ai = _byteswap_ulong(a[i]);
354 | uint32_t bi = _byteswap_ulong(b[i]);
355 | #else
356 | uint32_t ai = __builtin_bswap32(a[i]);
357 | uint32_t bi = __builtin_bswap32(b[i]);
358 | #endif
359 | if( ai>bi ) return 1;
360 | else return -1;
361 | } else {
362 | return 0;
363 | }
364 |
365 | }
366 |
367 |
--------------------------------------------------------------------------------
/Int.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | // Big integer class (Fixed size)
19 |
20 | #ifndef BIGINTH
21 | #define BIGINTH
22 |
23 | #include "Random.h"
24 | #include
25 | #include
26 |
27 | // We need 1 extra block for Knuth div algorithm , Montgomery multiplication and ModInv
28 | #define BISIZE 256
29 |
30 | #if BISIZE==256
31 | #define NB64BLOCK 5
32 | #define NB32BLOCK 10
33 | #elif BISIZE==512
34 | #define NB64BLOCK 9
35 | #define NB32BLOCK 18
36 | #else
37 | #error Unsuported size
38 | #endif
39 |
40 | class Int {
41 |
42 | public:
43 |
44 | Int();
45 | Int(int64_t i64);
46 | Int(Int *a);
47 |
48 | // Op
49 | void Add(uint64_t a);
50 | void Add(Int *a);
51 | void Add(Int *a,Int *b);
52 | void AddOne();
53 | void Sub(uint64_t a);
54 | void Sub(Int *a);
55 | void Sub(Int *a, Int *b);
56 | void SubOne();
57 | void Mult(Int *a);
58 | void Mult(uint64_t a);
59 | void IMult(int64_t a);
60 | void Mult(Int *a,uint64_t b);
61 | void IMult(Int *a, int64_t b);
62 | void Mult(Int *a,Int *b);
63 | void Div(Int *a,Int *mod = NULL);
64 | void MultModN(Int *a, Int *b, Int *n);
65 | void Neg();
66 | void Abs();
67 |
68 | // Right shift (signed)
69 | void ShiftR(uint32_t n);
70 | void ShiftR32Bit();
71 | void ShiftR64Bit();
72 | // Left shift
73 | void ShiftL(uint32_t n);
74 | void ShiftL32Bit();
75 | void ShiftL64Bit();
76 |
77 | // Comp
78 | bool IsGreater(Int *a);
79 | bool IsGreaterOrEqual(Int *a);
80 | bool IsLowerOrEqual(Int *a);
81 | bool IsLower(Int *a);
82 | bool IsEqual(Int *a);
83 | bool IsZero();
84 | bool IsOne();
85 | bool IsStrictPositive();
86 | bool IsPositive();
87 | bool IsNegative();
88 | bool IsEven();
89 | bool IsOdd();
90 |
91 | // Modular arithmetic
92 |
93 | // Setup field
94 | // n is the field characteristic
95 | // R used in Montgomery mult (R = 2^size(n))
96 | // R2 = R^2, R3 = R^3, R4 = R^4
97 | static void SetupField(Int *n, Int *R = NULL, Int *R2 = NULL, Int *R3 = NULL, Int *R4 = NULL);
98 | static Int *GetR(); // Return R
99 | static Int *GetR2(); // Return R2
100 | static Int *GetR3(); // Return R3
101 | static Int *GetR4(); // Return R4
102 | static Int* GetFieldCharacteristic(); // Return field characteristic
103 |
104 | void GCD(Int *a); // this <- GCD(this,a)
105 | void Mod(Int *n); // this <- this (mod n)
106 | void ModInv(); // this <- this^-1 (mod n)
107 | void MontgomeryMult(Int *a,Int *b); // this <- a*b*R^-1 (mod n)
108 | void MontgomeryMult(Int *a); // this <- this*a*R^-1 (mod n)
109 | void ModAdd(Int *a); // this <- this+a (mod n) [0
224 | #endif
225 |
226 | static void inline imm_mul(uint64_t *x, uint64_t y, uint64_t *dst) {
227 |
228 | unsigned char c = 0;
229 | uint64_t h, carry;
230 | dst[0] = _umul128(x[0], y, &h); carry = h;
231 | c = _addcarry_u64(c, _umul128(x[1], y, &h), carry, dst + 1); carry = h;
232 | c = _addcarry_u64(c, _umul128(x[2], y, &h), carry, dst + 2); carry = h;
233 | c = _addcarry_u64(c, _umul128(x[3], y, &h), carry, dst + 3); carry = h;
234 | c = _addcarry_u64(c, _umul128(x[4], y, &h), carry, dst + 4); carry = h;
235 | #if NB64BLOCK > 5
236 | c = _addcarry_u64(c, _umul128(x[5], y, &h), carry, dst + 5); carry = h;
237 | c = _addcarry_u64(c, _umul128(x[6], y, &h), carry, dst + 6); carry = h;
238 | c = _addcarry_u64(c, _umul128(x[7], y, &h), carry, dst + 7); carry = h;
239 | c = _addcarry_u64(c, _umul128(x[8], y, &h), carry, dst + 8); carry = h;
240 | #endif
241 |
242 | }
243 |
244 | static void inline imm_umul(uint64_t *x, uint64_t y, uint64_t *dst) {
245 |
246 | // Assume that x[NB64BLOCK-1] is 0
247 | unsigned char c = 0;
248 | uint64_t h, carry;
249 | dst[0] = _umul128(x[0], y, &h); carry = h;
250 | c = _addcarry_u64(c, _umul128(x[1], y, &h), carry, dst + 1); carry = h;
251 | c = _addcarry_u64(c, _umul128(x[2], y, &h), carry, dst + 2); carry = h;
252 | c = _addcarry_u64(c, _umul128(x[3], y, &h), carry, dst + 3); carry = h;
253 | #if NB64BLOCK > 5
254 | c = _addcarry_u64(c, _umul128(x[4], y, &h), carry, dst + 4); carry = h;
255 | c = _addcarry_u64(c, _umul128(x[5], y, &h), carry, dst + 5); carry = h;
256 | c = _addcarry_u64(c, _umul128(x[6], y, &h), carry, dst + 6); carry = h;
257 | c = _addcarry_u64(c, _umul128(x[7], y, &h), carry, dst + 7); carry = h;
258 | #endif
259 | _addcarry_u64(c, 0ULL, carry, dst + (NB64BLOCK - 1));
260 |
261 | }
262 |
263 | static void inline shiftR(unsigned char n, uint64_t *d) {
264 |
265 | d[0] = __shiftright128(d[0], d[1], n);
266 | d[1] = __shiftright128(d[1], d[2], n);
267 | d[2] = __shiftright128(d[2], d[3], n);
268 | d[3] = __shiftright128(d[3], d[4], n);
269 | #if NB64BLOCK > 5
270 | d[4] = __shiftright128(d[4], d[5], n);
271 | d[5] = __shiftright128(d[5], d[6], n);
272 | d[6] = __shiftright128(d[6], d[7], n);
273 | d[7] = __shiftright128(d[7], d[8], n);
274 | #endif
275 | d[NB64BLOCK-1] = ((int64_t)d[NB64BLOCK-1]) >> n;
276 |
277 | }
278 |
279 | static void inline shiftL(unsigned char n, uint64_t *d) {
280 |
281 | #if NB64BLOCK > 5
282 | d[8] = __shiftleft128(d[7], d[8], n);
283 | d[7] = __shiftleft128(d[6], d[7], n);
284 | d[6] = __shiftleft128(d[5], d[6], n);
285 | d[5] = __shiftleft128(d[4], d[5], n);
286 | #endif
287 | d[4] = __shiftleft128(d[3], d[4], n);
288 | d[3] = __shiftleft128(d[2], d[3], n);
289 | d[2] = __shiftleft128(d[1], d[2], n);
290 | d[1] = __shiftleft128(d[0], d[1], n);
291 | d[0] = d[0] << n;
292 |
293 | }
294 |
295 | #endif // BIGINTH
296 |
--------------------------------------------------------------------------------
/hash/ripemd160.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include "ripemd160.h"
19 | #include
20 |
21 | /// Internal RIPEMD-160 implementation.
22 | namespace _ripemd160 {
23 |
24 | /** Initialize RIPEMD-160 state. */
25 | void inline Initialize(uint32_t* s)
26 | {
27 | s[0] = 0x67452301ul;
28 | s[1] = 0xEFCDAB89ul;
29 | s[2] = 0x98BADCFEul;
30 | s[3] = 0x10325476ul;
31 | s[4] = 0xC3D2E1F0ul;
32 | }
33 |
34 | #ifndef WIN64
35 | inline uint32_t _rotl(uint32_t x, uint8_t r) {
36 | asm("roll %1,%0" : "+r" (x) : "c" (r));
37 | return x;
38 | }
39 | #endif
40 |
41 | #define ROL(x,n) _rotl(x,n)
42 |
43 | #define f1(x, y, z) (x ^ y ^ z)
44 | #define f2(x, y, z) ((x & y) | (~x & z))
45 | #define f3(x, y, z) ((x | ~y) ^ z)
46 | #define f4(x, y, z) ((x & z) | (~z & y))
47 | #define f5(x, y, z) (x ^ (y | ~z))
48 |
49 | #define Round(a,b,c,d,e,f,x,k,r) \
50 | a = ROL(a + f + x + k, r) + e; \
51 | c = ROL(c, 10);
52 |
53 | #define R11(a,b,c,d,e,x,r) Round(a, b, c, d, e, f1(b, c, d), x, 0, r)
54 | #define R21(a,b,c,d,e,x,r) Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r)
55 | #define R31(a,b,c,d,e,x,r) Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r)
56 | #define R41(a,b,c,d,e,x,r) Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r)
57 | #define R51(a,b,c,d,e,x,r) Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r)
58 | #define R12(a,b,c,d,e,x,r) Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r)
59 | #define R22(a,b,c,d,e,x,r) Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r)
60 | #define R32(a,b,c,d,e,x,r) Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r)
61 | #define R42(a,b,c,d,e,x,r) Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r)
62 | #define R52(a,b,c,d,e,x,r) Round(a, b, c, d, e, f1(b, c, d), x, 0, r)
63 |
64 | /** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */
65 | void Transform(uint32_t* s, const unsigned char* chunk)
66 | {
67 | uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4];
68 | uint32_t a2 = a1, b2 = b1, c2 = c1, d2 = d1, e2 = e1;
69 | uint32_t w[16];
70 | memcpy(w,chunk,16*sizeof(uint32_t));
71 |
72 | R11(a1, b1, c1, d1, e1, w[0], 11);
73 | R12(a2, b2, c2, d2, e2, w[5], 8);
74 | R11(e1, a1, b1, c1, d1, w[1], 14);
75 | R12(e2, a2, b2, c2, d2, w[14], 9);
76 | R11(d1, e1, a1, b1, c1, w[2], 15);
77 | R12(d2, e2, a2, b2, c2, w[7], 9);
78 | R11(c1, d1, e1, a1, b1, w[3], 12);
79 | R12(c2, d2, e2, a2, b2, w[0], 11);
80 | R11(b1, c1, d1, e1, a1, w[4], 5);
81 | R12(b2, c2, d2, e2, a2, w[9], 13);
82 | R11(a1, b1, c1, d1, e1, w[5], 8);
83 | R12(a2, b2, c2, d2, e2, w[2], 15);
84 | R11(e1, a1, b1, c1, d1, w[6], 7);
85 | R12(e2, a2, b2, c2, d2, w[11], 15);
86 | R11(d1, e1, a1, b1, c1, w[7], 9);
87 | R12(d2, e2, a2, b2, c2, w[4], 5);
88 | R11(c1, d1, e1, a1, b1, w[8], 11);
89 | R12(c2, d2, e2, a2, b2, w[13], 7);
90 | R11(b1, c1, d1, e1, a1, w[9], 13);
91 | R12(b2, c2, d2, e2, a2, w[6], 7);
92 | R11(a1, b1, c1, d1, e1, w[10], 14);
93 | R12(a2, b2, c2, d2, e2, w[15], 8);
94 | R11(e1, a1, b1, c1, d1, w[11], 15);
95 | R12(e2, a2, b2, c2, d2, w[8], 11);
96 | R11(d1, e1, a1, b1, c1, w[12], 6);
97 | R12(d2, e2, a2, b2, c2, w[1], 14);
98 | R11(c1, d1, e1, a1, b1, w[13], 7);
99 | R12(c2, d2, e2, a2, b2, w[10], 14);
100 | R11(b1, c1, d1, e1, a1, w[14], 9);
101 | R12(b2, c2, d2, e2, a2, w[3], 12);
102 | R11(a1, b1, c1, d1, e1, w[15], 8);
103 | R12(a2, b2, c2, d2, e2, w[12], 6);
104 |
105 | R21(e1, a1, b1, c1, d1, w[7], 7);
106 | R22(e2, a2, b2, c2, d2, w[6], 9);
107 | R21(d1, e1, a1, b1, c1, w[4], 6);
108 | R22(d2, e2, a2, b2, c2, w[11], 13);
109 | R21(c1, d1, e1, a1, b1, w[13], 8);
110 | R22(c2, d2, e2, a2, b2, w[3], 15);
111 | R21(b1, c1, d1, e1, a1, w[1], 13);
112 | R22(b2, c2, d2, e2, a2, w[7], 7);
113 | R21(a1, b1, c1, d1, e1, w[10], 11);
114 | R22(a2, b2, c2, d2, e2, w[0], 12);
115 | R21(e1, a1, b1, c1, d1, w[6], 9);
116 | R22(e2, a2, b2, c2, d2, w[13], 8);
117 | R21(d1, e1, a1, b1, c1, w[15], 7);
118 | R22(d2, e2, a2, b2, c2, w[5], 9);
119 | R21(c1, d1, e1, a1, b1, w[3], 15);
120 | R22(c2, d2, e2, a2, b2, w[10], 11);
121 | R21(b1, c1, d1, e1, a1, w[12], 7);
122 | R22(b2, c2, d2, e2, a2, w[14], 7);
123 | R21(a1, b1, c1, d1, e1, w[0], 12);
124 | R22(a2, b2, c2, d2, e2, w[15], 7);
125 | R21(e1, a1, b1, c1, d1, w[9], 15);
126 | R22(e2, a2, b2, c2, d2, w[8], 12);
127 | R21(d1, e1, a1, b1, c1, w[5], 9);
128 | R22(d2, e2, a2, b2, c2, w[12], 7);
129 | R21(c1, d1, e1, a1, b1, w[2], 11);
130 | R22(c2, d2, e2, a2, b2, w[4], 6);
131 | R21(b1, c1, d1, e1, a1, w[14], 7);
132 | R22(b2, c2, d2, e2, a2, w[9], 15);
133 | R21(a1, b1, c1, d1, e1, w[11], 13);
134 | R22(a2, b2, c2, d2, e2, w[1], 13);
135 | R21(e1, a1, b1, c1, d1, w[8], 12);
136 | R22(e2, a2, b2, c2, d2, w[2], 11);
137 |
138 | R31(d1, e1, a1, b1, c1, w[3], 11);
139 | R32(d2, e2, a2, b2, c2, w[15], 9);
140 | R31(c1, d1, e1, a1, b1, w[10], 13);
141 | R32(c2, d2, e2, a2, b2, w[5], 7);
142 | R31(b1, c1, d1, e1, a1, w[14], 6);
143 | R32(b2, c2, d2, e2, a2, w[1], 15);
144 | R31(a1, b1, c1, d1, e1, w[4], 7);
145 | R32(a2, b2, c2, d2, e2, w[3], 11);
146 | R31(e1, a1, b1, c1, d1, w[9], 14);
147 | R32(e2, a2, b2, c2, d2, w[7], 8);
148 | R31(d1, e1, a1, b1, c1, w[15], 9);
149 | R32(d2, e2, a2, b2, c2, w[14], 6);
150 | R31(c1, d1, e1, a1, b1, w[8], 13);
151 | R32(c2, d2, e2, a2, b2, w[6], 6);
152 | R31(b1, c1, d1, e1, a1, w[1], 15);
153 | R32(b2, c2, d2, e2, a2, w[9], 14);
154 | R31(a1, b1, c1, d1, e1, w[2], 14);
155 | R32(a2, b2, c2, d2, e2, w[11], 12);
156 | R31(e1, a1, b1, c1, d1, w[7], 8);
157 | R32(e2, a2, b2, c2, d2, w[8], 13);
158 | R31(d1, e1, a1, b1, c1, w[0], 13);
159 | R32(d2, e2, a2, b2, c2, w[12], 5);
160 | R31(c1, d1, e1, a1, b1, w[6], 6);
161 | R32(c2, d2, e2, a2, b2, w[2], 14);
162 | R31(b1, c1, d1, e1, a1, w[13], 5);
163 | R32(b2, c2, d2, e2, a2, w[10], 13);
164 | R31(a1, b1, c1, d1, e1, w[11], 12);
165 | R32(a2, b2, c2, d2, e2, w[0], 13);
166 | R31(e1, a1, b1, c1, d1, w[5], 7);
167 | R32(e2, a2, b2, c2, d2, w[4], 7);
168 | R31(d1, e1, a1, b1, c1, w[12], 5);
169 | R32(d2, e2, a2, b2, c2, w[13], 5);
170 |
171 | R41(c1, d1, e1, a1, b1, w[1], 11);
172 | R42(c2, d2, e2, a2, b2, w[8], 15);
173 | R41(b1, c1, d1, e1, a1, w[9], 12);
174 | R42(b2, c2, d2, e2, a2, w[6], 5);
175 | R41(a1, b1, c1, d1, e1, w[11], 14);
176 | R42(a2, b2, c2, d2, e2, w[4], 8);
177 | R41(e1, a1, b1, c1, d1, w[10], 15);
178 | R42(e2, a2, b2, c2, d2, w[1], 11);
179 | R41(d1, e1, a1, b1, c1, w[0], 14);
180 | R42(d2, e2, a2, b2, c2, w[3], 14);
181 | R41(c1, d1, e1, a1, b1, w[8], 15);
182 | R42(c2, d2, e2, a2, b2, w[11], 14);
183 | R41(b1, c1, d1, e1, a1, w[12], 9);
184 | R42(b2, c2, d2, e2, a2, w[15], 6);
185 | R41(a1, b1, c1, d1, e1, w[4], 8);
186 | R42(a2, b2, c2, d2, e2, w[0], 14);
187 | R41(e1, a1, b1, c1, d1, w[13], 9);
188 | R42(e2, a2, b2, c2, d2, w[5], 6);
189 | R41(d1, e1, a1, b1, c1, w[3], 14);
190 | R42(d2, e2, a2, b2, c2, w[12], 9);
191 | R41(c1, d1, e1, a1, b1, w[7], 5);
192 | R42(c2, d2, e2, a2, b2, w[2], 12);
193 | R41(b1, c1, d1, e1, a1, w[15], 6);
194 | R42(b2, c2, d2, e2, a2, w[13], 9);
195 | R41(a1, b1, c1, d1, e1, w[14], 8);
196 | R42(a2, b2, c2, d2, e2, w[9], 12);
197 | R41(e1, a1, b1, c1, d1, w[5], 6);
198 | R42(e2, a2, b2, c2, d2, w[7], 5);
199 | R41(d1, e1, a1, b1, c1, w[6], 5);
200 | R42(d2, e2, a2, b2, c2, w[10], 15);
201 | R41(c1, d1, e1, a1, b1, w[2], 12);
202 | R42(c2, d2, e2, a2, b2, w[14], 8);
203 |
204 | R51(b1, c1, d1, e1, a1, w[4], 9);
205 | R52(b2, c2, d2, e2, a2, w[12], 8);
206 | R51(a1, b1, c1, d1, e1, w[0], 15);
207 | R52(a2, b2, c2, d2, e2, w[15], 5);
208 | R51(e1, a1, b1, c1, d1, w[5], 5);
209 | R52(e2, a2, b2, c2, d2, w[10], 12);
210 | R51(d1, e1, a1, b1, c1, w[9], 11);
211 | R52(d2, e2, a2, b2, c2, w[4], 9);
212 | R51(c1, d1, e1, a1, b1, w[7], 6);
213 | R52(c2, d2, e2, a2, b2, w[1], 12);
214 | R51(b1, c1, d1, e1, a1, w[12], 8);
215 | R52(b2, c2, d2, e2, a2, w[5], 5);
216 | R51(a1, b1, c1, d1, e1, w[2], 13);
217 | R52(a2, b2, c2, d2, e2, w[8], 14);
218 | R51(e1, a1, b1, c1, d1, w[10], 12);
219 | R52(e2, a2, b2, c2, d2, w[7], 6);
220 | R51(d1, e1, a1, b1, c1, w[14], 5);
221 | R52(d2, e2, a2, b2, c2, w[6], 8);
222 | R51(c1, d1, e1, a1, b1, w[1], 12);
223 | R52(c2, d2, e2, a2, b2, w[2], 13);
224 | R51(b1, c1, d1, e1, a1, w[3], 13);
225 | R52(b2, c2, d2, e2, a2, w[13], 6);
226 | R51(a1, b1, c1, d1, e1, w[8], 14);
227 | R52(a2, b2, c2, d2, e2, w[14], 5);
228 | R51(e1, a1, b1, c1, d1, w[11], 11);
229 | R52(e2, a2, b2, c2, d2, w[0], 15);
230 | R51(d1, e1, a1, b1, c1, w[6], 8);
231 | R52(d2, e2, a2, b2, c2, w[3], 13);
232 | R51(c1, d1, e1, a1, b1, w[15], 5);
233 | R52(c2, d2, e2, a2, b2, w[9], 11);
234 | R51(b1, c1, d1, e1, a1, w[13], 6);
235 | R52(b2, c2, d2, e2, a2, w[11], 11);
236 |
237 | uint32_t t = s[0];
238 | s[0] = s[1] + c1 + d2;
239 | s[1] = s[2] + d1 + e2;
240 | s[2] = s[3] + e1 + a2;
241 | s[3] = s[4] + a1 + b2;
242 | s[4] = t + b1 + c2;
243 | }
244 |
245 | } // namespace ripemd160
246 |
247 | CRIPEMD160::CRIPEMD160() : bytes(0)
248 | {
249 | _ripemd160::Initialize(s);
250 | }
251 |
252 | void CRIPEMD160::Write(const unsigned char* data, size_t len)
253 | {
254 | const unsigned char* end = data + len;
255 | size_t bufsize = bytes % 64;
256 | if (bufsize && bufsize + len >= 64) {
257 | // Fill the buffer, and process it.
258 | memcpy(buf + bufsize, data, 64 - bufsize);
259 | bytes += 64 - bufsize;
260 | data += 64 - bufsize;
261 | _ripemd160::Transform(s, buf);
262 | bufsize = 0;
263 | }
264 | while (end >= data + 64) {
265 | // Process full chunks directly from the source.
266 | _ripemd160::Transform(s, data);
267 | bytes += 64;
268 | data += 64;
269 | }
270 | if (end > data) {
271 | // Fill the buffer with what remains.
272 | memcpy(buf + bufsize, data, end - data);
273 | bytes += end - data;
274 | }
275 | }
276 |
277 | void CRIPEMD160::Finalize(unsigned char hash[20])
278 | {
279 | static const unsigned char pad[64] = {0x80};
280 | unsigned char sizedesc[8];
281 | *(uint64_t *)sizedesc = bytes << 3;
282 | Write(pad, 1 + ((119 - (bytes % 64)) % 64));
283 | Write(sizedesc, 8);
284 | memcpy(hash,s,20);
285 | }
286 |
287 | static const uint64_t sizedesc_32 = 32 << 3;
288 | static const unsigned char pad[64] = { 0x80 };
289 |
290 | void ripemd160_32(unsigned char *input, unsigned char *digest) {
291 |
292 | uint32_t *s = (uint32_t *)digest;
293 | _ripemd160::Initialize(s);
294 | memcpy(input+32,pad,24);
295 | memcpy(input+56,&sizedesc_32,8);
296 | _ripemd160::Transform(s, input);
297 |
298 | }
299 |
300 | void ripemd160(unsigned char *input,int length,unsigned char *digest) {
301 |
302 | CRIPEMD160 cripe;
303 | cripe.Write(input,length);
304 | cripe.Finalize(digest);
305 |
306 | }
307 |
308 | std::string ripemd160_hex(unsigned char *digest) {
309 |
310 | char buf[2 * 20 + 1];
311 | buf[2 * 20] = 0;
312 | for (int i = 0; i < 20; i++)
313 | sprintf(buf + i * 2, "%02x", (int)digest[i]);
314 | return std::string(buf);
315 |
316 | }
317 |
--------------------------------------------------------------------------------
/hash/sha512.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include
19 | #include "sha512.h"
20 |
21 | #define BSWAP
22 | #define SHA512_BLOCK_SIZE 128
23 | #define SHA512_HASH_LENGTH 64
24 | #define MIN(x,y) (xy)?x:y;
26 |
27 | /// Internal SHA-512 implementation.
28 | namespace _sha512 {
29 |
30 | static const uint64_t K[80] = {
31 | 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
32 | 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
33 | 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
34 | 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
35 | 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
36 | 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
37 | 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
38 | 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
39 | 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
40 | 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
41 | 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
42 | 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
43 | 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
44 | 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
45 | 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
46 | 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
47 | 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
48 | 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
49 | 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
50 | 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
51 | 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
52 | 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
53 | 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
54 | 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
55 | 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
56 | 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
57 | 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
58 | };
59 |
60 | #ifndef WIN64
61 | #define _byteswap_ulong __builtin_bswap32
62 | #define _byteswap_uint64 __builtin_bswap64
63 | inline uint64_t _rotr64(uint64_t x, uint8_t r) {
64 | asm("rorq %1,%0" : "+r" (x) : "c" (r));
65 | return x;
66 | }
67 | #endif
68 |
69 | #define ROR(x,n) _rotr64(x, n)
70 | #define S0(x) (ROR(x, 28) ^ ROR(x, 34) ^ ROR(x, 39))
71 | #define S1(x) (ROR(x, 14) ^ ROR(x, 18) ^ ROR(x, 41))
72 | #define G0(x) (ROR(x, 1) ^ ROR(x, 8) ^ (x >> 7))
73 | #define G1(x) (ROR(x, 19) ^ ROR(x, 61) ^ (x >> 6))
74 |
75 | #define ROUND(i, a,b,c,d,e,f,g,h) \
76 | t = h + S1(e) + (g ^ (e & (f ^ g))) + K[i] + W[i]; \
77 | d += t; \
78 | h = t + S0(a) + ( ((a | b) & c) | (a & b) )
79 |
80 | #ifdef BSWAP
81 | #define READBE64(ptr) _byteswap_uint64(*(uint64_t *)(ptr));
82 | #define WRITEBE64(ptr,x) *((uint64_t *)(ptr)) = _byteswap_uint64(x);
83 | #define READBE32(i) _byteswap_ulong((uint32_t)(i));
84 | #else
85 | #define READBE64(ptr) *(uint64_t *)(ptr);
86 | #define WRITEBE64(ptr,x) *(ptr) = x;
87 | #define READBE32(i) (uint32_t)(i);
88 | #endif
89 |
90 | static void Transform(uint64_t state[8], const uint8_t buf[128]) {
91 |
92 | uint64_t W[80], t;
93 | uint64_t a, b, c, d, e, f, g, h;
94 | int i;
95 |
96 | a = state[0];
97 | b = state[1];
98 | c = state[2];
99 | d = state[3];
100 | e = state[4];
101 | f = state[5];
102 | g = state[6];
103 | h = state[7];
104 |
105 | W[0] = READBE64(buf + 0x0);
106 | W[1] = READBE64(buf + 0x8);
107 | W[2] = READBE64(buf + 0x10);
108 | W[3] = READBE64(buf + 0x18);
109 | W[4] = READBE64(buf + 0x20);
110 | W[5] = READBE64(buf + 0x28);
111 | W[6] = READBE64(buf + 0x30);
112 | W[7] = READBE64(buf + 0x38);
113 | W[8] = READBE64(buf + 0x40);
114 | W[9] = READBE64(buf + 0x48);
115 | W[10] = READBE64(buf + 0x50);
116 | W[11] = READBE64(buf + 0x58);
117 | W[12] = READBE64(buf + 0x60);
118 | W[13] = READBE64(buf + 0x68);
119 | W[14] = READBE64(buf + 0x70);
120 | W[15] = READBE64(buf + 0x78);
121 |
122 | for(i = 16; i < 80; i++)
123 | W[i] = W[i - 16] + G0(W[i - 15]) + W[i - 7] + G1(W[i - 2]);
124 |
125 | for (i = 0; i < 80; i += 8) {
126 | ROUND(i + 0, a, b, c, d, e, f, g, h);
127 | ROUND(i + 1, h, a, b, c, d, e, f, g);
128 | ROUND(i + 2, g, h, a, b, c, d, e, f);
129 | ROUND(i + 3, f, g, h, a, b, c, d, e);
130 | ROUND(i + 4, e, f, g, h, a, b, c, d);
131 | ROUND(i + 5, d, e, f, g, h, a, b, c);
132 | ROUND(i + 6, c, d, e, f, g, h, a, b);
133 | ROUND(i + 7, b, c, d, e, f, g, h, a);
134 | }
135 |
136 | state[0] += a;
137 | state[1] += b;
138 | state[2] += c;
139 | state[3] += d;
140 | state[4] += e;
141 | state[5] += f;
142 | state[6] += g;
143 | state[7] += h;
144 |
145 | }
146 |
147 |
148 | }
149 |
150 |
151 | class CSHA512 {
152 |
153 | private:
154 | uint64_t s[8];
155 | unsigned char buf[128];
156 | size_t buffSize;
157 | size_t count;
158 |
159 | public:
160 |
161 | CSHA512();
162 | void Initialize();
163 | void Write(const unsigned char* data, size_t len);
164 | void WriteDirect128(const unsigned char* data);
165 | void WriteDirect64(const unsigned char* data);
166 | void Finalize(unsigned char hash[64]);
167 |
168 | };
169 |
170 | CSHA512::CSHA512() {
171 |
172 | Initialize();
173 |
174 | }
175 |
176 | void CSHA512::Initialize() {
177 |
178 | buffSize = 0;
179 | count = 0;
180 | s[0] = 0x6a09e667f3bcc908ULL;
181 | s[1] = 0xbb67ae8584caa73bULL;
182 | s[2] = 0x3c6ef372fe94f82bULL;
183 | s[3] = 0xa54ff53a5f1d36f1ULL;
184 | s[4] = 0x510e527fade682d1ULL;
185 | s[5] = 0x9b05688c2b3e6c1fULL;
186 | s[6] = 0x1f83d9abfb41bd6bULL;
187 | s[7] = 0x5be0cd19137e2179ULL;
188 |
189 | }
190 |
191 | void CSHA512::Write(const unsigned char* data, size_t len) {
192 |
193 | if (buffSize > 0) {
194 |
195 | // Fill internal buffer up and transform
196 | size_t fill = MIN(len,128-buffSize);
197 | memcpy(buf+buffSize,data, fill);
198 | len -= fill;
199 | buffSize += fill;
200 | if(buffSize < 128)
201 | return;
202 | _sha512::Transform(s, buf);
203 | count++;
204 |
205 | }
206 |
207 | // Internal buffer is empty
208 | while (len >= 128) {
209 | _sha512::Transform(s, data);
210 | count++;
211 | data += 128;
212 | len -= 128;
213 | }
214 |
215 | // save rest for next time
216 | memcpy(buf,data,len);
217 | buffSize = len;
218 |
219 | }
220 |
221 | // Write 128 bytes aligned (buffsize must be 0)
222 | void CSHA512::WriteDirect128(const unsigned char* data) {
223 | _sha512::Transform(s, data);
224 | count++;
225 | }
226 |
227 | // Write 64 bytes aligned (buffsize must be 0)
228 | void CSHA512::WriteDirect64(const unsigned char* data) {
229 | memcpy(buf, data, 64);
230 | buffSize = 64;
231 | }
232 |
233 | void CSHA512::Finalize(unsigned char hash[64]) {
234 |
235 | size_t rest;
236 | size_t i;
237 |
238 | rest = buffSize;
239 |
240 | // End code
241 | buf[buffSize++] = 0x80;
242 |
243 | if (buffSize > 112) {
244 | memset(buf+buffSize,0,128-buffSize);
245 | _sha512::Transform(s, buf);
246 | buffSize = 0;
247 | }
248 | memset(buf+buffSize,0,112-buffSize);
249 |
250 | // Write length (128bit big-endian)
251 | WRITEBE64(buf + 112, count >> 54);
252 | WRITEBE64(buf + 120, ((count << 7) | rest) << 3);
253 | _sha512::Transform(s, buf);
254 |
255 | for (i = 0; i < 8; i++)
256 | WRITEBE64(hash + 8 * i, s[i]);
257 |
258 | }
259 |
260 |
261 | /* padding */
262 | #define IPAD 0x36
263 | #define IPADLL 0x3636363636363636LL
264 | #define OPAD 0x5c
265 | #define OPADLL 0x5c5c5c5c5c5c5c5cLL
266 |
267 | void hmac_sha512_init(CSHA512 &ctx, const uint8_t key[SHA512_BLOCK_SIZE]) {
268 |
269 | uint64_t pad[SHA512_BLOCK_SIZE/8];
270 | uint64_t *keyPtr = (uint64_t *)key;
271 | int i;
272 |
273 | // Inner padding
274 | for (i = 0; i < SHA512_BLOCK_SIZE/8; i++)
275 | pad[i] = keyPtr[i] ^ IPADLL;
276 |
277 | ctx.Initialize();
278 | ctx.WriteDirect128((unsigned char *)pad);
279 |
280 | }
281 |
282 |
283 | void hmac_sha512_done(CSHA512 &ctx, const uint8_t key[SHA512_BLOCK_SIZE], uint8_t result[SHA512_HASH_LENGTH]) {
284 |
285 | uint64_t pad[SHA512_BLOCK_SIZE/8];
286 | uint64_t *keyPtr = (uint64_t *)key;
287 | uint8_t ihash[SHA512_HASH_LENGTH];
288 | int i;
289 |
290 | // Finalize inner hash
291 | ctx.Finalize(ihash);
292 |
293 | // Construct outer padding
294 | for (i = 0; i < SHA512_BLOCK_SIZE/8; i++)
295 | pad[i] = keyPtr[i] ^ OPADLL;
296 |
297 | // Final hash
298 | CSHA512 c;
299 | c.WriteDirect128((unsigned char *)pad);
300 | c.WriteDirect64(ihash);
301 | c.Finalize(result);
302 |
303 | }
304 |
305 |
306 | void pbkdf2_hmac_sha512(uint8_t *out, size_t outlen,
307 | const uint8_t *passwd, size_t passlen,
308 | const uint8_t *salt, size_t saltlen,
309 | uint64_t iter) {
310 |
311 | CSHA512 hmac, hmac_template;
312 | uint32_t i, be32i;
313 | uint64_t j;
314 | int k;
315 |
316 | uint8_t key[SHA512_BLOCK_SIZE];
317 | uint8_t F[SHA512_HASH_LENGTH], U[SHA512_HASH_LENGTH];
318 | uint64_t *Fptr = (uint64_t *)F;
319 | uint64_t *Uptr = (uint64_t *)U;
320 | size_t need;
321 |
322 | if (passlen < SHA512_BLOCK_SIZE) {
323 | memcpy(key, passwd, passlen);
324 | memset(key + passlen, 0, SHA512_BLOCK_SIZE - passlen);
325 | } else {
326 | hmac.Write(passwd, passlen);
327 | hmac.Finalize(key);
328 | memset(key + SHA512_HASH_LENGTH, 0, SHA512_BLOCK_SIZE - SHA512_HASH_LENGTH);
329 | }
330 |
331 | hmac_sha512_init(hmac_template, key);
332 | hmac_template.Write(salt, saltlen);
333 |
334 | for (i = 1; outlen > 0; i++) {
335 |
336 | hmac = hmac_template;
337 | be32i = READBE32(i);
338 | hmac.Write((unsigned char *)&be32i, sizeof(be32i));
339 | hmac_sha512_done(hmac, key, U);
340 | memcpy(F, U, SHA512_HASH_LENGTH);
341 |
342 | for (j = 2; j <= iter; j++) {
343 | hmac_sha512_init(hmac, key);
344 | hmac.WriteDirect64(U);
345 | hmac_sha512_done(hmac, key, U);
346 | for (k = 0; k < SHA512_HASH_LENGTH/8; k++)
347 | Fptr[k] ^= Uptr[k];
348 | }
349 |
350 | need = MIN(SHA512_HASH_LENGTH, outlen);
351 |
352 | memcpy(out, F, need);
353 | out += need;
354 | outlen -= need;
355 |
356 | }
357 |
358 | }
359 |
360 | void hmac_sha512(unsigned char *key, int key_length, unsigned char *message, int message_length, unsigned char *digest) {
361 |
362 | uint8_t ipad[SHA512_BLOCK_SIZE];
363 | uint8_t opad[SHA512_BLOCK_SIZE];
364 | uint8_t hash[SHA512_HASH_LENGTH];
365 | int i;
366 |
367 | // TODO Handle key larger than 128
368 |
369 | for (i = 0; i < key_length && i < SHA512_BLOCK_SIZE; i++) {
370 | ipad[i] = key[i] ^ IPAD;
371 | opad[i] = key[i] ^ OPAD;
372 | }
373 | for (; i < SHA512_BLOCK_SIZE; i++) {
374 | ipad[i] = IPAD;
375 | opad[i] = OPAD;
376 | }
377 |
378 | CSHA512 h;
379 | h.WriteDirect128(ipad);
380 | h.Write(message, message_length);
381 | h.Finalize(hash);
382 |
383 | h.Initialize();
384 | h.WriteDirect128(opad);
385 | h.Write(hash, SHA512_HASH_LENGTH);
386 | h.Finalize(digest);
387 |
388 | }
389 |
390 | void sha512(unsigned char *input, int length, unsigned char *digest) {
391 |
392 | CSHA512 sha;
393 | sha.Write(input, length);
394 | sha.Finalize(digest);
395 |
396 | }
397 |
398 | std::string sha512_hex(unsigned char *digest) {
399 |
400 | char buf[2 * 64 + 1];
401 | buf[2 * 64] = 0;
402 | for (int i = 0; i < 64; i++)
403 | sprintf(buf + i * 2, "%02x", digest[i]);
404 | return std::string(buf);
405 |
406 | }
407 |
--------------------------------------------------------------------------------
/hash/ripemd160_sse.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include "ripemd160.h"
19 | #include
20 | #include
21 |
22 | // Internal SSE RIPEMD-160 implementation.
23 | namespace ripemd160sse {
24 |
25 | #ifdef WIN64
26 | static const __declspec(align(16)) uint32_t _init[] = {
27 | #else
28 | static const uint32_t _init[] __attribute__ ((aligned (16))) = {
29 | #endif
30 | 0x67452301ul,0x67452301ul,0x67452301ul,0x67452301ul,
31 | 0xEFCDAB89ul,0xEFCDAB89ul,0xEFCDAB89ul,0xEFCDAB89ul,
32 | 0x98BADCFEul,0x98BADCFEul,0x98BADCFEul,0x98BADCFEul,
33 | 0x10325476ul,0x10325476ul,0x10325476ul,0x10325476ul,
34 | 0xC3D2E1F0ul,0xC3D2E1F0ul,0xC3D2E1F0ul,0xC3D2E1F0ul
35 | };
36 |
37 | //#define f1(x, y, z) (x ^ y ^ z)
38 | //#define f2(x, y, z) ((x & y) | (~x & z))
39 | //#define f3(x, y, z) ((x | ~y) ^ z)
40 | //#define f4(x, y, z) ((x & z) | (~z & y))
41 | //#define f5(x, y, z) (x ^ (y | ~z))
42 |
43 | #define ROL(x,n) _mm_or_si128( _mm_slli_epi32(x, n) , _mm_srli_epi32(x, 32 - n) )
44 |
45 | #ifdef WIN64
46 |
47 | #define not(x) _mm_andnot_si128(x, _mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()))
48 | #define f1(x,y,z) _mm_xor_si128(x, _mm_xor_si128(y, z))
49 | #define f2(x,y,z) _mm_or_si128(_mm_and_si128(x,y),_mm_andnot_si128(x,z))
50 | #define f3(x,y,z) _mm_xor_si128(_mm_or_si128(x,not(y)),z)
51 | #define f4(x,y,z) _mm_or_si128(_mm_and_si128(x,z),_mm_andnot_si128(z,y))
52 | #define f5(x,y,z) _mm_xor_si128(x,_mm_or_si128(y,not(z)))
53 |
54 | #else
55 |
56 | #define f1(x,y,z) _mm_xor_si128(x, _mm_xor_si128(y, z))
57 | #define f2(x,y,z) _mm_or_si128(_mm_and_si128(x,y),_mm_andnot_si128(x,z))
58 | #define f3(x,y,z) _mm_xor_si128(_mm_or_si128(x,~(y)),z)
59 | #define f4(x,y,z) _mm_or_si128(_mm_and_si128(x,z),_mm_andnot_si128(z,y))
60 | #define f5(x,y,z) _mm_xor_si128(x,_mm_or_si128(y,~(z)))
61 |
62 | #endif
63 |
64 |
65 | #define add3(x0, x1, x2 ) _mm_add_epi32(_mm_add_epi32(x0, x1), x2)
66 | #define add4(x0, x1, x2, x3) _mm_add_epi32(_mm_add_epi32(x0, x1), _mm_add_epi32(x2, x3))
67 |
68 | #define Round(a,b,c,d,e,f,x,k,r) \
69 | u = add4(a,f,x,_mm_set1_epi32(k)); \
70 | a = _mm_add_epi32(ROL(u, r),e); \
71 | c = ROL(c, 10);
72 |
73 | #define R11(a,b,c,d,e,x,r) Round(a, b, c, d, e, f1(b, c, d), x, 0, r)
74 | #define R21(a,b,c,d,e,x,r) Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r)
75 | #define R31(a,b,c,d,e,x,r) Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r)
76 | #define R41(a,b,c,d,e,x,r) Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r)
77 | #define R51(a,b,c,d,e,x,r) Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r)
78 | #define R12(a,b,c,d,e,x,r) Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r)
79 | #define R22(a,b,c,d,e,x,r) Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r)
80 | #define R32(a,b,c,d,e,x,r) Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r)
81 | #define R42(a,b,c,d,e,x,r) Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r)
82 | #define R52(a,b,c,d,e,x,r) Round(a, b, c, d, e, f1(b, c, d), x, 0, r)
83 |
84 | #define LOADW(i) _mm_set_epi32(*((uint32_t *)blk[0]+i),*((uint32_t *)blk[1]+i),*((uint32_t *)blk[2]+i),*((uint32_t *)blk[3]+i))
85 |
86 | // Initialize RIPEMD-160 state
87 | void Initialize(__m128i *s) {
88 | memcpy(s, _init, sizeof(_init));
89 | }
90 |
91 | // Perform 4 RIPE in parallel using SSE2
92 | void Transform(__m128i *s, uint8_t *blk[4]) {
93 |
94 | __m128i a1 = _mm_load_si128(s + 0);
95 | __m128i b1 = _mm_load_si128(s + 1);
96 | __m128i c1 = _mm_load_si128(s + 2);
97 | __m128i d1 = _mm_load_si128(s + 3);
98 | __m128i e1 = _mm_load_si128(s + 4);
99 | __m128i a2 = a1;
100 | __m128i b2 = b1;
101 | __m128i c2 = c1;
102 | __m128i d2 = d1;
103 | __m128i e2 = e1;
104 | __m128i u;
105 | __m128i w[16];
106 |
107 |
108 | w[0] = LOADW(0);
109 | w[1] = LOADW(1);
110 | w[2] = LOADW(2);
111 | w[3] = LOADW(3);
112 | w[4] = LOADW(4);
113 | w[5] = LOADW(5);
114 | w[6] = LOADW(6);
115 | w[7] = LOADW(7);
116 | w[8] = LOADW(8);
117 | w[9] = LOADW(9);
118 | w[10] = LOADW(10);
119 | w[11] = LOADW(11);
120 | w[12] = LOADW(12);
121 | w[13] = LOADW(13);
122 | w[14] = LOADW(14);
123 | w[15] = LOADW(15);
124 |
125 | R11(a1, b1, c1, d1, e1, w[0], 11);
126 | R12(a2, b2, c2, d2, e2, w[5], 8);
127 | R11(e1, a1, b1, c1, d1, w[1], 14);
128 | R12(e2, a2, b2, c2, d2, w[14], 9);
129 | R11(d1, e1, a1, b1, c1, w[2], 15);
130 | R12(d2, e2, a2, b2, c2, w[7], 9);
131 | R11(c1, d1, e1, a1, b1, w[3], 12);
132 | R12(c2, d2, e2, a2, b2, w[0], 11);
133 | R11(b1, c1, d1, e1, a1, w[4], 5);
134 | R12(b2, c2, d2, e2, a2, w[9], 13);
135 | R11(a1, b1, c1, d1, e1, w[5], 8);
136 | R12(a2, b2, c2, d2, e2, w[2], 15);
137 | R11(e1, a1, b1, c1, d1, w[6], 7);
138 | R12(e2, a2, b2, c2, d2, w[11], 15);
139 | R11(d1, e1, a1, b1, c1, w[7], 9);
140 | R12(d2, e2, a2, b2, c2, w[4], 5);
141 | R11(c1, d1, e1, a1, b1, w[8], 11);
142 | R12(c2, d2, e2, a2, b2, w[13], 7);
143 | R11(b1, c1, d1, e1, a1, w[9], 13);
144 | R12(b2, c2, d2, e2, a2, w[6], 7);
145 | R11(a1, b1, c1, d1, e1, w[10], 14);
146 | R12(a2, b2, c2, d2, e2, w[15], 8);
147 | R11(e1, a1, b1, c1, d1, w[11], 15);
148 | R12(e2, a2, b2, c2, d2, w[8], 11);
149 | R11(d1, e1, a1, b1, c1, w[12], 6);
150 | R12(d2, e2, a2, b2, c2, w[1], 14);
151 | R11(c1, d1, e1, a1, b1, w[13], 7);
152 | R12(c2, d2, e2, a2, b2, w[10], 14);
153 | R11(b1, c1, d1, e1, a1, w[14], 9);
154 | R12(b2, c2, d2, e2, a2, w[3], 12);
155 | R11(a1, b1, c1, d1, e1, w[15], 8);
156 | R12(a2, b2, c2, d2, e2, w[12], 6);
157 |
158 | R21(e1, a1, b1, c1, d1, w[7], 7);
159 | R22(e2, a2, b2, c2, d2, w[6], 9);
160 | R21(d1, e1, a1, b1, c1, w[4], 6);
161 | R22(d2, e2, a2, b2, c2, w[11], 13);
162 | R21(c1, d1, e1, a1, b1, w[13], 8);
163 | R22(c2, d2, e2, a2, b2, w[3], 15);
164 | R21(b1, c1, d1, e1, a1, w[1], 13);
165 | R22(b2, c2, d2, e2, a2, w[7], 7);
166 | R21(a1, b1, c1, d1, e1, w[10], 11);
167 | R22(a2, b2, c2, d2, e2, w[0], 12);
168 | R21(e1, a1, b1, c1, d1, w[6], 9);
169 | R22(e2, a2, b2, c2, d2, w[13], 8);
170 | R21(d1, e1, a1, b1, c1, w[15], 7);
171 | R22(d2, e2, a2, b2, c2, w[5], 9);
172 | R21(c1, d1, e1, a1, b1, w[3], 15);
173 | R22(c2, d2, e2, a2, b2, w[10], 11);
174 | R21(b1, c1, d1, e1, a1, w[12], 7);
175 | R22(b2, c2, d2, e2, a2, w[14], 7);
176 | R21(a1, b1, c1, d1, e1, w[0], 12);
177 | R22(a2, b2, c2, d2, e2, w[15], 7);
178 | R21(e1, a1, b1, c1, d1, w[9], 15);
179 | R22(e2, a2, b2, c2, d2, w[8], 12);
180 | R21(d1, e1, a1, b1, c1, w[5], 9);
181 | R22(d2, e2, a2, b2, c2, w[12], 7);
182 | R21(c1, d1, e1, a1, b1, w[2], 11);
183 | R22(c2, d2, e2, a2, b2, w[4], 6);
184 | R21(b1, c1, d1, e1, a1, w[14], 7);
185 | R22(b2, c2, d2, e2, a2, w[9], 15);
186 | R21(a1, b1, c1, d1, e1, w[11], 13);
187 | R22(a2, b2, c2, d2, e2, w[1], 13);
188 | R21(e1, a1, b1, c1, d1, w[8], 12);
189 | R22(e2, a2, b2, c2, d2, w[2], 11);
190 |
191 | R31(d1, e1, a1, b1, c1, w[3], 11);
192 | R32(d2, e2, a2, b2, c2, w[15], 9);
193 | R31(c1, d1, e1, a1, b1, w[10], 13);
194 | R32(c2, d2, e2, a2, b2, w[5], 7);
195 | R31(b1, c1, d1, e1, a1, w[14], 6);
196 | R32(b2, c2, d2, e2, a2, w[1], 15);
197 | R31(a1, b1, c1, d1, e1, w[4], 7);
198 | R32(a2, b2, c2, d2, e2, w[3], 11);
199 | R31(e1, a1, b1, c1, d1, w[9], 14);
200 | R32(e2, a2, b2, c2, d2, w[7], 8);
201 | R31(d1, e1, a1, b1, c1, w[15], 9);
202 | R32(d2, e2, a2, b2, c2, w[14], 6);
203 | R31(c1, d1, e1, a1, b1, w[8], 13);
204 | R32(c2, d2, e2, a2, b2, w[6], 6);
205 | R31(b1, c1, d1, e1, a1, w[1], 15);
206 | R32(b2, c2, d2, e2, a2, w[9], 14);
207 | R31(a1, b1, c1, d1, e1, w[2], 14);
208 | R32(a2, b2, c2, d2, e2, w[11], 12);
209 | R31(e1, a1, b1, c1, d1, w[7], 8);
210 | R32(e2, a2, b2, c2, d2, w[8], 13);
211 | R31(d1, e1, a1, b1, c1, w[0], 13);
212 | R32(d2, e2, a2, b2, c2, w[12], 5);
213 | R31(c1, d1, e1, a1, b1, w[6], 6);
214 | R32(c2, d2, e2, a2, b2, w[2], 14);
215 | R31(b1, c1, d1, e1, a1, w[13], 5);
216 | R32(b2, c2, d2, e2, a2, w[10], 13);
217 | R31(a1, b1, c1, d1, e1, w[11], 12);
218 | R32(a2, b2, c2, d2, e2, w[0], 13);
219 | R31(e1, a1, b1, c1, d1, w[5], 7);
220 | R32(e2, a2, b2, c2, d2, w[4], 7);
221 | R31(d1, e1, a1, b1, c1, w[12], 5);
222 | R32(d2, e2, a2, b2, c2, w[13], 5);
223 |
224 | R41(c1, d1, e1, a1, b1, w[1], 11);
225 | R42(c2, d2, e2, a2, b2, w[8], 15);
226 | R41(b1, c1, d1, e1, a1, w[9], 12);
227 | R42(b2, c2, d2, e2, a2, w[6], 5);
228 | R41(a1, b1, c1, d1, e1, w[11], 14);
229 | R42(a2, b2, c2, d2, e2, w[4], 8);
230 | R41(e1, a1, b1, c1, d1, w[10], 15);
231 | R42(e2, a2, b2, c2, d2, w[1], 11);
232 | R41(d1, e1, a1, b1, c1, w[0], 14);
233 | R42(d2, e2, a2, b2, c2, w[3], 14);
234 | R41(c1, d1, e1, a1, b1, w[8], 15);
235 | R42(c2, d2, e2, a2, b2, w[11], 14);
236 | R41(b1, c1, d1, e1, a1, w[12], 9);
237 | R42(b2, c2, d2, e2, a2, w[15], 6);
238 | R41(a1, b1, c1, d1, e1, w[4], 8);
239 | R42(a2, b2, c2, d2, e2, w[0], 14);
240 | R41(e1, a1, b1, c1, d1, w[13], 9);
241 | R42(e2, a2, b2, c2, d2, w[5], 6);
242 | R41(d1, e1, a1, b1, c1, w[3], 14);
243 | R42(d2, e2, a2, b2, c2, w[12], 9);
244 | R41(c1, d1, e1, a1, b1, w[7], 5);
245 | R42(c2, d2, e2, a2, b2, w[2], 12);
246 | R41(b1, c1, d1, e1, a1, w[15], 6);
247 | R42(b2, c2, d2, e2, a2, w[13], 9);
248 | R41(a1, b1, c1, d1, e1, w[14], 8);
249 | R42(a2, b2, c2, d2, e2, w[9], 12);
250 | R41(e1, a1, b1, c1, d1, w[5], 6);
251 | R42(e2, a2, b2, c2, d2, w[7], 5);
252 | R41(d1, e1, a1, b1, c1, w[6], 5);
253 | R42(d2, e2, a2, b2, c2, w[10], 15);
254 | R41(c1, d1, e1, a1, b1, w[2], 12);
255 | R42(c2, d2, e2, a2, b2, w[14], 8);
256 |
257 | R51(b1, c1, d1, e1, a1, w[4], 9);
258 | R52(b2, c2, d2, e2, a2, w[12], 8);
259 | R51(a1, b1, c1, d1, e1, w[0], 15);
260 | R52(a2, b2, c2, d2, e2, w[15], 5);
261 | R51(e1, a1, b1, c1, d1, w[5], 5);
262 | R52(e2, a2, b2, c2, d2, w[10], 12);
263 | R51(d1, e1, a1, b1, c1, w[9], 11);
264 | R52(d2, e2, a2, b2, c2, w[4], 9);
265 | R51(c1, d1, e1, a1, b1, w[7], 6);
266 | R52(c2, d2, e2, a2, b2, w[1], 12);
267 | R51(b1, c1, d1, e1, a1, w[12], 8);
268 | R52(b2, c2, d2, e2, a2, w[5], 5);
269 | R51(a1, b1, c1, d1, e1, w[2], 13);
270 | R52(a2, b2, c2, d2, e2, w[8], 14);
271 | R51(e1, a1, b1, c1, d1, w[10], 12);
272 | R52(e2, a2, b2, c2, d2, w[7], 6);
273 | R51(d1, e1, a1, b1, c1, w[14], 5);
274 | R52(d2, e2, a2, b2, c2, w[6], 8);
275 | R51(c1, d1, e1, a1, b1, w[1], 12);
276 | R52(c2, d2, e2, a2, b2, w[2], 13);
277 | R51(b1, c1, d1, e1, a1, w[3], 13);
278 | R52(b2, c2, d2, e2, a2, w[13], 6);
279 | R51(a1, b1, c1, d1, e1, w[8], 14);
280 | R52(a2, b2, c2, d2, e2, w[14], 5);
281 | R51(e1, a1, b1, c1, d1, w[11], 11);
282 | R52(e2, a2, b2, c2, d2, w[0], 15);
283 | R51(d1, e1, a1, b1, c1, w[6], 8);
284 | R52(d2, e2, a2, b2, c2, w[3], 13);
285 | R51(c1, d1, e1, a1, b1, w[15], 5);
286 | R52(c2, d2, e2, a2, b2, w[9], 11);
287 | R51(b1, c1, d1, e1, a1, w[13], 6);
288 | R52(b2, c2, d2, e2, a2, w[11], 11);
289 |
290 | __m128i t = s[0];
291 | s[0] = add3(s[1],c1,d2);
292 | s[1] = add3(s[2],d1,e2);
293 | s[2] = add3(s[3],e1,a2);
294 | s[3] = add3(s[4],a1,b2);
295 | s[4] = add3(t,b1,c2);
296 | }
297 |
298 | } // namespace ripemd160sse
299 |
300 | #ifdef WIN64
301 |
302 | #define DEPACK(d,i) \
303 | ((uint32_t *)d)[0] = s[0].m128i_u32[i]; \
304 | ((uint32_t *)d)[1] = s[1].m128i_u32[i]; \
305 | ((uint32_t *)d)[2] = s[2].m128i_u32[i]; \
306 | ((uint32_t *)d)[3] = s[3].m128i_u32[i]; \
307 | ((uint32_t *)d)[4] = s[4].m128i_u32[i];
308 |
309 | #else
310 |
311 | #define DEPACK(d,i) \
312 | ((uint32_t *)d)[0] = s0[i]; \
313 | ((uint32_t *)d)[1] = s1[i]; \
314 | ((uint32_t *)d)[2] = s2[i]; \
315 | ((uint32_t *)d)[3] = s3[i]; \
316 | ((uint32_t *)d)[4] = s4[i];
317 |
318 | #endif
319 |
320 | static const uint64_t sizedesc_32 = 32 << 3;
321 | static const unsigned char pad[64] = { 0x80 };
322 |
323 | void ripemd160sse_32(
324 | unsigned char *i0,
325 | unsigned char *i1,
326 | unsigned char *i2,
327 | unsigned char *i3,
328 | unsigned char *d0,
329 | unsigned char *d1,
330 | unsigned char *d2,
331 | unsigned char *d3) {
332 |
333 | __m128i s[5];
334 | uint8_t *bs[] = { i0,i1,i2,i3 };
335 |
336 | ripemd160sse::Initialize(s);
337 | memcpy(i0 + 32, pad, 24);
338 | memcpy(i0 + 56, &sizedesc_32, 8);
339 | memcpy(i1 + 32, pad, 24);
340 | memcpy(i1 + 56, &sizedesc_32, 8);
341 | memcpy(i2 + 32, pad, 24);
342 | memcpy(i2 + 56, &sizedesc_32, 8);
343 | memcpy(i3 + 32, pad, 24);
344 | memcpy(i3 + 56, &sizedesc_32, 8);
345 |
346 | ripemd160sse::Transform(s, bs);
347 |
348 | #ifndef WIN64
349 | uint32_t *s0 = (uint32_t *)&s[0];
350 | uint32_t *s1 = (uint32_t *)&s[1];
351 | uint32_t *s2 = (uint32_t *)&s[2];
352 | uint32_t *s3 = (uint32_t *)&s[3];
353 | uint32_t *s4 = (uint32_t *)&s[4];
354 | #endif
355 |
356 | DEPACK(d0,3);
357 | DEPACK(d1,2);
358 | DEPACK(d2,1);
359 | DEPACK(d3,0);
360 |
361 | }
362 |
363 | void ripemd160sse_test() {
364 |
365 | unsigned char h0[20];
366 | unsigned char h1[20];
367 | unsigned char h2[20];
368 | unsigned char h3[20];
369 | unsigned char ch0[20];
370 | unsigned char ch1[20];
371 | unsigned char ch2[20];
372 | unsigned char ch3[20];
373 | unsigned char m0[64];
374 | unsigned char m1[64];
375 | unsigned char m2[64];
376 | unsigned char m3[64];
377 |
378 | strcpy((char *)m0, "This is a test message to test01");
379 | strcpy((char *)m1, "This is a test message to test02");
380 | strcpy((char *)m2, "This is a test message to test03");
381 | strcpy((char *)m3, "This is a test message to test04");
382 |
383 | ripemd160_32(m0, ch0);
384 | ripemd160_32(m1, ch1);
385 | ripemd160_32(m2, ch2);
386 | ripemd160_32(m3, ch3);
387 |
388 | ripemd160sse_32(m0, m1, m2, m3, h0, h1, h2, h3);
389 |
390 | if ((ripemd160_hex(h0) != ripemd160_hex(ch0)) ||
391 | (ripemd160_hex(h1) != ripemd160_hex(ch1)) ||
392 | (ripemd160_hex(h2) != ripemd160_hex(ch2)) ||
393 | (ripemd160_hex(h3) != ripemd160_hex(ch3))) {
394 |
395 | printf("RIPEMD160() Results Wrong !\n");
396 | printf("RIP: %s\n", ripemd160_hex(ch0).c_str());
397 | printf("RIP: %s\n", ripemd160_hex(ch1).c_str());
398 | printf("RIP: %s\n", ripemd160_hex(ch2).c_str());
399 | printf("RIP: %s\n\n", ripemd160_hex(ch3).c_str());
400 | printf("SSE: %s\n", ripemd160_hex(h0).c_str());
401 | printf("SSE: %s\n", ripemd160_hex(h1).c_str());
402 | printf("SSE: %s\n", ripemd160_hex(h2).c_str());
403 | printf("SSE: %s\n\n", ripemd160_hex(h3).c_str());
404 |
405 | }
406 |
407 | printf("RIPE() Results OK !\n");
408 |
409 | }
410 |
--------------------------------------------------------------------------------
/GPU/GPUEngine.cu:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef WIN64
19 | #include
20 | #include
21 | #endif
22 |
23 | #include "GPUEngine.h"
24 | #include
25 | #include
26 |
27 | #include
28 | #include "../hash/sha256.h"
29 | #include "../hash/ripemd160.h"
30 | #include "../Timer.h"
31 |
32 | #include "GPUMath.h"
33 | #include "GPUHash.h"
34 | #include "GPUCompute.h"
35 |
36 | // ---------------------------------------------------------------------------------------
37 |
38 | __global__ void comp_hash(uint64_t *keys, uint64_t *hashes, uint32_t maxFound, uint32_t *found, uint64_t dpMask, uint16_t colMask, uint16_t nbFull, bool extraPoints) {
39 |
40 | int xPtr = (blockIdx.x*blockDim.x*GPU_GRP_SIZE) * 6;
41 | ComputeHash(keys, hashes + xPtr, maxFound, found, dpMask, colMask, nbFull, extraPoints);
42 |
43 | }
44 |
45 | __global__ void comp_hash_p2sh(uint64_t *keys, uint64_t *hashes, uint32_t maxFound, uint32_t *found, uint64_t dpMask, uint16_t colMask, uint16_t nbFull, bool extraPoints) {
46 |
47 | int xPtr = (blockIdx.x*blockDim.x*GPU_GRP_SIZE) * 6;
48 | ComputeHashP2SH(keys, hashes + xPtr, maxFound, found, dpMask, colMask, nbFull, extraPoints);
49 |
50 | }
51 |
52 | // ---------------------------------------------------------------------------------------
53 |
54 | using namespace std;
55 |
56 | int _ConvertSMVer2Cores(int major, int minor) {
57 |
58 | // Defines for GPU Architecture types (using the SM version to determine
59 | // the # of cores per SM
60 | typedef struct {
61 | int SM; // 0xMm (hexidecimal notation), M = SM Major version,
62 | // and m = SM minor version
63 | int Cores;
64 | } sSMtoCores;
65 |
66 | sSMtoCores nGpuArchCoresPerSM[] = {
67 | {0x20, 32}, // Fermi Generation (SM 2.0) GF100 class
68 | {0x21, 48}, // Fermi Generation (SM 2.1) GF10x class
69 | {0x30, 192},
70 | {0x32, 192},
71 | {0x35, 192},
72 | {0x37, 192},
73 | {0x50, 128},
74 | {0x52, 128},
75 | {0x53, 128},
76 | {0x60, 64},
77 | {0x61, 128},
78 | {0x62, 128},
79 | {0x70, 64},
80 | {0x72, 64},
81 | {0x75, 64},
82 | {-1, -1} };
83 |
84 | int index = 0;
85 |
86 | while (nGpuArchCoresPerSM[index].SM != -1) {
87 | if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor)) {
88 | return nGpuArchCoresPerSM[index].Cores;
89 | }
90 |
91 | index++;
92 | }
93 |
94 | return 0;
95 |
96 | }
97 |
98 | GPUEngine::GPUEngine(int nbThreadGroup, int nbThreadPerGroup, int gpuId, uint32_t maxFound) {
99 |
100 | // Initialise CUDA
101 | this->nbThreadPerGroup = nbThreadPerGroup;
102 | initialised = false;
103 | cudaError_t err;
104 |
105 | int deviceCount = 0;
106 | cudaError_t error_id = cudaGetDeviceCount(&deviceCount);
107 |
108 | if (error_id != cudaSuccess) {
109 | printf("GPUEngine: CudaGetDeviceCount %s\n", cudaGetErrorString(error_id));
110 | return;
111 | }
112 |
113 | // This function call returns 0 if there are no CUDA capable devices.
114 | if (deviceCount == 0) {
115 | printf("GPUEngine: There are no available device(s) that support CUDA\n");
116 | return;
117 | }
118 |
119 | err = cudaSetDevice(gpuId);
120 | if (err != cudaSuccess) {
121 | printf("GPUEngine: %s\n", cudaGetErrorString(err));
122 | return;
123 | }
124 |
125 | cudaDeviceProp deviceProp;
126 | cudaGetDeviceProperties(&deviceProp, gpuId);
127 |
128 | this->nbThread = nbThreadGroup * nbThreadPerGroup;
129 | this->maxFound = maxFound;
130 | this->outputSize = (maxFound*ITEM_SIZE + 4);
131 |
132 | char tmp[512];
133 | sprintf(tmp,"GPU #%d %s (%dx%d cores) Grid(%dx%d)",
134 | gpuId,deviceProp.name,deviceProp.multiProcessorCount,
135 | _ConvertSMVer2Cores(deviceProp.major, deviceProp.minor),
136 | nbThread / nbThreadPerGroup,
137 | nbThreadPerGroup);
138 | deviceName = std::string(tmp);
139 |
140 | // Prefer L1 (We do not use __shared__ at all)
141 | err = cudaDeviceSetCacheConfig(cudaFuncCachePreferL1);
142 | if (err != cudaSuccess) {
143 | printf("GPUEngine: %s\n", cudaGetErrorString(err));
144 | return;
145 | }
146 |
147 | /*
148 | size_t stackSize = 49152;
149 | err = cudaDeviceSetLimit(cudaLimitStackSize, stackSize);
150 | if (err != cudaSuccess) {
151 | printf("GPUEngine: %s\n", cudaGetErrorString(err));
152 | return;
153 | }
154 |
155 | size_t heapSize = ;
156 | err = cudaDeviceSetLimit(cudaLimitMallocHeapSize, heapSize);
157 | if (err != cudaSuccess) {
158 | printf("Error: %s\n", cudaGetErrorString(err));
159 | exit(0);
160 | }
161 |
162 | size_t size;
163 | cudaDeviceGetLimit(&size, cudaLimitStackSize);
164 | printf("Stack Size %lld\n", size);
165 | cudaDeviceGetLimit(&size, cudaLimitMallocHeapSize);
166 | printf("Heap Size %lld\n", size);
167 | */
168 |
169 | // Allocate memory
170 | inputKey = NULL;
171 | inputKeyPinned = NULL;
172 | outputHash = NULL;
173 | outputHashPinned = NULL;
174 | inputHash = NULL;
175 | inputHashPinned = NULL;
176 |
177 | // Input keys (see BTCCollider.cpp)
178 | keySize = 10 * _64K * 32 * 2;
179 | err = cudaMalloc((void **)&inputKey, keySize);
180 | if (err != cudaSuccess) {
181 | printf("GPUEngine: Allocate input memory: %s\n", cudaGetErrorString(err));
182 | return;
183 | }
184 | err = cudaHostAlloc(&inputKeyPinned, keySize, cudaHostAllocWriteCombined | cudaHostAllocMapped);
185 | if (err != cudaSuccess) {
186 | printf("GPUEngine: Allocate input pinned memory: %s\n", cudaGetErrorString(err));
187 | return;
188 | }
189 | // OutputHash
190 | err = cudaMalloc((void **)&outputHash, outputSize);
191 | if (err != cudaSuccess) {
192 | printf("GPUEngine: Allocate output memory: %s\n", cudaGetErrorString(err));
193 | return;
194 | }
195 | err = cudaHostAlloc(&outputHashPinned, outputSize, cudaHostAllocMapped);
196 | if (err != cudaSuccess) {
197 | printf("GPUEngine: Allocate output pinned memory: %s\n", cudaGetErrorString(err));
198 | return;
199 | }
200 | // InputHash (hash160 sotred on 3*64bit)
201 | inputHashSize = GPU_GRP_SIZE * nbThread * 48;
202 | err = cudaMalloc((void **)&inputHash, inputHashSize);
203 | if (err != cudaSuccess) {
204 | printf("GPUEngine: Allocate output memory: %s\n", cudaGetErrorString(err));
205 | return;
206 | }
207 | err = cudaHostAlloc(&inputHashPinned, inputHashSize, cudaHostAllocWriteCombined | cudaHostAllocMapped);
208 | if (err != cudaSuccess) {
209 | printf("GPUEngine: Allocate output pinned memory: %s\n", cudaGetErrorString(err));
210 | return;
211 | }
212 |
213 | searchType = P2PKH;
214 | initialised = true;
215 | useExtraPoints = false;
216 |
217 |
218 | }
219 |
220 | GPUEngine::~GPUEngine() {
221 |
222 | if(inputKey) cudaFree(inputKey);
223 | if(inputHash) cudaFree(inputHash);
224 | if(outputHash) cudaFree(outputHash);
225 | if(inputKeyPinned) cudaFreeHost(inputKeyPinned);
226 | if(inputHashPinned) cudaFreeHost(inputHashPinned);
227 | if(outputHashPinned) cudaFreeHost(outputHashPinned);
228 |
229 | }
230 |
231 |
232 | int GPUEngine::GetMemory() {
233 | return keySize + inputHashSize + outputSize;
234 | }
235 |
236 |
237 | int GPUEngine::GetGroupSize() {
238 | return GPU_GRP_SIZE;
239 | }
240 |
241 | bool GPUEngine::GetGridSize(int gpuId, int *x, int *y) {
242 |
243 | if ( *x <= 0 || *y <= 0 ) {
244 |
245 | int deviceCount = 0;
246 | cudaError_t error_id = cudaGetDeviceCount(&deviceCount);
247 |
248 | if (error_id != cudaSuccess) {
249 | printf("GPUEngine: CudaGetDeviceCount %s\n", cudaGetErrorString(error_id));
250 | return false;
251 | }
252 |
253 | // This function call returns 0 if there are no CUDA capable devices.
254 | if (deviceCount == 0) {
255 | printf("GPUEngine: There are no available device(s) that support CUDA\n");
256 | return false;
257 | }
258 |
259 | if (gpuId >= deviceCount) {
260 | printf("GPUEngine::GetGridSize() Invalid gpuId\n");
261 | return false;
262 | }
263 |
264 | cudaDeviceProp deviceProp;
265 | cudaGetDeviceProperties(&deviceProp, gpuId);
266 |
267 | if(*x<=0) *x = 2 * deviceProp.multiProcessorCount;
268 | if(*y<=0) *y = 2 * _ConvertSMVer2Cores(deviceProp.major, deviceProp.minor);
269 | if(*y<=0) *y = 128;
270 |
271 | }
272 |
273 | return true;
274 |
275 | }
276 |
277 | void *GPUEngine::AllocatePinnedMemory(size_t size) {
278 |
279 | void *buff;
280 |
281 | cudaError_t err = cudaHostAlloc(&buff, size, cudaHostAllocPortable);
282 | if (err != cudaSuccess) {
283 | printf("GPUEngine: AllocatePinnedMemory: %s\n", cudaGetErrorString(err));
284 | return NULL;
285 | }
286 |
287 | return buff;
288 |
289 | }
290 |
291 | void GPUEngine::FreePinnedMemory(void *buff) {
292 | cudaFreeHost(buff);
293 | }
294 |
295 | void GPUEngine::PrintCudaInfo() {
296 |
297 | cudaError_t err;
298 |
299 | const char *sComputeMode[] =
300 | {
301 | "Multiple host threads",
302 | "Only one host thread",
303 | "No host thread",
304 | "Multiple process threads",
305 | "Unknown",
306 | NULL
307 | };
308 |
309 | int deviceCount = 0;
310 | cudaError_t error_id = cudaGetDeviceCount(&deviceCount);
311 |
312 | if (error_id != cudaSuccess) {
313 | printf("GPUEngine: CudaGetDeviceCount %s\n", cudaGetErrorString(error_id));
314 | return;
315 | }
316 |
317 | // This function call returns 0 if there are no CUDA capable devices.
318 | if (deviceCount == 0) {
319 | printf("GPUEngine: There are no available device(s) that support CUDA\n");
320 | return;
321 | }
322 |
323 | for(int i=0;isearchType = searchType;
353 | }
354 |
355 | bool GPUEngine::GetHashes(uint64_t *sHash, uint64_t *cHash) {
356 |
357 | // Retrieve hash from device memory
358 | cudaMemcpy(inputHashPinned, inputHash, inputHashSize, cudaMemcpyDeviceToHost);
359 |
360 | cudaError_t err = cudaGetLastError();
361 | if (err != cudaSuccess) {
362 | printf("GPUEngine: GetHashes: %s\n", cudaGetErrorString(err));
363 | return false;
364 | }
365 |
366 | int gSize = 6 * GPU_GRP_SIZE;
367 | int strideSize = nbThreadPerGroup * 6;
368 | int nbBlock = nbThread / nbThreadPerGroup;
369 | int blockSize = nbThreadPerGroup * gSize;
370 |
371 | for (int b = 0; b < nbBlock; b++) {
372 | for (int g = 0; g < GPU_GRP_SIZE; g++) {
373 | for (int t = 0; t < nbThreadPerGroup; t++) {
374 | // Current hash
375 | cHash[0] = inputHashPinned[b * blockSize + g * strideSize + t + 0 * nbThreadPerGroup];
376 | cHash[1] = inputHashPinned[b * blockSize + g * strideSize + t + 1 * nbThreadPerGroup];
377 | cHash[2] = inputHashPinned[b * blockSize + g * strideSize + t + 2 * nbThreadPerGroup];
378 | // Start hash
379 | sHash[0] = inputHashPinned[b * blockSize + g * strideSize + t + 3 * nbThreadPerGroup];
380 | sHash[1] = inputHashPinned[b * blockSize + g * strideSize + t + 4 * nbThreadPerGroup];
381 | sHash[2] = inputHashPinned[b * blockSize + g * strideSize + t + 5 * nbThreadPerGroup];
382 | cHash += 3;
383 | sHash += 3;
384 | }
385 | }
386 | }
387 |
388 | return true;
389 |
390 | }
391 |
392 | bool GPUEngine::SetStartingHashes(uint64_t *sHash, uint64_t *cHash) {
393 |
394 | lostWarning = false;
395 |
396 | // Sets the starting hash of each thread
397 | int gSize = 6 * GPU_GRP_SIZE;
398 | int strideSize = nbThreadPerGroup * 6;
399 | int nbBlock = nbThread / nbThreadPerGroup;
400 | int blockSize = nbThreadPerGroup * gSize;
401 |
402 | for (int b = 0; b < nbBlock; b++) {
403 | for (int g = 0; g < GPU_GRP_SIZE; g++) {
404 | for (int t = 0; t < nbThreadPerGroup; t++) {
405 | // Current hash
406 | inputHashPinned[b * blockSize + g * strideSize + t + 0* nbThreadPerGroup] = cHash[0];
407 | inputHashPinned[b * blockSize + g * strideSize + t + 1* nbThreadPerGroup] = cHash[1];
408 | inputHashPinned[b * blockSize + g * strideSize + t + 2* nbThreadPerGroup] = cHash[2];
409 | // Start hash
410 | inputHashPinned[b * blockSize + g * strideSize + t + 3 * nbThreadPerGroup] = sHash[0];
411 | inputHashPinned[b * blockSize + g * strideSize + t + 4 * nbThreadPerGroup] = sHash[1];
412 | inputHashPinned[b * blockSize + g * strideSize + t + 5 * nbThreadPerGroup] = sHash[2];
413 | cHash += 3;
414 | sHash += 3;
415 | }
416 | }
417 | }
418 |
419 | // Fill device memory
420 | cudaMemcpy(inputHash, inputHashPinned, inputHashSize, cudaMemcpyHostToDevice);
421 |
422 | cudaError_t err = cudaGetLastError();
423 | if (err != cudaSuccess) {
424 | printf("GPUEngine: SetStartHashes: %s\n", cudaGetErrorString(err));
425 | }
426 |
427 | return callKernel();
428 |
429 | }
430 |
431 | bool GPUEngine::callKernel() {
432 |
433 | // Reset nbFound
434 | cudaMemset(outputHash,0,4);
435 |
436 | // Call the kernel (Perform STEP_SIZE keys per thread)
437 | if (searchType == P2SH) {
438 |
439 | comp_hash_p2sh << < nbThread / nbThreadPerGroup, nbThreadPerGroup >> >
440 | (inputKey, inputHash, maxFound, outputHash, dpMask, colMask, nbFull, useExtraPoints);
441 |
442 | } else {
443 |
444 | // P2PKH or BECH32
445 | comp_hash << < nbThread / nbThreadPerGroup, nbThreadPerGroup >> >
446 | (inputKey, inputHash, maxFound, outputHash, dpMask, colMask, nbFull, useExtraPoints);
447 |
448 | }
449 |
450 | cudaError_t err = cudaGetLastError();
451 | if (err != cudaSuccess) {
452 | printf("GPUEngine: Kernel: %s\n", cudaGetErrorString(err));
453 | return false;
454 | }
455 | return true;
456 |
457 | }
458 |
459 | void GPUEngine::SetMasks(uint16_t colMask, uint64_t dpMask, uint16_t nbFull) {
460 | this->colMask = colMask;
461 | this->dpMask = dpMask;
462 | this->nbFull = nbFull;
463 | }
464 |
465 | #define PX(i,j) p[(i)*(65536*2) + 2*(j)]
466 | #define PY(i,j) p[(i)*(65536*2) + 2*(j)+1]
467 |
468 | void GPUEngine::SetKeys(Int *p) {
469 |
470 | // Sets the base keys for mapping
471 |
472 | for (int i = 0; i < 10; i++) {
473 | for (int j = 0; j < 65536; j++) {
474 |
475 | inputKeyPinned[8 * ((i*_64K) + j) + 0] = PX(i, j).bits64[0];
476 | inputKeyPinned[8 * ((i*_64K) + j) + 1] = PX(i, j).bits64[1];
477 | inputKeyPinned[8 * ((i*_64K) + j) + 2] = PX(i, j).bits64[2];
478 | inputKeyPinned[8 * ((i*_64K) + j) + 3] = PX(i, j).bits64[3];
479 |
480 | inputKeyPinned[8 * ((i*_64K) + j) + 4] = PY(i, j).bits64[0];
481 | inputKeyPinned[8 * ((i*_64K) + j) + 5] = PY(i, j).bits64[1];
482 | inputKeyPinned[8 * ((i*_64K) + j) + 6] = PY(i, j).bits64[2];
483 | inputKeyPinned[8 * ((i*_64K) + j) + 7] = PY(i, j).bits64[3];
484 |
485 | }
486 | }
487 |
488 | // Fill device memory
489 | cudaMemcpy(inputKey, inputKeyPinned, keySize, cudaMemcpyHostToDevice);
490 |
491 | // We do not need the key pinned memory anymore
492 | cudaFreeHost(inputKeyPinned);
493 | inputKeyPinned = NULL;
494 |
495 | cudaError_t err = cudaGetLastError();
496 | if (err != cudaSuccess) {
497 | printf("GPUEngine: SetKeys: %s\n", cudaGetErrorString(err));
498 | }
499 |
500 | }
501 |
502 | bool GPUEngine::Launch(std::vector
- &hashFound,bool spinWait) {
503 |
504 |
505 | hashFound.clear();
506 |
507 | // Get the result
508 |
509 | if(spinWait) {
510 |
511 | cudaMemcpy(outputHashPinned, outputHash, outputSize, cudaMemcpyDeviceToHost);
512 |
513 | } else {
514 |
515 | // Use cudaMemcpyAsync to avoid default spin wait of cudaMemcpy wich takes 100% CPU
516 | cudaEvent_t evt;
517 | cudaEventCreate(&evt);
518 | cudaMemcpyAsync(outputHashPinned, outputHash, 4, cudaMemcpyDeviceToHost, 0);
519 | cudaEventRecord(evt, 0);
520 | while (cudaEventQuery(evt) == cudaErrorNotReady) {
521 | // Sleep 1 ms to free the CPU
522 | Timer::SleepMillis(1);
523 | }
524 | cudaEventDestroy(evt);
525 |
526 | }
527 |
528 | cudaError_t err = cudaGetLastError();
529 | if (err != cudaSuccess) {
530 | printf("GPUEngine: Launch: %s\n", cudaGetErrorString(err));
531 | return false;
532 | }
533 |
534 | // Look for prefix found
535 | uint32_t nbFound = outputHashPinned[0];
536 | if (nbFound > maxFound) {
537 | // prefix has been lost
538 | if (!lostWarning) {
539 | printf("\nWarning, %d items lost\nHint: Search with less threads (-g)\n", (nbFound - maxFound));
540 | lostWarning = true;
541 | }
542 | nbFound = maxFound;
543 | }
544 |
545 | // When can perform a standard copy, the kernel is eneded
546 | cudaMemcpy(outputHashPinned, outputHash, nbFound*ITEM_SIZE + 4 , cudaMemcpyDeviceToHost);
547 |
548 | for (uint32_t i = 0; i < nbFound; i++) {
549 | uint32_t *itemPtr = outputHashPinned + (i*ITEM_SIZE32 + 1);
550 | ITEM it;
551 | it.h1 = ((uint8_t *)(itemPtr));
552 | it.h2 = ((uint8_t *)(itemPtr))+20;
553 | hashFound.push_back(it);
554 | }
555 |
556 | return callKernel();
557 |
558 | }
559 |
--------------------------------------------------------------------------------
/GPU/GPUHash.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the BTCCollider distribution (https://github.com/JeanLucPons/BTCCollider).
3 | * Copyright (c) 2020 Jean Luc PONS.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | // ---------------------------------------------------------------------------------
19 | // SHA256
20 | // ---------------------------------------------------------------------------------
21 |
22 | __device__ __constant__ uint32_t K[] =
23 | {
24 | 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
25 | 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
26 | 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
27 | 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
28 | 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
29 | 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
30 | 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
31 | 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
32 | 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
33 | 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
34 | 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
35 | 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
36 | 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
37 | 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
38 | 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
39 | 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
40 | };
41 |
42 | __device__ __constant__ uint32_t I[] = {
43 | 0x6a09e667ul,
44 | 0xbb67ae85ul,
45 | 0x3c6ef372ul,
46 | 0xa54ff53aul,
47 | 0x510e527ful,
48 | 0x9b05688cul,
49 | 0x1f83d9abul,
50 | 0x5be0cd19ul,
51 | };
52 |
53 | //#define ASSEMBLY_SIGMA
54 | #ifdef ASSEMBLY_SIGMA
55 |
56 | __device__ __forceinline__ uint32_t S0(uint32_t x) {
57 |
58 | uint32_t y;
59 | asm("{\n\t"
60 | " .reg .u64 r1,r2,r3;\n\t"
61 | " cvt.u64.u32 r1, %1;\n\t"
62 | " mov.u64 r2, r1;\n\t"
63 | " shl.b64 r2, r2,32;\n\t"
64 | " or.b64 r1, r1,r2;\n\t"
65 | " shr.b64 r3, r1, 2;\n\t"
66 | " mov.u64 r2, r3;\n\t"
67 | " shr.b64 r3, r1, 13;\n\t"
68 | " xor.b64 r2, r2, r3;\n\t"
69 | " shr.b64 r3, r1, 22;\n\t"
70 | " xor.b64 r2, r2, r3;\n\t"
71 | " cvt.u32.u64 %0,r2;\n\t"
72 | "}\n\t"
73 | : "=r"(y) : "r" (x));
74 | return y;
75 |
76 | }
77 |
78 | __device__ __forceinline__ uint32_t S1(uint32_t x) {
79 |
80 | uint32_t y;
81 | asm("{\n\t"
82 | " .reg .u64 r1,r2,r3;\n\t"
83 | " cvt.u64.u32 r1, %1;\n\t"
84 | " mov.u64 r2, r1;\n\t"
85 | " shl.b64 r2, r2,32;\n\t"
86 | " or.b64 r1, r1,r2;\n\t"
87 | " shr.b64 r3, r1, 6;\n\t"
88 | " mov.u64 r2, r3;\n\t"
89 | " shr.b64 r3, r1, 11;\n\t"
90 | " xor.b64 r2, r2, r3;\n\t"
91 | " shr.b64 r3, r1, 25;\n\t"
92 | " xor.b64 r2, r2, r3;\n\t"
93 | " cvt.u32.u64 %0,r2;\n\t"
94 | "}\n\t"
95 | : "=r"(y) : "r" (x));
96 | return y;
97 |
98 | }
99 |
100 | __device__ __forceinline__ uint32_t s0(uint32_t x) {
101 |
102 | uint32_t y;
103 | asm("{\n\t"
104 | " .reg .u64 r1,r2,r3;\n\t"
105 | " cvt.u64.u32 r1, %1;\n\t"
106 | " mov.u64 r2, r1;\n\t"
107 | " shl.b64 r2, r2,32;\n\t"
108 | " or.b64 r1, r1,r2;\n\t"
109 | " shr.b64 r2, r2, 35;\n\t"
110 | " shr.b64 r3, r1, 18;\n\t"
111 | " xor.b64 r2, r2, r3;\n\t"
112 | " shr.b64 r3, r1, 7;\n\t"
113 | " xor.b64 r2, r2, r3;\n\t"
114 | " cvt.u32.u64 %0,r2;\n\t"
115 | "}\n\t"
116 | : "=r"(y) : "r" (x));
117 | return y;
118 |
119 | }
120 |
121 | __device__ __forceinline__ uint32_t s1(uint32_t x) {
122 |
123 | uint32_t y;
124 | asm("{\n\t"
125 | " .reg .u64 r1,r2,r3;\n\t"
126 | " cvt.u64.u32 r1, %1;\n\t"
127 | " mov.u64 r2, r1;\n\t"
128 | " shl.b64 r2, r2,32;\n\t"
129 | " or.b64 r1, r1,r2;\n\t"
130 | " shr.b64 r2, r2, 42;\n\t"
131 | " shr.b64 r3, r1, 19;\n\t"
132 | " xor.b64 r2, r2, r3;\n\t"
133 | " shr.b64 r3, r1, 17;\n\t"
134 | " xor.b64 r2, r2, r3;\n\t"
135 | " cvt.u32.u64 %0,r2;\n\t"
136 | "}\n\t"
137 | : "=r"(y) : "r" (x));
138 | return y;
139 |
140 | }
141 |
142 | #else
143 |
144 | #define ROR(x,n) ((x>>n)|(x<<(32-n)))
145 | #define S0(x) (ROR(x,2) ^ ROR(x,13) ^ ROR(x,22))
146 | #define S1(x) (ROR(x,6) ^ ROR(x,11) ^ ROR(x,25))
147 | #define s0(x) (ROR(x,7) ^ ROR(x,18) ^ (x >> 3))
148 | #define s1(x) (ROR(x,17) ^ ROR(x,19) ^ (x >> 10))
149 |
150 | #endif
151 |
152 | //#define Maj(x,y,z) ((x&y)^(x&z)^(y&z))
153 | //#define Ch(x,y,z) ((x&y)^(~x&z))
154 |
155 | // The following functions are equivalent to the above
156 | #define Maj(x,y,z) ((x & y) | (z & (x | y)))
157 | #define Ch(x,y,z) (z ^ (x & (y ^ z)))
158 |
159 | // SHA-256 inner round
160 | #define S2Round(a, b, c, d, e, f, g, h, k, w) \
161 | t1 = h + S1(e) + Ch(e,f,g) + k + (w); \
162 | t2 = S0(a) + Maj(a,b,c); \
163 | d += t1; \
164 | h = t1 + t2;
165 |
166 | // WMIX
167 | #define WMIX() { \
168 | w[0] += s1(w[14]) + w[9] + s0(w[1]);\
169 | w[1] += s1(w[15]) + w[10] + s0(w[2]);\
170 | w[2] += s1(w[0]) + w[11] + s0(w[3]);\
171 | w[3] += s1(w[1]) + w[12] + s0(w[4]);\
172 | w[4] += s1(w[2]) + w[13] + s0(w[5]);\
173 | w[5] += s1(w[3]) + w[14] + s0(w[6]);\
174 | w[6] += s1(w[4]) + w[15] + s0(w[7]);\
175 | w[7] += s1(w[5]) + w[0] + s0(w[8]);\
176 | w[8] += s1(w[6]) + w[1] + s0(w[9]);\
177 | w[9] += s1(w[7]) + w[2] + s0(w[10]);\
178 | w[10] += s1(w[8]) + w[3] + s0(w[11]);\
179 | w[11] += s1(w[9]) + w[4] + s0(w[12]);\
180 | w[12] += s1(w[10]) + w[5] + s0(w[13]);\
181 | w[13] += s1(w[11]) + w[6] + s0(w[14]);\
182 | w[14] += s1(w[12]) + w[7] + s0(w[15]);\
183 | w[15] += s1(w[13]) + w[8] + s0(w[0]);\
184 | }
185 |
186 | // ROUND
187 | #define SHA256_RND(k) {\
188 | S2Round(a, b, c, d, e, f, g, h, K[k], w[0]);\
189 | S2Round(h, a, b, c, d, e, f, g, K[k + 1], w[1]);\
190 | S2Round(g, h, a, b, c, d, e, f, K[k + 2], w[2]);\
191 | S2Round(f, g, h, a, b, c, d, e, K[k + 3], w[3]);\
192 | S2Round(e, f, g, h, a, b, c, d, K[k + 4], w[4]);\
193 | S2Round(d, e, f, g, h, a, b, c, K[k + 5], w[5]);\
194 | S2Round(c, d, e, f, g, h, a, b, K[k + 6], w[6]);\
195 | S2Round(b, c, d, e, f, g, h, a, K[k + 7], w[7]);\
196 | S2Round(a, b, c, d, e, f, g, h, K[k + 8], w[8]);\
197 | S2Round(h, a, b, c, d, e, f, g, K[k + 9], w[9]);\
198 | S2Round(g, h, a, b, c, d, e, f, K[k + 10], w[10]);\
199 | S2Round(f, g, h, a, b, c, d, e, K[k + 11], w[11]);\
200 | S2Round(e, f, g, h, a, b, c, d, K[k + 12], w[12]);\
201 | S2Round(d, e, f, g, h, a, b, c, K[k + 13], w[13]);\
202 | S2Round(c, d, e, f, g, h, a, b, K[k + 14], w[14]);\
203 | S2Round(b, c, d, e, f, g, h, a, K[k + 15], w[15]);\
204 | }
205 |
206 |
207 | // Initialise state
208 | __device__ void SHA256Initialize(uint32_t s[8]) {
209 | #pragma unroll 8
210 | for (int i = 0; i < 8; i++)
211 | s[i] = I[i];
212 | }
213 |
214 | #define DEF(x,y) uint32_t x = s[y]
215 |
216 | // Perform SHA-256 transformations, process 64-byte chunks
217 | __device__ void SHA256Transform(uint32_t s[8],uint32_t* w) {
218 |
219 | uint32_t t1;
220 | uint32_t t2;
221 |
222 | DEF(a, 0);
223 | DEF(b, 1);
224 | DEF(c, 2);
225 | DEF(d, 3);
226 | DEF(e, 4);
227 | DEF(f, 5);
228 | DEF(g, 6);
229 | DEF(h, 7);
230 |
231 | SHA256_RND(0);
232 | WMIX();
233 | SHA256_RND(16);
234 | WMIX();
235 | SHA256_RND(32);
236 | WMIX();
237 | SHA256_RND(48);
238 |
239 | s[0] += a;
240 | s[1] += b;
241 | s[2] += c;
242 | s[3] += d;
243 | s[4] += e;
244 | s[5] += f;
245 | s[6] += g;
246 | s[7] += h;
247 |
248 | }
249 |
250 |
251 | // ---------------------------------------------------------------------------------
252 | // RIPEMD160
253 | // ---------------------------------------------------------------------------------
254 | __device__ __constant__ uint64_t ripemd160_sizedesc_32 = 32 << 3;
255 |
256 | __device__ void RIPEMD160Initialize(uint32_t s[5]) {
257 |
258 | s[0] = 0x67452301ul;
259 | s[1] = 0xEFCDAB89ul;
260 | s[2] = 0x98BADCFEul;
261 | s[3] = 0x10325476ul;
262 | s[4] = 0xC3D2E1F0ul;
263 |
264 | }
265 |
266 | #define ROL(x,n) ((x>>(32-n))|(x<.
16 | */
17 |
18 | #include
19 | #include "sha256.h"
20 |
21 | #define BSWAP
22 |
23 | /// Internal SHA-256 implementation.
24 | namespace _sha256
25 | {
26 |
27 | static const unsigned char pad[64] = { 0x80 };
28 |
29 | #ifndef WIN64
30 | #define _byteswap_ulong __builtin_bswap32
31 | #define _byteswap_uint64 __builtin_bswap64
32 | inline uint32_t _rotr(uint32_t x, uint8_t r) {
33 | asm("rorl %1,%0" : "+r" (x) : "c" (r));
34 | return x;
35 | }
36 | #endif
37 |
38 | #define ROR(x,n) _rotr(x, n)
39 | #define S0(x) (ROR(x,2) ^ ROR(x,13) ^ ROR(x,22))
40 | #define S1(x) (ROR(x,6) ^ ROR(x,11) ^ ROR(x,25))
41 | #define s0(x) (ROR(x,7) ^ ROR(x,18) ^ (x >> 3))
42 | #define s1(x) (ROR(x,17) ^ ROR(x,19) ^ (x >> 10))
43 |
44 | #define Maj(x,y,z) ((x&y)^(x&z)^(y&z))
45 | //#define Ch(x,y,z) ((x&y)^(~x&z))
46 |
47 | // The following functions are equivalent to the above
48 | //#define Maj(x,y,z) ((x & y) | (z & (x | y)))
49 | #define Ch(x,y,z) (z ^ (x & (y ^ z)))
50 |
51 | // SHA-256 round
52 | #define Round(a, b, c, d, e, f, g, h, k, w) \
53 | t1 = h + S1(e) + Ch(e,f,g) + k + (w); \
54 | t2 = S0(a) + Maj(a,b,c); \
55 | d += t1; \
56 | h = t1 + t2;
57 |
58 | #ifdef BSWAP
59 | #define WRITEBE32(ptr,x) *((uint32_t *)(ptr)) = _byteswap_ulong(x)
60 | #define WRITEBE64(ptr,x) *((uint64_t *)(ptr)) = _byteswap_uint64(x)
61 | #define READBE32(ptr) (uint32_t)_byteswap_ulong(*(uint32_t *)(ptr))
62 | #else
63 | #define WRITEBE32(ptr,x) *(ptr) = x
64 | #define WRITEBE64(ptr,x) *(ptr) = x
65 | #define READBE32(ptr) *(uint32_t *)(ptr)
66 | #endif
67 |
68 | // Initialise state
69 | void Initialize(uint32_t *s) {
70 |
71 | s[0] = 0x6a09e667ul;
72 | s[1] = 0xbb67ae85ul;
73 | s[2] = 0x3c6ef372ul;
74 | s[3] = 0xa54ff53aul;
75 | s[4] = 0x510e527ful;
76 | s[5] = 0x9b05688cul;
77 | s[6] = 0x1f83d9abul;
78 | s[7] = 0x5be0cd19ul;
79 |
80 | }
81 |
82 |
83 | // Perform SHA-256 transformations, process 64-byte chunks
84 | void Transform(uint32_t* s, const unsigned char* chunk)
85 | {
86 | uint32_t t1;
87 | uint32_t t2;
88 | uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
89 | uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
90 |
91 | Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = READBE32(chunk + 0));
92 | Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = READBE32(chunk + 4));
93 | Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = READBE32(chunk + 8));
94 | Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = READBE32(chunk + 12));
95 | Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = READBE32(chunk + 16));
96 | Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = READBE32(chunk + 20));
97 | Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = READBE32(chunk + 24));
98 | Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = READBE32(chunk + 28));
99 | Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = READBE32(chunk + 32));
100 | Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = READBE32(chunk + 36));
101 | Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = READBE32(chunk + 40));
102 | Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = READBE32(chunk + 44));
103 | Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = READBE32(chunk + 48));
104 | Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = READBE32(chunk + 52));
105 | Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = READBE32(chunk + 56));
106 | Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = READBE32(chunk + 60));
107 |
108 | Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += s1(w14) + w9 + s0(w1));
109 | Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += s1(w15) + w10 + s0(w2));
110 | Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += s1(w0) + w11 + s0(w3));
111 | Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += s1(w1) + w12 + s0(w4));
112 | Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += s1(w2) + w13 + s0(w5));
113 | Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += s1(w3) + w14 + s0(w6));
114 | Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += s1(w4) + w15 + s0(w7));
115 | Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += s1(w5) + w0 + s0(w8));
116 | Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += s1(w6) + w1 + s0(w9));
117 | Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += s1(w7) + w2 + s0(w10));
118 | Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += s1(w8) + w3 + s0(w11));
119 | Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += s1(w9) + w4 + s0(w12));
120 | Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += s1(w10) + w5 + s0(w13));
121 | Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += s1(w11) + w6 + s0(w14));
122 | Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += s1(w12) + w7 + s0(w15));
123 | Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += s1(w13) + w8 + s0(w0));
124 |
125 | Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += s1(w14) + w9 + s0(w1));
126 | Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += s1(w15) + w10 + s0(w2));
127 | Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += s1(w0) + w11 + s0(w3));
128 | Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += s1(w1) + w12 + s0(w4));
129 | Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += s1(w2) + w13 + s0(w5));
130 | Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += s1(w3) + w14 + s0(w6));
131 | Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += s1(w4) + w15 + s0(w7));
132 | Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += s1(w5) + w0 + s0(w8));
133 | Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += s1(w6) + w1 + s0(w9));
134 | Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += s1(w7) + w2 + s0(w10));
135 | Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += s1(w8) + w3 + s0(w11));
136 | Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += s1(w9) + w4 + s0(w12));
137 | Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += s1(w10) + w5 + s0(w13));
138 | Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += s1(w11) + w6 + s0(w14));
139 | Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += s1(w12) + w7 + s0(w15));
140 | Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += s1(w13) + w8 + s0(w0));
141 |
142 | Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += s1(w14) + w9 + s0(w1));
143 | Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += s1(w15) + w10 + s0(w2));
144 | Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += s1(w0) + w11 + s0(w3));
145 | Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += s1(w1) + w12 + s0(w4));
146 | Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += s1(w2) + w13 + s0(w5));
147 | Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += s1(w3) + w14 + s0(w6));
148 | Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += s1(w4) + w15 + s0(w7));
149 | Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += s1(w5) + w0 + s0(w8));
150 | Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += s1(w6) + w1 + s0(w9));
151 | Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += s1(w7) + w2 + s0(w10));
152 | Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += s1(w8) + w3 + s0(w11));
153 | Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += s1(w9) + w4 + s0(w12));
154 | Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += s1(w10) + w5 + s0(w13));
155 | Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += s1(w11) + w6 + s0(w14));
156 | Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + s1(w12) + w7 + s0(w15));
157 | Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + s1(w13) + w8 + s0(w0));
158 |
159 | s[0] += a;
160 | s[1] += b;
161 | s[2] += c;
162 | s[3] += d;
163 | s[4] += e;
164 | s[5] += f;
165 | s[6] += g;
166 | s[7] += h;
167 |
168 | }
169 |
170 | // Compute SHA256(SHA256(chunk))[0]
171 | void Transform2(uint32_t* s, const unsigned char* chunk) {
172 |
173 | uint32_t t1;
174 | uint32_t t2;
175 | uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
176 |
177 | uint32_t a = 0x6a09e667ul;
178 | uint32_t b = 0xbb67ae85ul;
179 | uint32_t c = 0x3c6ef372ul;
180 | uint32_t d = 0xa54ff53aul;
181 | uint32_t e = 0x510e527ful;
182 | uint32_t f = 0x9b05688cul;
183 | uint32_t g = 0x1f83d9abul;
184 | uint32_t h = 0x5be0cd19ul;
185 |
186 | Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = READBE32(chunk + 0));
187 | Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = READBE32(chunk + 4));
188 | Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = READBE32(chunk + 8));
189 | Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = READBE32(chunk + 12));
190 | Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = READBE32(chunk + 16));
191 | Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = READBE32(chunk + 20));
192 | Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = READBE32(chunk + 24));
193 | Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = READBE32(chunk + 28));
194 | Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = READBE32(chunk + 32));
195 | Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = READBE32(chunk + 36));
196 | Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = READBE32(chunk + 40));
197 | Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = READBE32(chunk + 44));
198 | Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = READBE32(chunk + 48));
199 | Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = READBE32(chunk + 52));
200 | Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = READBE32(chunk + 56));
201 | Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = READBE32(chunk + 60));
202 |
203 | Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += s1(w14) + w9 + s0(w1));
204 | Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += s1(w15) + w10 + s0(w2));
205 | Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += s1(w0) + w11 + s0(w3));
206 | Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += s1(w1) + w12 + s0(w4));
207 | Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += s1(w2) + w13 + s0(w5));
208 | Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += s1(w3) + w14 + s0(w6));
209 | Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += s1(w4) + w15 + s0(w7));
210 | Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += s1(w5) + w0 + s0(w8));
211 | Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += s1(w6) + w1 + s0(w9));
212 | Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += s1(w7) + w2 + s0(w10));
213 | Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += s1(w8) + w3 + s0(w11));
214 | Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += s1(w9) + w4 + s0(w12));
215 | Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += s1(w10) + w5 + s0(w13));
216 | Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += s1(w11) + w6 + s0(w14));
217 | Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += s1(w12) + w7 + s0(w15));
218 | Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += s1(w13) + w8 + s0(w0));
219 |
220 | Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += s1(w14) + w9 + s0(w1));
221 | Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += s1(w15) + w10 + s0(w2));
222 | Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += s1(w0) + w11 + s0(w3));
223 | Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += s1(w1) + w12 + s0(w4));
224 | Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += s1(w2) + w13 + s0(w5));
225 | Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += s1(w3) + w14 + s0(w6));
226 | Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += s1(w4) + w15 + s0(w7));
227 | Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += s1(w5) + w0 + s0(w8));
228 | Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += s1(w6) + w1 + s0(w9));
229 | Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += s1(w7) + w2 + s0(w10));
230 | Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += s1(w8) + w3 + s0(w11));
231 | Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += s1(w9) + w4 + s0(w12));
232 | Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += s1(w10) + w5 + s0(w13));
233 | Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += s1(w11) + w6 + s0(w14));
234 | Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += s1(w12) + w7 + s0(w15));
235 | Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += s1(w13) + w8 + s0(w0));
236 |
237 | Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += s1(w14) + w9 + s0(w1));
238 | Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += s1(w15) + w10 + s0(w2));
239 | Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += s1(w0) + w11 + s0(w3));
240 | Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += s1(w1) + w12 + s0(w4));
241 | Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += s1(w2) + w13 + s0(w5));
242 | Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += s1(w3) + w14 + s0(w6));
243 | Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += s1(w4) + w15 + s0(w7));
244 | Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += s1(w5) + w0 + s0(w8));
245 | Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += s1(w6) + w1 + s0(w9));
246 | Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += s1(w7) + w2 + s0(w10));
247 | Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += s1(w8) + w3 + s0(w11));
248 | Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += s1(w9) + w4 + s0(w12));
249 | Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += s1(w10) + w5 + s0(w13));
250 | Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += s1(w11) + w6 + s0(w14));
251 | Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + s1(w12) + w7 + s0(w15));
252 | Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + s1(w13) + w8 + s0(w0));
253 |
254 | w0 = 0x6a09e667ul + a;
255 | w1 = 0xbb67ae85ul + b;
256 | w2 = 0x3c6ef372ul + c;
257 | w3 = 0xa54ff53aul + d;
258 | w4 = 0x510e527ful + e;
259 | w5 = 0x9b05688cul + f;
260 | w6 = 0x1f83d9abul + g;
261 | w7 = 0x5be0cd19ul + h;
262 | w8 = 0x80000000;
263 | w9 = 0;
264 | w10 = 0;
265 | w11 = 0;
266 | w12 = 0;
267 | w13 = 0;
268 | w14 = 0;
269 | w15 = 0x100;
270 |
271 | a = 0x6a09e667ul;
272 | b = 0xbb67ae85ul;
273 | c = 0x3c6ef372ul;
274 | d = 0xa54ff53aul;
275 | e = 0x510e527ful;
276 | f = 0x9b05688cul;
277 | g = 0x1f83d9abul;
278 | h = 0x5be0cd19ul;
279 |
280 | Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0);
281 | Round(h, a, b, c, d, e, f, g, 0x71374491, w1);
282 | Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2);
283 | Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3);
284 | Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4);
285 | Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5);
286 | Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6);
287 | Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7);
288 | Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8);
289 | Round(h, a, b, c, d, e, f, g, 0x12835b01, w9);
290 | Round(g, h, a, b, c, d, e, f, 0x243185be, w10);
291 | Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11);
292 | Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12);
293 | Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13);
294 | Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14);
295 | Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15);
296 |
297 | Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += s1(w14) + w9 + s0(w1));
298 | Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += s1(w15) + w10 + s0(w2));
299 | Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += s1(w0) + w11 + s0(w3));
300 | Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += s1(w1) + w12 + s0(w4));
301 | Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += s1(w2) + w13 + s0(w5));
302 | Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += s1(w3) + w14 + s0(w6));
303 | Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += s1(w4) + w15 + s0(w7));
304 | Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += s1(w5) + w0 + s0(w8));
305 | Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += s1(w6) + w1 + s0(w9));
306 | Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += s1(w7) + w2 + s0(w10));
307 | Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += s1(w8) + w3 + s0(w11));
308 | Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += s1(w9) + w4 + s0(w12));
309 | Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += s1(w10) + w5 + s0(w13));
310 | Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += s1(w11) + w6 + s0(w14));
311 | Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += s1(w12) + w7 + s0(w15));
312 | Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += s1(w13) + w8 + s0(w0));
313 |
314 | Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += s1(w14) + w9 + s0(w1));
315 | Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += s1(w15) + w10 + s0(w2));
316 | Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += s1(w0) + w11 + s0(w3));
317 | Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += s1(w1) + w12 + s0(w4));
318 | Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += s1(w2) + w13 + s0(w5));
319 | Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += s1(w3) + w14 + s0(w6));
320 | Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += s1(w4) + w15 + s0(w7));
321 | Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += s1(w5) + w0 + s0(w8));
322 | Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += s1(w6) + w1 + s0(w9));
323 | Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += s1(w7) + w2 + s0(w10));
324 | Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += s1(w8) + w3 + s0(w11));
325 | Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += s1(w9) + w4 + s0(w12));
326 | Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += s1(w10) + w5 + s0(w13));
327 | Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += s1(w11) + w6 + s0(w14));
328 | Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += s1(w12) + w7 + s0(w15));
329 | Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += s1(w13) + w8 + s0(w0));
330 |
331 | Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += s1(w14) + w9 + s0(w1));
332 | Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += s1(w15) + w10 + s0(w2));
333 | Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += s1(w0) + w11 + s0(w3));
334 | Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += s1(w1) + w12 + s0(w4));
335 | Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += s1(w2) + w13 + s0(w5));
336 | Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += s1(w3) + w14 + s0(w6));
337 | Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += s1(w4) + w15 + s0(w7));
338 | Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += s1(w5) + w0 + s0(w8));
339 | Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += s1(w6) + w1 + s0(w9));
340 | Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += s1(w7) + w2 + s0(w10));
341 | Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += s1(w8) + w3 + s0(w11));
342 | Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += s1(w9) + w4 + s0(w12));
343 | Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += s1(w10) + w5 + s0(w13));
344 | Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += s1(w11) + w6 + s0(w14));
345 | Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + s1(w12) + w7 + s0(w15));
346 | Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + s1(w13) + w8 + s0(w0));
347 |
348 | s[0] = 0x6a09e667ul + a;
349 |
350 | }
351 |
352 | } // namespace sha256
353 |
354 |
355 | ////// SHA-256
356 |
357 | class CSHA256
358 | {
359 | private:
360 | uint32_t s[8];
361 | unsigned char buf[64];
362 | uint64_t bytes;
363 |
364 | public:
365 | static const size_t OUTPUT_SIZE = 32;
366 |
367 | CSHA256();
368 | void Write(const unsigned char* data, size_t len);
369 | void Finalize(unsigned char hash[OUTPUT_SIZE]);
370 |
371 | };
372 |
373 | CSHA256::CSHA256() {
374 | bytes = 0;
375 | s[0] = 0x6a09e667ul;
376 | s[1] = 0xbb67ae85ul;
377 | s[2] = 0x3c6ef372ul;
378 | s[3] = 0xa54ff53aul;
379 | s[4] = 0x510e527ful;
380 | s[5] = 0x9b05688cul;
381 | s[6] = 0x1f83d9abul;
382 | s[7] = 0x5be0cd19ul;
383 | }
384 |
385 | void CSHA256::Write(const unsigned char* data, size_t len)
386 | {
387 | const unsigned char* end = data + len;
388 | size_t bufsize = bytes % 64;
389 | if (bufsize && bufsize + len >= 64) {
390 | // Fill the buffer, and process it.
391 | memcpy(buf + bufsize, data, 64 - bufsize);
392 | bytes += 64 - bufsize;
393 | data += 64 - bufsize;
394 | _sha256::Transform(s, buf);
395 | bufsize = 0;
396 | }
397 | while (end >= data + 64) {
398 | // Process full chunks directly from the source.
399 | _sha256::Transform(s, data);
400 | bytes += 64;
401 | data += 64;
402 | }
403 | if (end > data) {
404 | // Fill the buffer with what remains.
405 | memcpy(buf + bufsize, data, end - data);
406 | bytes += end - data;
407 | }
408 | }
409 |
410 | void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
411 | {
412 | unsigned char sizedesc[8];
413 | WRITEBE64(sizedesc, bytes << 3);
414 | Write(_sha256::pad, 1 + ((119 - (bytes % 64)) % 64));
415 | Write(sizedesc, 8);
416 | WRITEBE32(hash, s[0]);
417 | WRITEBE32(hash + 4, s[1]);
418 | WRITEBE32(hash + 8, s[2]);
419 | WRITEBE32(hash + 12, s[3]);
420 | WRITEBE32(hash + 16, s[4]);
421 | WRITEBE32(hash + 20, s[5]);
422 | WRITEBE32(hash + 24, s[6]);
423 | WRITEBE32(hash + 28, s[7]);
424 | }
425 |
426 | void sha256(unsigned char *input, int length, unsigned char *digest) {
427 |
428 | CSHA256 sha;
429 | sha.Write(input, length);
430 | sha.Finalize(digest);
431 |
432 | }
433 |
434 | const uint8_t sizedesc_32[8] = { 0,0,0,0,0,0,1,0 };
435 | const uint8_t sizedesc_33[8] = { 0,0,0,0,0,0,1,8 };
436 | const uint8_t sizedesc_65[8] = { 0,0,0,0,0,0,2,8 };
437 |
438 | void sha256_33(unsigned char *input, unsigned char *digest) {
439 |
440 | uint32_t s[8];
441 |
442 | _sha256::Initialize(s);
443 | memcpy(input + 33, _sha256::pad, 23);
444 | memcpy(input + 56, sizedesc_33, 8);
445 | _sha256::Transform(s, input);
446 |
447 | WRITEBE32(digest, s[0]);
448 | WRITEBE32(digest + 4, s[1]);
449 | WRITEBE32(digest + 8, s[2]);
450 | WRITEBE32(digest + 12, s[3]);
451 | WRITEBE32(digest + 16, s[4]);
452 | WRITEBE32(digest + 20, s[5]);
453 | WRITEBE32(digest + 24, s[6]);
454 | WRITEBE32(digest + 28, s[7]);
455 |
456 |
457 | }
458 |
459 | void sha256_65(unsigned char *input, unsigned char *digest) {
460 |
461 | uint32_t s[8];
462 |
463 | memcpy(input + 65, _sha256::pad, 55);
464 | memcpy(input + 120, sizedesc_65, 8);
465 |
466 | _sha256::Initialize(s);
467 | _sha256::Transform(s, input);
468 | _sha256::Transform(s, input+64);
469 |
470 | WRITEBE32(digest, s[0]);
471 | WRITEBE32(digest + 4, s[1]);
472 | WRITEBE32(digest + 8, s[2]);
473 | WRITEBE32(digest + 12, s[3]);
474 | WRITEBE32(digest + 16, s[4]);
475 | WRITEBE32(digest + 20, s[5]);
476 | WRITEBE32(digest + 24, s[6]);
477 | WRITEBE32(digest + 28, s[7]);
478 |
479 | }
480 |
481 | void sha256_checksum(uint8_t *input, int length, uint8_t *checksum) {
482 |
483 | uint32_t s[8];
484 | uint8_t b[64];
485 | memcpy(b,input,length);
486 | memcpy(b + length, _sha256::pad, 56-length);
487 | WRITEBE64(b + 56, length << 3);
488 | _sha256::Transform2(s, b);
489 | WRITEBE32(checksum,s[0]);
490 |
491 | }
492 |
493 | std::string sha256_hex(unsigned char *digest) {
494 |
495 | char buf[2*32+1];
496 | buf[2*32] = 0;
497 | for (int i = 0; i < 32; i++)
498 | sprintf(buf+i*2,"%02x",digest[i]);
499 | return std::string(buf);
500 |
501 | }
502 |
503 |
--------------------------------------------------------------------------------