├── 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 | ![40BITS dp curves](img/hash160_col40.jpg) 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 | ![40BITS dp curves](img/hash160_col40_asymptote.jpg) 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 | --------------------------------------------------------------------------------