From 93b5aaf2ad541ada93b803bbdfa15a075968a02c Mon Sep 17 00:00:00 2001 From: AlbertoBSD Date: Mon, 25 Oct 2021 19:38:06 +0200 Subject: [PATCH] ethereum, minikeys, stride,rmd double speed --- CHANGELOG.md | 6 + Makefile | 8 +- README.md | 172 ++++- base58/base58.c | 49 +- base58/libbase58.h | 3 +- hash/ripemd160.cpp | 316 +++++++++ hash/ripemd160.h | 56 ++ hash/ripemd160_sse.cpp | 409 ++++++++++++ hash/sha256.cpp | 502 +++++++++++++++ hash/sha256.h | 35 + hash/sha256_sse.cpp | 627 ++++++++++++++++++ hash/sha512.cpp | 406 ++++++++++++ hash/sha512.h | 28 + keyhunt.cpp | 1353 ++++++++++++++++++++++++++++----------- rmd160/rmd160.h | 8 + secp256k1/SECP256K1.cpp | 215 ++++++- secp256k1/SECP256k1.h | 13 + sha256/sha256.c | 142 ---- sha256/sha256.h | 17 - tests/1to32.eth | 32 + tests/minikeys.txt | 3 + 21 files changed, 3837 insertions(+), 563 deletions(-) create mode 100644 hash/ripemd160.cpp create mode 100644 hash/ripemd160.h create mode 100644 hash/ripemd160_sse.cpp create mode 100644 hash/sha256.cpp create mode 100644 hash/sha256.h create mode 100644 hash/sha256_sse.cpp create mode 100644 hash/sha512.cpp create mode 100644 hash/sha512.h delete mode 100644 sha256/sha256.c delete mode 100644 sha256/sha256.h create mode 100644 tests/1to32.eth create mode 100644 tests/minikeys.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index deb60af..ddf8ef8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# Version 0.2.211018 Chocolate ¡Beta! +- Ethereum support +- Double speed for rmd160 mode +- Minikeys mode support +- Stride option + # Version 0.2.211018 Chocolate ¡Beta! - Solved some bugs: https://github.com/albertobsd/keyhunt/issues/122 https://github.com/albertobsd/keyhunt/issues/111 - Files are going to be updated automatillyca diff --git a/Makefile b/Makefile index e57c21d..d6744e2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ default: g++ -O3 -c oldbloom/bloom.cpp -o oldbloom.o g++ -O3 -c bloom/bloom.cpp -o bloom.o - g++ -O3 -c sha256/sha256.c -o sha256.o +# g++ -O3 -c sha256/sha256.c -o sha256.o gcc -O3 -c base58/base58.c -o base58.o gcc -O3 -c rmd160/rmd160.c -o rmd160.o g++ -O3 -c sha3/sha3.c -o sha3.o @@ -14,7 +14,11 @@ default: g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/IntMod.cpp -o IntMod.o g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/Random.cpp -o Random.o g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/IntGroup.cpp -o IntGroup.o - g++ -o keyhunt keyhunt.cpp base58.o rmd160.o sha256.o bloom.o oldbloom.o xxhash.o util.o Int.o Point.o SECP256K1.o IntMod.o Random.o IntGroup.o sha3.o keccak.o -lm -lpthread + g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/ripemd160.o -c hash/ripemd160.cpp + g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/sha256.o -c hash/sha256.cpp + g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/ripemd160_sse.o -c hash/ripemd160_sse.cpp + g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/sha256_sse.o -c hash/sha256_sse.cpp + g++ -o keyhunt keyhunt.cpp base58.o rmd160.o hash/ripemd160.o hash/ripemd160_sse.o hash/sha256.o hash/sha256_sse.o bloom.o oldbloom.o xxhash.o util.o Int.o Point.o SECP256K1.o IntMod.o Random.o IntGroup.o sha3.o keccak.o -lm -lpthread rm -r *.o clean: rm keyhunt diff --git a/README.md b/README.md index 4a94bdd..0fe18ad 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,16 @@ # keyhunt + Tool for hunt privatekeys for crypto currencies that use secp256k1 elliptic curve Post: https://bitcointalk.org/index.php?topic=5322040.0 -Work for btc in this moment, only legacy Addresses that start with '1' - -Ethereum addresses is a work in develop +Work for Bitcoin +- address compress or uncompress +- hashes rmd160 compress or uncompress +- publickeys compress or uncompress +Work for Ethereum +- address ## For regulars users @@ -25,28 +29,38 @@ don't forget change to the keyhunt directory `cd keyhunt` # How to build + First compile: -`make` +``` +make +``` and then execute with `-h` to see the help -```./keyhunt -h``` +``` +./keyhunt -h +``` ## ¡Beta! -This version is still a *beta* version, there are a lot of things that can be fail. And absoluly there are some bugs + +This version is still a **beta** version, there are a lot of things that can be fail. And absoluly there are some bugs # Modes Keyhunt can work in diferents ways at different speeds. + The current availables modes are: - address - rmd160 - xpoint - bsgs -you can select them with `-m` +## Experimental modes + +- minikeys +- pub2rmd ## address mode @@ -496,6 +510,7 @@ Output: ## pub2rmd mode + This method is made to try to get the puzzles publickey key it works a little more faster because it skip the EC Operations The input file need to have the hash RMD160 of the address without publickey leaked: @@ -1049,6 +1064,148 @@ user 2m15.706s sys 0m13.009s ``` +## minikeys Mode + +This mode is some experimental. + +For the moment only Minikeys of 22 characters are available + +The minikey are generated from a 16 byte buffer using the base58 encode funtion using the next string `S23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz` any sugestion please let me know. + + + +This minikeys are generated in a deterministic way using one Intenger number from `1` to `0x100000000000000000000000000000000` that is why the range is from `-r 1:100000000000000000000000000000000` + + + +Command: + +``` +./keyhunt -m minikeys -f minkey_h160.txt -r 1:100000000000000000000000000000000 -n 0x1000000 -M +``` + +Output: + +``` +[+] Version 0.2.211024 Chocolate ¡Beta!, developed by AlbertoBSD +[+] Mode minikeys +[+] Matrix screen +[+] Stride : 1 +[+] Opening file minkey_h160.txt +[+] N = 0x1000000 +[+] Range +[+] -- from : 0x1 +[+] -- to : 0x100000000000000000000000000000000 +[+] Allocating memory for 61560 elements: 1.17 MB +[+] Bloom filter for 61560 elements. +[+] Loading data to the bloomfilter total: 0.21 MB +[+] Bloomfilter completed +[+] Sorting data ... done! 61560 values were loaded and sorted +[+] Base key: 0x1 => S8AQGAut7N92awznwCnjuR +[+] Base key: 0x1000001 => S8AQGFk5PpkiBMwcrkM943 +[+] Base key: 0x2000001 => S8AQGLaGgHNPmmtSnHuYCf +[+] Total 141312 keys in 30 seconds: 4710 keys/s +``` + +Please note that total keys tested at the moment are only 141312, those are the valid keys that pass the check-test. + +the input file need to be a list of the RMD160 hash from the target address, example `tests/minikeys.txt` + +``` +da88f47133b93a1cc0c9dcf0163b2b48e2e0a20a +24b6ed321b3ccfe1fc2e6860e3f89d4d5ab257da +2312e3b76db5b91c5ad34eaea194c2ee6ece6f13 +``` + +command + +``` +./keyhunt -m minikeys -f tests/minikeys.txt -r 1:100000000000000000000000000000000 -n 0x1000000 -M +``` + +output: + +``` +[+] Version 0.2.211024 Chocolate ¡Beta!, developed by AlbertoBSD +[+] Mode minikeys +[+] Matrix screen +[+] Stride : 1 +[+] Opening file tests/minikeys.txt +[+] N = 0x1000000 +[+] Range +[+] -- from : 0x1 +[+] -- to : 0x100000000000000000000000000000000 +[+] Allocating memory for 3 elements: 0.00 MB +[+] Bloom filter for 3 elements. +[+] Loading data to the bloomfilter total: 0.00 MB +[+] Bloomfilter completed +[+] Sorting data ... done! 3 values were loaded and sorted +[+] Base key: 0x1 => S8AQGAut7N92awznwCnjuR + +HIT!! PrivKey: c4302796060742e218520bc5a4d3282ad4b8e3bf32ea2faeb1cc75cbbda33eed +pubkey: 04fe4fee3a7f5fbc9289e1857cb2a84e0fc532a470b37635f419fdfcac9379c4c7fe2c29d36add668f38ddc18e0064a18f22467dd02a902406b7aa61112eec5249 +minikey: SUCsVzCwXiNaW4bnBuzx8Q +address: 14CTHBV5S2fd9DPbKmMhrAe5se54Q85wqN + +HIT!! PrivKey: 3711a88da553ea782f9f8935cc10a9642191041e6d8e22ba1e48b7abf613047d +pubkey: 04c5180db6ad25ba53d0c39ca95925f8554e71fbf15024f64cd105be307633975bc54ad824fcb85682053158a4a22ea4c61267a4d53b23b0c114d32ad581a5fe30 +minikey: SUpxjSMeoHoXuTVhy9VYQm +address: 14M8TsBG3ntFiTm8XcDiBmHaECfZarfSw8 + +HIT!! PrivKey: 82d02f3df7b73d7e6d8be2e3636461d3680263a07bd2e63e92e855840ecc2740 +pubkey: 04e6ebe21d214d13e547c74c8bf81fdf85cee2ba5d80e3ff1d4d0ef2d4542da9f938ae79f4c6f07f7ad4205794fc5e6e613146e6d218d5ddcb06377765a00baf7e +minikey: SNQeNHzJXCJ3PcFUKB7bNv +address: 1LvWNcKf4LuWcyCmZkEev8hMusQ4qr55L8 +^C +``` + + + +# Ethereum + +Finally ethreum address are supported, for ethreum there are no modes exect for address. + +if you have publickeys for ethereum you can use xpoint or bsgs mode. + +to test the functionality of ethereum you can use the sample file `tests/1to32.eth` + +command: + +``` +./keyhunt -c eth -f tests/1to32.eth -r 1:100000000 -M +``` + +output: + +``` +[+] Version 0.2.211024 Chocolate ¡Beta!, developed by AlbertoBSD +[+] Setting search for ETH adddress. +[+] Matrix screen +[+] Stride : 1 +[+] Opening file tests/1to32.eth +[+] N = 0x100000000 +[+] Range +[+] -- from : 0x1 +[+] -- to : 0x100000000 +[+] Allocating memory for 32 elements: 0.00 MB +[+] Bloom filter for 32 elements. +[+] Loading data to the bloomfilter total: 0.00 MB +[+] Bloomfilter completed +[+] Sorting data ... done! 32 values were loaded and sorted +Base key: 1 thread 0 + + Hit!!!! PrivKey: 1 +address: 0x7e5f4552091a69125d5dfcb7b8c2659029395bdf + + Hit!!!! PrivKey: 3 +address: 0x6813eb9362372eef6200f3b1dbc3f819671cba69 + + Hit!!!! PrivKey: 7 +address: 0xd41c057fd1c78805aac12b0a94a405c0461a6fbb +.... +``` + + ## FAQ @@ -1084,7 +1241,6 @@ R: No, is just to help to speed up a little the load process and no more, but th ## Dependencies - pthread - Tested under Debian, Ubuntu Shell for windows 10 ## Thanks diff --git a/base58/base58.c b/base58/base58.c index 6265741..1dcc4ff 100644 --- a/base58/base58.c +++ b/base58/base58.c @@ -5,7 +5,7 @@ * under the terms of the standard MIT license. See COPYING for more details. */ -#ifndef WIN32 +#ifndef _WIN64 #include #else #include @@ -188,6 +188,53 @@ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) return true; } +bool b58enc_custom(char *b58, size_t *b58sz, const void *data, size_t binsz,char *buffer) +{ + const uint8_t *bin = data; + int carry; + size_t i, j, high, zcount = 0; + size_t size; + + while (zcount < binsz && !bin[zcount]) + ++zcount; + + size = (binsz - zcount) * 138 / 100 + 1; + uint8_t buf[size]; + memset(buf, 0, size); + + for (i = zcount, high = size - 1; i < binsz; ++i, high = j) + { + for (carry = bin[i], j = size - 1; (j > high) || carry; --j) + { + carry += 256 * buf[j]; + buf[j] = carry % 58; + carry /= 58; + if (!j) { + // Otherwise j wraps to maxint which is > high + break; + } + } + } + + for (j = 0; j < size && !buf[j]; ++j); + + if (*b58sz <= zcount + size - j) + { + *b58sz = zcount + size - j + 1; + return false; + } + + if (zcount) + memset(b58, buffer[0], zcount); + for (i = zcount; j < size; ++i, ++j) + b58[i] = buffer[buf[j]]; + b58[i] = '\0'; + *b58sz = i + 1; + + return true; +} + + bool b58check_enc(char *b58c, size_t *b58c_sz, uint8_t ver, const void *data, size_t datasz) { uint8_t buf[1 + datasz + 0x20]; diff --git a/base58/libbase58.h b/base58/libbase58.h index fafe653..a30fe74 100644 --- a/base58/libbase58.h +++ b/base58/libbase58.h @@ -13,6 +13,7 @@ extern bool (*b58_sha256_impl)(void *, const void *, size_t); extern bool b58tobin(void *bin, size_t *binsz, const char *b58, size_t b58sz); extern int b58check(const void *bin, size_t binsz, const char *b58, size_t b58sz); +extern bool b58enc_custom(char *b58, size_t *b58sz, const void *bin, size_t binsz,char* buffer); extern bool b58enc(char *b58, size_t *b58sz, const void *bin, size_t binsz); extern bool b58check_enc(char *b58c, size_t *b58c_sz, uint8_t ver, const void *data, size_t datasz); @@ -20,4 +21,4 @@ extern bool b58check_enc(char *b58c, size_t *b58c_sz, uint8_t ver, const void *d } #endif -#endif +#endif \ No newline at end of file diff --git a/hash/ripemd160.cpp b/hash/ripemd160.cpp new file mode 100644 index 0000000..7edccc7 --- /dev/null +++ b/hash/ripemd160.cpp @@ -0,0 +1,316 @@ +/* + * This file is part of the VanitySearch distribution (https://github.com/JeanLucPons/VanitySearch). + * Copyright (c) 2019 Jean Luc PONS. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +#include "ripemd160.h" +#include + +/// Internal RIPEMD-160 implementation. +namespace _ripemd160 { + +/** Initialize RIPEMD-160 state. */ +void inline Initialize(uint32_t* s) +{ + s[0] = 0x67452301ul; + s[1] = 0xEFCDAB89ul; + s[2] = 0x98BADCFEul; + s[3] = 0x10325476ul; + s[4] = 0xC3D2E1F0ul; +} + +#ifndef WIN64 +inline uint32_t _rotl(uint32_t x, uint8_t r) { + asm("roll %1,%0" : "+r" (x) : "c" (r)); + return x; +} +#endif + +#define ROL(x,n) _rotl(x,n) + +#define f1(x, y, z) (x ^ y ^ z) +#define f2(x, y, z) ((x & y) | (~x & z)) +#define f3(x, y, z) ((x | ~y) ^ z) +#define f4(x, y, z) ((x & z) | (~z & y)) +#define f5(x, y, z) (x ^ (y | ~z)) + +#define Round(a,b,c,d,e,f,x,k,r) \ + a = ROL(a + f + x + k, r) + e; \ + c = ROL(c, 10); + +#define R11(a,b,c,d,e,x,r) Round(a, b, c, d, e, f1(b, c, d), x, 0, r) +#define R21(a,b,c,d,e,x,r) Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r) +#define R31(a,b,c,d,e,x,r) Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r) +#define R41(a,b,c,d,e,x,r) Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r) +#define R51(a,b,c,d,e,x,r) Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r) +#define R12(a,b,c,d,e,x,r) Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r) +#define R22(a,b,c,d,e,x,r) Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r) +#define R32(a,b,c,d,e,x,r) Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r) +#define R42(a,b,c,d,e,x,r) Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r) +#define R52(a,b,c,d,e,x,r) Round(a, b, c, d, e, f1(b, c, d), x, 0, r) + +/** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */ +void Transform(uint32_t* s, const unsigned char* chunk) +{ + uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4]; + uint32_t a2 = a1, b2 = b1, c2 = c1, d2 = d1, e2 = e1; + uint32_t w[16]; + memcpy(w,chunk,16*sizeof(uint32_t)); + + R11(a1, b1, c1, d1, e1, w[0], 11); + R12(a2, b2, c2, d2, e2, w[5], 8); + R11(e1, a1, b1, c1, d1, w[1], 14); + R12(e2, a2, b2, c2, d2, w[14], 9); + R11(d1, e1, a1, b1, c1, w[2], 15); + R12(d2, e2, a2, b2, c2, w[7], 9); + R11(c1, d1, e1, a1, b1, w[3], 12); + R12(c2, d2, e2, a2, b2, w[0], 11); + R11(b1, c1, d1, e1, a1, w[4], 5); + R12(b2, c2, d2, e2, a2, w[9], 13); + R11(a1, b1, c1, d1, e1, w[5], 8); + R12(a2, b2, c2, d2, e2, w[2], 15); + R11(e1, a1, b1, c1, d1, w[6], 7); + R12(e2, a2, b2, c2, d2, w[11], 15); + R11(d1, e1, a1, b1, c1, w[7], 9); + R12(d2, e2, a2, b2, c2, w[4], 5); + R11(c1, d1, e1, a1, b1, w[8], 11); + R12(c2, d2, e2, a2, b2, w[13], 7); + R11(b1, c1, d1, e1, a1, w[9], 13); + R12(b2, c2, d2, e2, a2, w[6], 7); + R11(a1, b1, c1, d1, e1, w[10], 14); + R12(a2, b2, c2, d2, e2, w[15], 8); + R11(e1, a1, b1, c1, d1, w[11], 15); + R12(e2, a2, b2, c2, d2, w[8], 11); + R11(d1, e1, a1, b1, c1, w[12], 6); + R12(d2, e2, a2, b2, c2, w[1], 14); + R11(c1, d1, e1, a1, b1, w[13], 7); + R12(c2, d2, e2, a2, b2, w[10], 14); + R11(b1, c1, d1, e1, a1, w[14], 9); + R12(b2, c2, d2, e2, a2, w[3], 12); + R11(a1, b1, c1, d1, e1, w[15], 8); + R12(a2, b2, c2, d2, e2, w[12], 6); + + R21(e1, a1, b1, c1, d1, w[7], 7); + R22(e2, a2, b2, c2, d2, w[6], 9); + R21(d1, e1, a1, b1, c1, w[4], 6); + R22(d2, e2, a2, b2, c2, w[11], 13); + R21(c1, d1, e1, a1, b1, w[13], 8); + R22(c2, d2, e2, a2, b2, w[3], 15); + R21(b1, c1, d1, e1, a1, w[1], 13); + R22(b2, c2, d2, e2, a2, w[7], 7); + R21(a1, b1, c1, d1, e1, w[10], 11); + R22(a2, b2, c2, d2, e2, w[0], 12); + R21(e1, a1, b1, c1, d1, w[6], 9); + R22(e2, a2, b2, c2, d2, w[13], 8); + R21(d1, e1, a1, b1, c1, w[15], 7); + R22(d2, e2, a2, b2, c2, w[5], 9); + R21(c1, d1, e1, a1, b1, w[3], 15); + R22(c2, d2, e2, a2, b2, w[10], 11); + R21(b1, c1, d1, e1, a1, w[12], 7); + R22(b2, c2, d2, e2, a2, w[14], 7); + R21(a1, b1, c1, d1, e1, w[0], 12); + R22(a2, b2, c2, d2, e2, w[15], 7); + R21(e1, a1, b1, c1, d1, w[9], 15); + R22(e2, a2, b2, c2, d2, w[8], 12); + R21(d1, e1, a1, b1, c1, w[5], 9); + R22(d2, e2, a2, b2, c2, w[12], 7); + R21(c1, d1, e1, a1, b1, w[2], 11); + R22(c2, d2, e2, a2, b2, w[4], 6); + R21(b1, c1, d1, e1, a1, w[14], 7); + R22(b2, c2, d2, e2, a2, w[9], 15); + R21(a1, b1, c1, d1, e1, w[11], 13); + R22(a2, b2, c2, d2, e2, w[1], 13); + R21(e1, a1, b1, c1, d1, w[8], 12); + R22(e2, a2, b2, c2, d2, w[2], 11); + + R31(d1, e1, a1, b1, c1, w[3], 11); + R32(d2, e2, a2, b2, c2, w[15], 9); + R31(c1, d1, e1, a1, b1, w[10], 13); + R32(c2, d2, e2, a2, b2, w[5], 7); + R31(b1, c1, d1, e1, a1, w[14], 6); + R32(b2, c2, d2, e2, a2, w[1], 15); + R31(a1, b1, c1, d1, e1, w[4], 7); + R32(a2, b2, c2, d2, e2, w[3], 11); + R31(e1, a1, b1, c1, d1, w[9], 14); + R32(e2, a2, b2, c2, d2, w[7], 8); + R31(d1, e1, a1, b1, c1, w[15], 9); + R32(d2, e2, a2, b2, c2, w[14], 6); + R31(c1, d1, e1, a1, b1, w[8], 13); + R32(c2, d2, e2, a2, b2, w[6], 6); + R31(b1, c1, d1, e1, a1, w[1], 15); + R32(b2, c2, d2, e2, a2, w[9], 14); + R31(a1, b1, c1, d1, e1, w[2], 14); + R32(a2, b2, c2, d2, e2, w[11], 12); + R31(e1, a1, b1, c1, d1, w[7], 8); + R32(e2, a2, b2, c2, d2, w[8], 13); + R31(d1, e1, a1, b1, c1, w[0], 13); + R32(d2, e2, a2, b2, c2, w[12], 5); + R31(c1, d1, e1, a1, b1, w[6], 6); + R32(c2, d2, e2, a2, b2, w[2], 14); + R31(b1, c1, d1, e1, a1, w[13], 5); + R32(b2, c2, d2, e2, a2, w[10], 13); + R31(a1, b1, c1, d1, e1, w[11], 12); + R32(a2, b2, c2, d2, e2, w[0], 13); + R31(e1, a1, b1, c1, d1, w[5], 7); + R32(e2, a2, b2, c2, d2, w[4], 7); + R31(d1, e1, a1, b1, c1, w[12], 5); + R32(d2, e2, a2, b2, c2, w[13], 5); + + R41(c1, d1, e1, a1, b1, w[1], 11); + R42(c2, d2, e2, a2, b2, w[8], 15); + R41(b1, c1, d1, e1, a1, w[9], 12); + R42(b2, c2, d2, e2, a2, w[6], 5); + R41(a1, b1, c1, d1, e1, w[11], 14); + R42(a2, b2, c2, d2, e2, w[4], 8); + R41(e1, a1, b1, c1, d1, w[10], 15); + R42(e2, a2, b2, c2, d2, w[1], 11); + R41(d1, e1, a1, b1, c1, w[0], 14); + R42(d2, e2, a2, b2, c2, w[3], 14); + R41(c1, d1, e1, a1, b1, w[8], 15); + R42(c2, d2, e2, a2, b2, w[11], 14); + R41(b1, c1, d1, e1, a1, w[12], 9); + R42(b2, c2, d2, e2, a2, w[15], 6); + R41(a1, b1, c1, d1, e1, w[4], 8); + R42(a2, b2, c2, d2, e2, w[0], 14); + R41(e1, a1, b1, c1, d1, w[13], 9); + R42(e2, a2, b2, c2, d2, w[5], 6); + R41(d1, e1, a1, b1, c1, w[3], 14); + R42(d2, e2, a2, b2, c2, w[12], 9); + R41(c1, d1, e1, a1, b1, w[7], 5); + R42(c2, d2, e2, a2, b2, w[2], 12); + R41(b1, c1, d1, e1, a1, w[15], 6); + R42(b2, c2, d2, e2, a2, w[13], 9); + R41(a1, b1, c1, d1, e1, w[14], 8); + R42(a2, b2, c2, d2, e2, w[9], 12); + R41(e1, a1, b1, c1, d1, w[5], 6); + R42(e2, a2, b2, c2, d2, w[7], 5); + R41(d1, e1, a1, b1, c1, w[6], 5); + R42(d2, e2, a2, b2, c2, w[10], 15); + R41(c1, d1, e1, a1, b1, w[2], 12); + R42(c2, d2, e2, a2, b2, w[14], 8); + + R51(b1, c1, d1, e1, a1, w[4], 9); + R52(b2, c2, d2, e2, a2, w[12], 8); + R51(a1, b1, c1, d1, e1, w[0], 15); + R52(a2, b2, c2, d2, e2, w[15], 5); + R51(e1, a1, b1, c1, d1, w[5], 5); + R52(e2, a2, b2, c2, d2, w[10], 12); + R51(d1, e1, a1, b1, c1, w[9], 11); + R52(d2, e2, a2, b2, c2, w[4], 9); + R51(c1, d1, e1, a1, b1, w[7], 6); + R52(c2, d2, e2, a2, b2, w[1], 12); + R51(b1, c1, d1, e1, a1, w[12], 8); + R52(b2, c2, d2, e2, a2, w[5], 5); + R51(a1, b1, c1, d1, e1, w[2], 13); + R52(a2, b2, c2, d2, e2, w[8], 14); + R51(e1, a1, b1, c1, d1, w[10], 12); + R52(e2, a2, b2, c2, d2, w[7], 6); + R51(d1, e1, a1, b1, c1, w[14], 5); + R52(d2, e2, a2, b2, c2, w[6], 8); + R51(c1, d1, e1, a1, b1, w[1], 12); + R52(c2, d2, e2, a2, b2, w[2], 13); + R51(b1, c1, d1, e1, a1, w[3], 13); + R52(b2, c2, d2, e2, a2, w[13], 6); + R51(a1, b1, c1, d1, e1, w[8], 14); + R52(a2, b2, c2, d2, e2, w[14], 5); + R51(e1, a1, b1, c1, d1, w[11], 11); + R52(e2, a2, b2, c2, d2, w[0], 15); + R51(d1, e1, a1, b1, c1, w[6], 8); + R52(d2, e2, a2, b2, c2, w[3], 13); + R51(c1, d1, e1, a1, b1, w[15], 5); + R52(c2, d2, e2, a2, b2, w[9], 11); + R51(b1, c1, d1, e1, a1, w[13], 6); + R52(b2, c2, d2, e2, a2, w[11], 11); + + uint32_t t = s[0]; + s[0] = s[1] + c1 + d2; + s[1] = s[2] + d1 + e2; + s[2] = s[3] + e1 + a2; + s[3] = s[4] + a1 + b2; + s[4] = t + b1 + c2; +} + +} // namespace ripemd160 + +CRIPEMD160::CRIPEMD160() : bytes(0) +{ + _ripemd160::Initialize(s); +} + +void CRIPEMD160::Write(const unsigned char* data, size_t len) +{ + const unsigned char* end = data + len; + size_t bufsize = bytes % 64; + if (bufsize && bufsize + len >= 64) { + // Fill the buffer, and process it. + memcpy(buf + bufsize, data, 64 - bufsize); + bytes += 64 - bufsize; + data += 64 - bufsize; + _ripemd160::Transform(s, buf); + bufsize = 0; + } + while (end >= data + 64) { + // Process full chunks directly from the source. + _ripemd160::Transform(s, data); + bytes += 64; + data += 64; + } + if (end > data) { + // Fill the buffer with what remains. + memcpy(buf + bufsize, data, end - data); + bytes += end - data; + } +} + +void CRIPEMD160::Finalize(unsigned char hash[20]) +{ + static const unsigned char pad[64] = {0x80}; + unsigned char sizedesc[8]; + *(uint64_t *)sizedesc = bytes << 3; + Write(pad, 1 + ((119 - (bytes % 64)) % 64)); + Write(sizedesc, 8); + memcpy(hash,s,20); +} + +static const uint64_t sizedesc_32 = 32 << 3; +static const unsigned char pad[64] = { 0x80 }; + +void ripemd160_32(unsigned char *input, unsigned char *digest) { + + uint32_t *s = (uint32_t *)digest; + _ripemd160::Initialize(s); + memcpy(input+32,pad,24); + memcpy(input+56,&sizedesc_32,8); + _ripemd160::Transform(s, input); + +} + +void ripemd160(unsigned char *input,int length,unsigned char *digest) { + + CRIPEMD160 cripe; + cripe.Write(input,length); + cripe.Finalize(digest); + +} + +std::string ripemd160_hex(unsigned char *digest) { + + char buf[2 * 20 + 1]; + buf[2 * 20] = 0; + for (int i = 0; i < 20; i++) + sprintf(buf + i * 2, "%02x", (int)digest[i]); + return std::string(buf); + +} diff --git a/hash/ripemd160.h b/hash/ripemd160.h new file mode 100644 index 0000000..1c8f74b --- /dev/null +++ b/hash/ripemd160.h @@ -0,0 +1,56 @@ +/* + * This file is part of the VanitySearch distribution (https://github.com/JeanLucPons/VanitySearch). + * Copyright (c) 2019 Jean Luc PONS. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +#ifndef RIPEMD160_H +#define RIPEMD160_H + +#include +#include +#include + +/** A hasher class for RIPEMD-160. */ +class CRIPEMD160 +{ +private: + uint32_t s[5]; + unsigned char buf[64]; + uint64_t bytes; + +public: + CRIPEMD160(); + void Write(const unsigned char* data, size_t len); + void Finalize(unsigned char hash[20]); +}; + +void ripemd160(unsigned char *input,int length,unsigned char *digest); +void ripemd160_32(unsigned char *input, unsigned char *digest); +void ripemd160sse_32(uint8_t *i0, uint8_t *i1, uint8_t *i2, uint8_t *i3, + uint8_t *d0, uint8_t *d1, uint8_t *d2, uint8_t *d3); +void ripemd160sse_test(); +std::string ripemd160_hex(unsigned char *digest); + +static inline bool ripemd160_comp_hash(uint8_t *h0, uint8_t *h1) { + uint32_t *h0i = (uint32_t *)h0; + uint32_t *h1i = (uint32_t *)h1; + return (h0i[0] == h1i[0]) && + (h0i[1] == h1i[1]) && + (h0i[2] == h1i[2]) && + (h0i[3] == h1i[3]) && + (h0i[4] == h1i[4]); +} + +#endif // RIPEMD160_H diff --git a/hash/ripemd160_sse.cpp b/hash/ripemd160_sse.cpp new file mode 100644 index 0000000..20ff459 --- /dev/null +++ b/hash/ripemd160_sse.cpp @@ -0,0 +1,409 @@ +/* + * This file is part of the VanitySearch distribution (https://github.com/JeanLucPons/VanitySearch). + * Copyright (c) 2019 Jean Luc PONS. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +#include "ripemd160.h" +#include +#include + +// Internal SSE RIPEMD-160 implementation. +namespace ripemd160sse { + +#ifdef WIN64 + static const __declspec(align(16)) uint32_t _init[] = { +#else + static const uint32_t _init[] __attribute__ ((aligned (16))) = { +#endif + 0x67452301ul,0x67452301ul,0x67452301ul,0x67452301ul, + 0xEFCDAB89ul,0xEFCDAB89ul,0xEFCDAB89ul,0xEFCDAB89ul, + 0x98BADCFEul,0x98BADCFEul,0x98BADCFEul,0x98BADCFEul, + 0x10325476ul,0x10325476ul,0x10325476ul,0x10325476ul, + 0xC3D2E1F0ul,0xC3D2E1F0ul,0xC3D2E1F0ul,0xC3D2E1F0ul + }; + +//#define f1(x, y, z) (x ^ y ^ z) +//#define f2(x, y, z) ((x & y) | (~x & z)) +//#define f3(x, y, z) ((x | ~y) ^ z) +//#define f4(x, y, z) ((x & z) | (~z & y)) +//#define f5(x, y, z) (x ^ (y | ~z)) + +#define ROL(x,n) _mm_or_si128( _mm_slli_epi32(x, n) , _mm_srli_epi32(x, 32 - n) ) + +#ifdef WIN64 + +#define not(x) _mm_andnot_si128(x, _mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128())) +#define f1(x,y,z) _mm_xor_si128(x, _mm_xor_si128(y, z)) +#define f2(x,y,z) _mm_or_si128(_mm_and_si128(x,y),_mm_andnot_si128(x,z)) +#define f3(x,y,z) _mm_xor_si128(_mm_or_si128(x,not(y)),z) +#define f4(x,y,z) _mm_or_si128(_mm_and_si128(x,z),_mm_andnot_si128(z,y)) +#define f5(x,y,z) _mm_xor_si128(x,_mm_or_si128(y,not(z))) + +#else + +#define f1(x,y,z) _mm_xor_si128(x, _mm_xor_si128(y, z)) +#define f2(x,y,z) _mm_or_si128(_mm_and_si128(x,y),_mm_andnot_si128(x,z)) +#define f3(x,y,z) _mm_xor_si128(_mm_or_si128(x,~(y)),z) +#define f4(x,y,z) _mm_or_si128(_mm_and_si128(x,z),_mm_andnot_si128(z,y)) +#define f5(x,y,z) _mm_xor_si128(x,_mm_or_si128(y,~(z))) + +#endif + + +#define add3(x0, x1, x2 ) _mm_add_epi32(_mm_add_epi32(x0, x1), x2) +#define add4(x0, x1, x2, x3) _mm_add_epi32(_mm_add_epi32(x0, x1), _mm_add_epi32(x2, x3)) + +#define Round(a,b,c,d,e,f,x,k,r) \ + u = add4(a,f,x,_mm_set1_epi32(k)); \ + a = _mm_add_epi32(ROL(u, r),e); \ + c = ROL(c, 10); + +#define R11(a,b,c,d,e,x,r) Round(a, b, c, d, e, f1(b, c, d), x, 0, r) +#define R21(a,b,c,d,e,x,r) Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r) +#define R31(a,b,c,d,e,x,r) Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r) +#define R41(a,b,c,d,e,x,r) Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r) +#define R51(a,b,c,d,e,x,r) Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r) +#define R12(a,b,c,d,e,x,r) Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r) +#define R22(a,b,c,d,e,x,r) Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r) +#define R32(a,b,c,d,e,x,r) Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r) +#define R42(a,b,c,d,e,x,r) Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r) +#define R52(a,b,c,d,e,x,r) Round(a, b, c, d, e, f1(b, c, d), x, 0, r) + +#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)) + + // Initialize RIPEMD-160 state + void Initialize(__m128i *s) { + memcpy(s, _init, sizeof(_init)); + } + + // Perform 4 RIPE in parallel using SSE2 + void Transform(__m128i *s, uint8_t *blk[4]) { + + __m128i a1 = _mm_load_si128(s + 0); + __m128i b1 = _mm_load_si128(s + 1); + __m128i c1 = _mm_load_si128(s + 2); + __m128i d1 = _mm_load_si128(s + 3); + __m128i e1 = _mm_load_si128(s + 4); + __m128i a2 = a1; + __m128i b2 = b1; + __m128i c2 = c1; + __m128i d2 = d1; + __m128i e2 = e1; + __m128i u; + __m128i w[16]; + + + w[0] = LOADW(0); + w[1] = LOADW(1); + w[2] = LOADW(2); + w[3] = LOADW(3); + w[4] = LOADW(4); + w[5] = LOADW(5); + w[6] = LOADW(6); + w[7] = LOADW(7); + w[8] = LOADW(8); + w[9] = LOADW(9); + w[10] = LOADW(10); + w[11] = LOADW(11); + w[12] = LOADW(12); + w[13] = LOADW(13); + w[14] = LOADW(14); + w[15] = LOADW(15); + + R11(a1, b1, c1, d1, e1, w[0], 11); + R12(a2, b2, c2, d2, e2, w[5], 8); + R11(e1, a1, b1, c1, d1, w[1], 14); + R12(e2, a2, b2, c2, d2, w[14], 9); + R11(d1, e1, a1, b1, c1, w[2], 15); + R12(d2, e2, a2, b2, c2, w[7], 9); + R11(c1, d1, e1, a1, b1, w[3], 12); + R12(c2, d2, e2, a2, b2, w[0], 11); + R11(b1, c1, d1, e1, a1, w[4], 5); + R12(b2, c2, d2, e2, a2, w[9], 13); + R11(a1, b1, c1, d1, e1, w[5], 8); + R12(a2, b2, c2, d2, e2, w[2], 15); + R11(e1, a1, b1, c1, d1, w[6], 7); + R12(e2, a2, b2, c2, d2, w[11], 15); + R11(d1, e1, a1, b1, c1, w[7], 9); + R12(d2, e2, a2, b2, c2, w[4], 5); + R11(c1, d1, e1, a1, b1, w[8], 11); + R12(c2, d2, e2, a2, b2, w[13], 7); + R11(b1, c1, d1, e1, a1, w[9], 13); + R12(b2, c2, d2, e2, a2, w[6], 7); + R11(a1, b1, c1, d1, e1, w[10], 14); + R12(a2, b2, c2, d2, e2, w[15], 8); + R11(e1, a1, b1, c1, d1, w[11], 15); + R12(e2, a2, b2, c2, d2, w[8], 11); + R11(d1, e1, a1, b1, c1, w[12], 6); + R12(d2, e2, a2, b2, c2, w[1], 14); + R11(c1, d1, e1, a1, b1, w[13], 7); + R12(c2, d2, e2, a2, b2, w[10], 14); + R11(b1, c1, d1, e1, a1, w[14], 9); + R12(b2, c2, d2, e2, a2, w[3], 12); + R11(a1, b1, c1, d1, e1, w[15], 8); + R12(a2, b2, c2, d2, e2, w[12], 6); + + R21(e1, a1, b1, c1, d1, w[7], 7); + R22(e2, a2, b2, c2, d2, w[6], 9); + R21(d1, e1, a1, b1, c1, w[4], 6); + R22(d2, e2, a2, b2, c2, w[11], 13); + R21(c1, d1, e1, a1, b1, w[13], 8); + R22(c2, d2, e2, a2, b2, w[3], 15); + R21(b1, c1, d1, e1, a1, w[1], 13); + R22(b2, c2, d2, e2, a2, w[7], 7); + R21(a1, b1, c1, d1, e1, w[10], 11); + R22(a2, b2, c2, d2, e2, w[0], 12); + R21(e1, a1, b1, c1, d1, w[6], 9); + R22(e2, a2, b2, c2, d2, w[13], 8); + R21(d1, e1, a1, b1, c1, w[15], 7); + R22(d2, e2, a2, b2, c2, w[5], 9); + R21(c1, d1, e1, a1, b1, w[3], 15); + R22(c2, d2, e2, a2, b2, w[10], 11); + R21(b1, c1, d1, e1, a1, w[12], 7); + R22(b2, c2, d2, e2, a2, w[14], 7); + R21(a1, b1, c1, d1, e1, w[0], 12); + R22(a2, b2, c2, d2, e2, w[15], 7); + R21(e1, a1, b1, c1, d1, w[9], 15); + R22(e2, a2, b2, c2, d2, w[8], 12); + R21(d1, e1, a1, b1, c1, w[5], 9); + R22(d2, e2, a2, b2, c2, w[12], 7); + R21(c1, d1, e1, a1, b1, w[2], 11); + R22(c2, d2, e2, a2, b2, w[4], 6); + R21(b1, c1, d1, e1, a1, w[14], 7); + R22(b2, c2, d2, e2, a2, w[9], 15); + R21(a1, b1, c1, d1, e1, w[11], 13); + R22(a2, b2, c2, d2, e2, w[1], 13); + R21(e1, a1, b1, c1, d1, w[8], 12); + R22(e2, a2, b2, c2, d2, w[2], 11); + + R31(d1, e1, a1, b1, c1, w[3], 11); + R32(d2, e2, a2, b2, c2, w[15], 9); + R31(c1, d1, e1, a1, b1, w[10], 13); + R32(c2, d2, e2, a2, b2, w[5], 7); + R31(b1, c1, d1, e1, a1, w[14], 6); + R32(b2, c2, d2, e2, a2, w[1], 15); + R31(a1, b1, c1, d1, e1, w[4], 7); + R32(a2, b2, c2, d2, e2, w[3], 11); + R31(e1, a1, b1, c1, d1, w[9], 14); + R32(e2, a2, b2, c2, d2, w[7], 8); + R31(d1, e1, a1, b1, c1, w[15], 9); + R32(d2, e2, a2, b2, c2, w[14], 6); + R31(c1, d1, e1, a1, b1, w[8], 13); + R32(c2, d2, e2, a2, b2, w[6], 6); + R31(b1, c1, d1, e1, a1, w[1], 15); + R32(b2, c2, d2, e2, a2, w[9], 14); + R31(a1, b1, c1, d1, e1, w[2], 14); + R32(a2, b2, c2, d2, e2, w[11], 12); + R31(e1, a1, b1, c1, d1, w[7], 8); + R32(e2, a2, b2, c2, d2, w[8], 13); + R31(d1, e1, a1, b1, c1, w[0], 13); + R32(d2, e2, a2, b2, c2, w[12], 5); + R31(c1, d1, e1, a1, b1, w[6], 6); + R32(c2, d2, e2, a2, b2, w[2], 14); + R31(b1, c1, d1, e1, a1, w[13], 5); + R32(b2, c2, d2, e2, a2, w[10], 13); + R31(a1, b1, c1, d1, e1, w[11], 12); + R32(a2, b2, c2, d2, e2, w[0], 13); + R31(e1, a1, b1, c1, d1, w[5], 7); + R32(e2, a2, b2, c2, d2, w[4], 7); + R31(d1, e1, a1, b1, c1, w[12], 5); + R32(d2, e2, a2, b2, c2, w[13], 5); + + R41(c1, d1, e1, a1, b1, w[1], 11); + R42(c2, d2, e2, a2, b2, w[8], 15); + R41(b1, c1, d1, e1, a1, w[9], 12); + R42(b2, c2, d2, e2, a2, w[6], 5); + R41(a1, b1, c1, d1, e1, w[11], 14); + R42(a2, b2, c2, d2, e2, w[4], 8); + R41(e1, a1, b1, c1, d1, w[10], 15); + R42(e2, a2, b2, c2, d2, w[1], 11); + R41(d1, e1, a1, b1, c1, w[0], 14); + R42(d2, e2, a2, b2, c2, w[3], 14); + R41(c1, d1, e1, a1, b1, w[8], 15); + R42(c2, d2, e2, a2, b2, w[11], 14); + R41(b1, c1, d1, e1, a1, w[12], 9); + R42(b2, c2, d2, e2, a2, w[15], 6); + R41(a1, b1, c1, d1, e1, w[4], 8); + R42(a2, b2, c2, d2, e2, w[0], 14); + R41(e1, a1, b1, c1, d1, w[13], 9); + R42(e2, a2, b2, c2, d2, w[5], 6); + R41(d1, e1, a1, b1, c1, w[3], 14); + R42(d2, e2, a2, b2, c2, w[12], 9); + R41(c1, d1, e1, a1, b1, w[7], 5); + R42(c2, d2, e2, a2, b2, w[2], 12); + R41(b1, c1, d1, e1, a1, w[15], 6); + R42(b2, c2, d2, e2, a2, w[13], 9); + R41(a1, b1, c1, d1, e1, w[14], 8); + R42(a2, b2, c2, d2, e2, w[9], 12); + R41(e1, a1, b1, c1, d1, w[5], 6); + R42(e2, a2, b2, c2, d2, w[7], 5); + R41(d1, e1, a1, b1, c1, w[6], 5); + R42(d2, e2, a2, b2, c2, w[10], 15); + R41(c1, d1, e1, a1, b1, w[2], 12); + R42(c2, d2, e2, a2, b2, w[14], 8); + + R51(b1, c1, d1, e1, a1, w[4], 9); + R52(b2, c2, d2, e2, a2, w[12], 8); + R51(a1, b1, c1, d1, e1, w[0], 15); + R52(a2, b2, c2, d2, e2, w[15], 5); + R51(e1, a1, b1, c1, d1, w[5], 5); + R52(e2, a2, b2, c2, d2, w[10], 12); + R51(d1, e1, a1, b1, c1, w[9], 11); + R52(d2, e2, a2, b2, c2, w[4], 9); + R51(c1, d1, e1, a1, b1, w[7], 6); + R52(c2, d2, e2, a2, b2, w[1], 12); + R51(b1, c1, d1, e1, a1, w[12], 8); + R52(b2, c2, d2, e2, a2, w[5], 5); + R51(a1, b1, c1, d1, e1, w[2], 13); + R52(a2, b2, c2, d2, e2, w[8], 14); + R51(e1, a1, b1, c1, d1, w[10], 12); + R52(e2, a2, b2, c2, d2, w[7], 6); + R51(d1, e1, a1, b1, c1, w[14], 5); + R52(d2, e2, a2, b2, c2, w[6], 8); + R51(c1, d1, e1, a1, b1, w[1], 12); + R52(c2, d2, e2, a2, b2, w[2], 13); + R51(b1, c1, d1, e1, a1, w[3], 13); + R52(b2, c2, d2, e2, a2, w[13], 6); + R51(a1, b1, c1, d1, e1, w[8], 14); + R52(a2, b2, c2, d2, e2, w[14], 5); + R51(e1, a1, b1, c1, d1, w[11], 11); + R52(e2, a2, b2, c2, d2, w[0], 15); + R51(d1, e1, a1, b1, c1, w[6], 8); + R52(d2, e2, a2, b2, c2, w[3], 13); + R51(c1, d1, e1, a1, b1, w[15], 5); + R52(c2, d2, e2, a2, b2, w[9], 11); + R51(b1, c1, d1, e1, a1, w[13], 6); + R52(b2, c2, d2, e2, a2, w[11], 11); + + __m128i t = s[0]; + s[0] = add3(s[1],c1,d2); + s[1] = add3(s[2],d1,e2); + s[2] = add3(s[3],e1,a2); + s[3] = add3(s[4],a1,b2); + s[4] = add3(t,b1,c2); + } + +} // namespace ripemd160sse + +#ifdef WIN64 + +#define DEPACK(d,i) \ +((uint32_t *)d)[0] = s[0].m128i_u32[i]; \ +((uint32_t *)d)[1] = s[1].m128i_u32[i]; \ +((uint32_t *)d)[2] = s[2].m128i_u32[i]; \ +((uint32_t *)d)[3] = s[3].m128i_u32[i]; \ +((uint32_t *)d)[4] = s[4].m128i_u32[i]; + +#else + +#define DEPACK(d,i) \ +((uint32_t *)d)[0] = s0[i]; \ +((uint32_t *)d)[1] = s1[i]; \ +((uint32_t *)d)[2] = s2[i]; \ +((uint32_t *)d)[3] = s3[i]; \ +((uint32_t *)d)[4] = s4[i]; + +#endif + +static const uint64_t sizedesc_32 = 32 << 3; +static const unsigned char pad[64] = { 0x80 }; + +void ripemd160sse_32( + unsigned char *i0, + unsigned char *i1, + unsigned char *i2, + unsigned char *i3, + unsigned char *d0, + unsigned char *d1, + unsigned char *d2, + unsigned char *d3) { + + __m128i s[5]; + uint8_t *bs[] = { i0,i1,i2,i3 }; + + ripemd160sse::Initialize(s); + memcpy(i0 + 32, pad, 24); + memcpy(i0 + 56, &sizedesc_32, 8); + memcpy(i1 + 32, pad, 24); + memcpy(i1 + 56, &sizedesc_32, 8); + memcpy(i2 + 32, pad, 24); + memcpy(i2 + 56, &sizedesc_32, 8); + memcpy(i3 + 32, pad, 24); + memcpy(i3 + 56, &sizedesc_32, 8); + + ripemd160sse::Transform(s, bs); + +#ifndef WIN64 + uint32_t *s0 = (uint32_t *)&s[0]; + uint32_t *s1 = (uint32_t *)&s[1]; + uint32_t *s2 = (uint32_t *)&s[2]; + uint32_t *s3 = (uint32_t *)&s[3]; + uint32_t *s4 = (uint32_t *)&s[4]; +#endif + + DEPACK(d0,3); + DEPACK(d1,2); + DEPACK(d2,1); + DEPACK(d3,0); + +} + +void ripemd160sse_test() { + + unsigned char h0[20]; + unsigned char h1[20]; + unsigned char h2[20]; + unsigned char h3[20]; + unsigned char ch0[20]; + unsigned char ch1[20]; + unsigned char ch2[20]; + unsigned char ch3[20]; + unsigned char m0[64]; + unsigned char m1[64]; + unsigned char m2[64]; + unsigned char m3[64]; + + strcpy((char *)m0, "This is a test message to test01"); + strcpy((char *)m1, "This is a test message to test02"); + strcpy((char *)m2, "This is a test message to test03"); + strcpy((char *)m3, "This is a test message to test04"); + + ripemd160_32(m0, ch0); + ripemd160_32(m1, ch1); + ripemd160_32(m2, ch2); + ripemd160_32(m3, ch3); + + ripemd160sse_32(m0, m1, m2, m3, h0, h1, h2, h3); + + if ((ripemd160_hex(h0) != ripemd160_hex(ch0)) || + (ripemd160_hex(h1) != ripemd160_hex(ch1)) || + (ripemd160_hex(h2) != ripemd160_hex(ch2)) || + (ripemd160_hex(h3) != ripemd160_hex(ch3))) { + + printf("RIPEMD160() Results Wrong !\n"); + printf("RIP: %s\n", ripemd160_hex(ch0).c_str()); + printf("RIP: %s\n", ripemd160_hex(ch1).c_str()); + printf("RIP: %s\n", ripemd160_hex(ch2).c_str()); + printf("RIP: %s\n\n", ripemd160_hex(ch3).c_str()); + printf("SSE: %s\n", ripemd160_hex(h0).c_str()); + printf("SSE: %s\n", ripemd160_hex(h1).c_str()); + printf("SSE: %s\n", ripemd160_hex(h2).c_str()); + printf("SSE: %s\n\n", ripemd160_hex(h3).c_str()); + + } + + printf("RIPE() Results OK !\n"); + +} diff --git a/hash/sha256.cpp b/hash/sha256.cpp new file mode 100644 index 0000000..682371e --- /dev/null +++ b/hash/sha256.cpp @@ -0,0 +1,502 @@ +/* + * This file is part of the VanitySearch distribution (https://github.com/JeanLucPons/VanitySearch). + * Copyright (c) 2019 Jean Luc PONS. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +#include +#include "sha256.h" + +#define BSWAP + +/// Internal SHA-256 implementation. +namespace _sha256 +{ + + static const unsigned char pad[64] = { 0x80 }; + +#ifndef WIN64 +#define _byteswap_ulong __builtin_bswap32 +#define _byteswap_uint64 __builtin_bswap64 +inline uint32_t _rotr(uint32_t x, uint8_t r) { + asm("rorl %1,%0" : "+r" (x) : "c" (r)); + return x; +} +#endif + +#define ROR(x,n) _rotr(x, n) +#define S0(x) (ROR(x,2) ^ ROR(x,13) ^ ROR(x,22)) +#define S1(x) (ROR(x,6) ^ ROR(x,11) ^ ROR(x,25)) +#define s0(x) (ROR(x,7) ^ ROR(x,18) ^ (x >> 3)) +#define s1(x) (ROR(x,17) ^ ROR(x,19) ^ (x >> 10)) + +#define Maj(x,y,z) ((x&y)^(x&z)^(y&z)) +//#define Ch(x,y,z) ((x&y)^(~x&z)) + +// The following functions are equivalent to the above +//#define Maj(x,y,z) ((x & y) | (z & (x | y))) +#define Ch(x,y,z) (z ^ (x & (y ^ z))) + +// SHA-256 round +#define Round(a, b, c, d, e, f, g, h, k, w) \ + t1 = h + S1(e) + Ch(e,f,g) + k + (w); \ + t2 = S0(a) + Maj(a,b,c); \ + d += t1; \ + h = t1 + t2; + +#ifdef BSWAP +#define WRITEBE32(ptr,x) *((uint32_t *)(ptr)) = _byteswap_ulong(x) +#define WRITEBE64(ptr,x) *((uint64_t *)(ptr)) = _byteswap_uint64(x) +#define READBE32(ptr) (uint32_t)_byteswap_ulong(*(uint32_t *)(ptr)) +#else +#define WRITEBE32(ptr,x) *(ptr) = x +#define WRITEBE64(ptr,x) *(ptr) = x +#define READBE32(ptr) *(uint32_t *)(ptr) +#endif + + // Initialise state + void Initialize(uint32_t *s) { + + s[0] = 0x6a09e667ul; + s[1] = 0xbb67ae85ul; + s[2] = 0x3c6ef372ul; + s[3] = 0xa54ff53aul; + s[4] = 0x510e527ful; + s[5] = 0x9b05688cul; + s[6] = 0x1f83d9abul; + s[7] = 0x5be0cd19ul; + + } + + + // Perform SHA-256 transformations, process 64-byte chunks + void Transform(uint32_t* s, const unsigned char* chunk) + { + uint32_t t1; + uint32_t t2; + 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]; + uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; + + Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = READBE32(chunk + 0)); + Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = READBE32(chunk + 4)); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = READBE32(chunk + 8)); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = READBE32(chunk + 12)); + Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = READBE32(chunk + 16)); + Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = READBE32(chunk + 20)); + Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = READBE32(chunk + 24)); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = READBE32(chunk + 28)); + Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = READBE32(chunk + 32)); + Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = READBE32(chunk + 36)); + Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = READBE32(chunk + 40)); + Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = READBE32(chunk + 44)); + Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = READBE32(chunk + 48)); + Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = READBE32(chunk + 52)); + Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = READBE32(chunk + 56)); + Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = READBE32(chunk + 60)); + + Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += s1(w14) + w9 + s0(w1)); + Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += s1(w15) + w10 + s0(w2)); + Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += s1(w0) + w11 + s0(w3)); + Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += s1(w1) + w12 + s0(w4)); + Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += s1(w2) + w13 + s0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += s1(w3) + w14 + s0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += s1(w4) + w15 + s0(w7)); + Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += s1(w5) + w0 + s0(w8)); + Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += s1(w6) + w1 + s0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += s1(w7) + w2 + s0(w10)); + Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += s1(w8) + w3 + s0(w11)); + Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += s1(w9) + w4 + s0(w12)); + Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += s1(w10) + w5 + s0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += s1(w11) + w6 + s0(w14)); + Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += s1(w12) + w7 + s0(w15)); + Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += s1(w13) + w8 + s0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += s1(w14) + w9 + s0(w1)); + Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += s1(w15) + w10 + s0(w2)); + Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += s1(w0) + w11 + s0(w3)); + Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += s1(w1) + w12 + s0(w4)); + Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += s1(w2) + w13 + s0(w5)); + Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += s1(w3) + w14 + s0(w6)); + Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += s1(w4) + w15 + s0(w7)); + Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += s1(w5) + w0 + s0(w8)); + Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += s1(w6) + w1 + s0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += s1(w7) + w2 + s0(w10)); + Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += s1(w8) + w3 + s0(w11)); + Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += s1(w9) + w4 + s0(w12)); + Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += s1(w10) + w5 + s0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += s1(w11) + w6 + s0(w14)); + Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += s1(w12) + w7 + s0(w15)); + Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += s1(w13) + w8 + s0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += s1(w14) + w9 + s0(w1)); + Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += s1(w15) + w10 + s0(w2)); + Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += s1(w0) + w11 + s0(w3)); + Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += s1(w1) + w12 + s0(w4)); + Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += s1(w2) + w13 + s0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += s1(w3) + w14 + s0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += s1(w4) + w15 + s0(w7)); + Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += s1(w5) + w0 + s0(w8)); + Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += s1(w6) + w1 + s0(w9)); + Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += s1(w7) + w2 + s0(w10)); + Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += s1(w8) + w3 + s0(w11)); + Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += s1(w9) + w4 + s0(w12)); + Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += s1(w10) + w5 + s0(w13)); + Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += s1(w11) + w6 + s0(w14)); + Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + s1(w12) + w7 + s0(w15)); + Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + s1(w13) + w8 + s0(w0)); + + s[0] += a; + s[1] += b; + s[2] += c; + s[3] += d; + s[4] += e; + s[5] += f; + s[6] += g; + s[7] += h; + + } + + // Compute SHA256(SHA256(chunk))[0] + void Transform2(uint32_t* s, const unsigned char* chunk) { + + uint32_t t1; + uint32_t t2; + uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; + + uint32_t a = 0x6a09e667ul; + uint32_t b = 0xbb67ae85ul; + uint32_t c = 0x3c6ef372ul; + uint32_t d = 0xa54ff53aul; + uint32_t e = 0x510e527ful; + uint32_t f = 0x9b05688cul; + uint32_t g = 0x1f83d9abul; + uint32_t h = 0x5be0cd19ul; + + Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = READBE32(chunk + 0)); + Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = READBE32(chunk + 4)); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = READBE32(chunk + 8)); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = READBE32(chunk + 12)); + Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = READBE32(chunk + 16)); + Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = READBE32(chunk + 20)); + Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = READBE32(chunk + 24)); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = READBE32(chunk + 28)); + Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = READBE32(chunk + 32)); + Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = READBE32(chunk + 36)); + Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = READBE32(chunk + 40)); + Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = READBE32(chunk + 44)); + Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = READBE32(chunk + 48)); + Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = READBE32(chunk + 52)); + Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = READBE32(chunk + 56)); + Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = READBE32(chunk + 60)); + + Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += s1(w14) + w9 + s0(w1)); + Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += s1(w15) + w10 + s0(w2)); + Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += s1(w0) + w11 + s0(w3)); + Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += s1(w1) + w12 + s0(w4)); + Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += s1(w2) + w13 + s0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += s1(w3) + w14 + s0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += s1(w4) + w15 + s0(w7)); + Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += s1(w5) + w0 + s0(w8)); + Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += s1(w6) + w1 + s0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += s1(w7) + w2 + s0(w10)); + Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += s1(w8) + w3 + s0(w11)); + Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += s1(w9) + w4 + s0(w12)); + Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += s1(w10) + w5 + s0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += s1(w11) + w6 + s0(w14)); + Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += s1(w12) + w7 + s0(w15)); + Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += s1(w13) + w8 + s0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += s1(w14) + w9 + s0(w1)); + Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += s1(w15) + w10 + s0(w2)); + Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += s1(w0) + w11 + s0(w3)); + Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += s1(w1) + w12 + s0(w4)); + Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += s1(w2) + w13 + s0(w5)); + Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += s1(w3) + w14 + s0(w6)); + Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += s1(w4) + w15 + s0(w7)); + Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += s1(w5) + w0 + s0(w8)); + Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += s1(w6) + w1 + s0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += s1(w7) + w2 + s0(w10)); + Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += s1(w8) + w3 + s0(w11)); + Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += s1(w9) + w4 + s0(w12)); + Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += s1(w10) + w5 + s0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += s1(w11) + w6 + s0(w14)); + Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += s1(w12) + w7 + s0(w15)); + Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += s1(w13) + w8 + s0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += s1(w14) + w9 + s0(w1)); + Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += s1(w15) + w10 + s0(w2)); + Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += s1(w0) + w11 + s0(w3)); + Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += s1(w1) + w12 + s0(w4)); + Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += s1(w2) + w13 + s0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += s1(w3) + w14 + s0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += s1(w4) + w15 + s0(w7)); + Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += s1(w5) + w0 + s0(w8)); + Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += s1(w6) + w1 + s0(w9)); + Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += s1(w7) + w2 + s0(w10)); + Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += s1(w8) + w3 + s0(w11)); + Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += s1(w9) + w4 + s0(w12)); + Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += s1(w10) + w5 + s0(w13)); + Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += s1(w11) + w6 + s0(w14)); + Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + s1(w12) + w7 + s0(w15)); + Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + s1(w13) + w8 + s0(w0)); + + w0 = 0x6a09e667ul + a; + w1 = 0xbb67ae85ul + b; + w2 = 0x3c6ef372ul + c; + w3 = 0xa54ff53aul + d; + w4 = 0x510e527ful + e; + w5 = 0x9b05688cul + f; + w6 = 0x1f83d9abul + g; + w7 = 0x5be0cd19ul + h; + w8 = 0x80000000; + w9 = 0; + w10 = 0; + w11 = 0; + w12 = 0; + w13 = 0; + w14 = 0; + w15 = 0x100; + + a = 0x6a09e667ul; + b = 0xbb67ae85ul; + c = 0x3c6ef372ul; + d = 0xa54ff53aul; + e = 0x510e527ful; + f = 0x9b05688cul; + g = 0x1f83d9abul; + h = 0x5be0cd19ul; + + Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0); + Round(h, a, b, c, d, e, f, g, 0x71374491, w1); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3); + Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4); + Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5); + Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7); + Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8); + Round(h, a, b, c, d, e, f, g, 0x12835b01, w9); + Round(g, h, a, b, c, d, e, f, 0x243185be, w10); + Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11); + Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12); + Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13); + Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14); + Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15); + + Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += s1(w14) + w9 + s0(w1)); + Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += s1(w15) + w10 + s0(w2)); + Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += s1(w0) + w11 + s0(w3)); + Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += s1(w1) + w12 + s0(w4)); + Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += s1(w2) + w13 + s0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += s1(w3) + w14 + s0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += s1(w4) + w15 + s0(w7)); + Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += s1(w5) + w0 + s0(w8)); + Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += s1(w6) + w1 + s0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += s1(w7) + w2 + s0(w10)); + Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += s1(w8) + w3 + s0(w11)); + Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += s1(w9) + w4 + s0(w12)); + Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += s1(w10) + w5 + s0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += s1(w11) + w6 + s0(w14)); + Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += s1(w12) + w7 + s0(w15)); + Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += s1(w13) + w8 + s0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += s1(w14) + w9 + s0(w1)); + Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += s1(w15) + w10 + s0(w2)); + Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += s1(w0) + w11 + s0(w3)); + Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += s1(w1) + w12 + s0(w4)); + Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += s1(w2) + w13 + s0(w5)); + Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += s1(w3) + w14 + s0(w6)); + Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += s1(w4) + w15 + s0(w7)); + Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += s1(w5) + w0 + s0(w8)); + Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += s1(w6) + w1 + s0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += s1(w7) + w2 + s0(w10)); + Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += s1(w8) + w3 + s0(w11)); + Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += s1(w9) + w4 + s0(w12)); + Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += s1(w10) + w5 + s0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += s1(w11) + w6 + s0(w14)); + Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += s1(w12) + w7 + s0(w15)); + Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += s1(w13) + w8 + s0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += s1(w14) + w9 + s0(w1)); + Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += s1(w15) + w10 + s0(w2)); + Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += s1(w0) + w11 + s0(w3)); + Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += s1(w1) + w12 + s0(w4)); + Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += s1(w2) + w13 + s0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += s1(w3) + w14 + s0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += s1(w4) + w15 + s0(w7)); + Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += s1(w5) + w0 + s0(w8)); + Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += s1(w6) + w1 + s0(w9)); + Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += s1(w7) + w2 + s0(w10)); + Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += s1(w8) + w3 + s0(w11)); + Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += s1(w9) + w4 + s0(w12)); + Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += s1(w10) + w5 + s0(w13)); + Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += s1(w11) + w6 + s0(w14)); + Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + s1(w12) + w7 + s0(w15)); + Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + s1(w13) + w8 + s0(w0)); + + s[0] = 0x6a09e667ul + a; + + } + +} // namespace sha256 + + +////// SHA-256 + +class CSHA256 +{ +private: + uint32_t s[8]; + unsigned char buf[64]; + uint64_t bytes; + +public: + static const size_t OUTPUT_SIZE = 32; + + CSHA256(); + void Write(const unsigned char* data, size_t len); + void Finalize(unsigned char hash[OUTPUT_SIZE]); + +}; + +CSHA256::CSHA256() { + bytes = 0; + s[0] = 0x6a09e667ul; + s[1] = 0xbb67ae85ul; + s[2] = 0x3c6ef372ul; + s[3] = 0xa54ff53aul; + s[4] = 0x510e527ful; + s[5] = 0x9b05688cul; + s[6] = 0x1f83d9abul; + s[7] = 0x5be0cd19ul; +} + +void CSHA256::Write(const unsigned char* data, size_t len) +{ + const unsigned char* end = data + len; + size_t bufsize = bytes % 64; + if (bufsize && bufsize + len >= 64) { + // Fill the buffer, and process it. + memcpy(buf + bufsize, data, 64 - bufsize); + bytes += 64 - bufsize; + data += 64 - bufsize; + _sha256::Transform(s, buf); + bufsize = 0; + } + while (end >= data + 64) { + // Process full chunks directly from the source. + _sha256::Transform(s, data); + bytes += 64; + data += 64; + } + if (end > data) { + // Fill the buffer with what remains. + memcpy(buf + bufsize, data, end - data); + bytes += end - data; + } +} + +void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE]) +{ + unsigned char sizedesc[8]; + WRITEBE64(sizedesc, bytes << 3); + Write(_sha256::pad, 1 + ((119 - (bytes % 64)) % 64)); + Write(sizedesc, 8); + WRITEBE32(hash, s[0]); + WRITEBE32(hash + 4, s[1]); + WRITEBE32(hash + 8, s[2]); + WRITEBE32(hash + 12, s[3]); + WRITEBE32(hash + 16, s[4]); + WRITEBE32(hash + 20, s[5]); + WRITEBE32(hash + 24, s[6]); + WRITEBE32(hash + 28, s[7]); +} + +void sha256(unsigned char *input, size_t length, unsigned char *digest) { + + CSHA256 sha; + sha.Write(input, length); + sha.Finalize(digest); + +} + +const uint8_t sizedesc_32[8] = { 0,0,0,0,0,0,1,0 }; +const uint8_t sizedesc_33[8] = { 0,0,0,0,0,0,1,8 }; +const uint8_t sizedesc_65[8] = { 0,0,0,0,0,0,2,8 }; + +void sha256_33(unsigned char *input, unsigned char *digest) { + + uint32_t s[8]; + + _sha256::Initialize(s); + memcpy(input + 33, _sha256::pad, 23); + memcpy(input + 56, sizedesc_33, 8); + _sha256::Transform(s, input); + + WRITEBE32(digest, s[0]); + WRITEBE32(digest + 4, s[1]); + WRITEBE32(digest + 8, s[2]); + WRITEBE32(digest + 12, s[3]); + WRITEBE32(digest + 16, s[4]); + WRITEBE32(digest + 20, s[5]); + WRITEBE32(digest + 24, s[6]); + WRITEBE32(digest + 28, s[7]); + + +} + +void sha256_65(unsigned char *input, unsigned char *digest) { + + uint32_t s[8]; + + memcpy(input + 65, _sha256::pad, 55); + memcpy(input + 120, sizedesc_65, 8); + + _sha256::Initialize(s); + _sha256::Transform(s, input); + _sha256::Transform(s, input+64); + + WRITEBE32(digest, s[0]); + WRITEBE32(digest + 4, s[1]); + WRITEBE32(digest + 8, s[2]); + WRITEBE32(digest + 12, s[3]); + WRITEBE32(digest + 16, s[4]); + WRITEBE32(digest + 20, s[5]); + WRITEBE32(digest + 24, s[6]); + WRITEBE32(digest + 28, s[7]); + +} + +void sha256_checksum(uint8_t *input, int length, uint8_t *checksum) { + + uint32_t s[8]; + uint8_t b[64]; + memcpy(b,input,length); + memcpy(b + length, _sha256::pad, 56-length); + WRITEBE64(b + 56, length << 3); + _sha256::Transform2(s, b); + WRITEBE32(checksum,s[0]); + +} + +std::string sha256_hex(unsigned char *digest) { + + char buf[2*32+1]; + buf[2*32] = 0; + for (int i = 0; i < 32; i++) + sprintf(buf+i*2,"%02x",digest[i]); + return std::string(buf); + +} + diff --git a/hash/sha256.h b/hash/sha256.h new file mode 100644 index 0000000..b7ad808 --- /dev/null +++ b/hash/sha256.h @@ -0,0 +1,35 @@ +/* + * This file is part of the VanitySearch distribution (https://github.com/JeanLucPons/VanitySearch). + * Copyright (c) 2019 Jean Luc PONS. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +#ifndef SHA256_H +#define SHA256_H +#include + +void sha256(uint8_t *input,size_t length, uint8_t *digest); +void sha256_33(uint8_t *input, uint8_t *digest); +void sha256_65(uint8_t *input, uint8_t *digest); +void sha256_checksum(uint8_t *input, int length, uint8_t *checksum); +void sha256sse_1B(uint32_t *i0, uint32_t *i1, uint32_t *i2, uint32_t *i3, + uint8_t *d0, uint8_t *d1, uint8_t *d2, uint8_t *d3); +void sha256sse_2B(uint32_t *i0, uint32_t *i1, uint32_t *i2, uint32_t *i3, + uint8_t *d0, uint8_t *d1, uint8_t *d2, uint8_t *d3); +void sha256sse_checksum(uint32_t *i0, uint32_t *i1, uint32_t *i2, uint32_t *i3, + uint8_t *d0, uint8_t *d1, uint8_t *d2, uint8_t *d3); +std::string sha256_hex(unsigned char *digest); +void sha256sse_test(); + +#endif \ No newline at end of file diff --git a/hash/sha256_sse.cpp b/hash/sha256_sse.cpp new file mode 100644 index 0000000..8e0f6cc --- /dev/null +++ b/hash/sha256_sse.cpp @@ -0,0 +1,627 @@ +/* + * This file is part of the VanitySearch distribution (https://github.com/JeanLucPons/VanitySearch). + * Copyright (c) 2019 Jean Luc PONS. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +#include "sha256.h" +#include +#include +#include + +namespace _sha256sse +{ + + +#ifdef WIN64 + static const __declspec(align(16)) uint32_t _init[] = { +#else + static const uint32_t _init[] __attribute__ ((aligned (16))) = { +#endif + 0x6a09e667,0x6a09e667,0x6a09e667,0x6a09e667, + 0xbb67ae85,0xbb67ae85,0xbb67ae85,0xbb67ae85, + 0x3c6ef372,0x3c6ef372,0x3c6ef372,0x3c6ef372, + 0xa54ff53a,0xa54ff53a,0xa54ff53a,0xa54ff53a, + 0x510e527f,0x510e527f,0x510e527f,0x510e527f, + 0x9b05688c,0x9b05688c,0x9b05688c,0x9b05688c, + 0x1f83d9ab,0x1f83d9ab,0x1f83d9ab,0x1f83d9ab, + 0x5be0cd19,0x5be0cd19,0x5be0cd19,0x5be0cd19 + }; + +//#define Maj(x,y,z) ((x&y)^(x&z)^(y&z)) +//#define Ch(x,y,z) ((x&y)^(~x&z)) + +// The following functions are equivalent to the above +//#define Maj(x,y,z) ((x & y) | (z & (x | y))) +//#define Ch(x,y,z) (z ^ (x & (y ^ z))) + +#define Maj(b,c,d) _mm_or_si128(_mm_and_si128(b, c), _mm_and_si128(d, _mm_or_si128(b, c)) ) +#define Ch(b,c,d) _mm_xor_si128(_mm_and_si128(b, c) , _mm_andnot_si128(b , d) ) +#define ROR(x,n) _mm_or_si128( _mm_srli_epi32(x, n) , _mm_slli_epi32(x, 32 - n) ) +#define SHR(x,n) _mm_srli_epi32(x, n) + + /* SHA256 Functions */ +#define S0(x) (_mm_xor_si128(ROR((x), 2) , _mm_xor_si128(ROR((x), 13), ROR((x), 22)))) +#define S1(x) (_mm_xor_si128(ROR((x), 6) , _mm_xor_si128(ROR((x), 11), ROR((x), 25)))) +#define s0(x) (_mm_xor_si128(ROR((x), 7) , _mm_xor_si128(ROR((x), 18), SHR((x), 3)))) +#define s1(x) (_mm_xor_si128(ROR((x), 17), _mm_xor_si128(ROR((x), 19), SHR((x), 10)))) + +#define add4(x0, x1, x2, x3) _mm_add_epi32(_mm_add_epi32(x0, x1), _mm_add_epi32(x2, x3)) +#define add3(x0, x1, x2 ) _mm_add_epi32(_mm_add_epi32(x0, x1), x2) +#define add5(x0, x1, x2, x3, x4) _mm_add_epi32(add3(x0, x1, x2), _mm_add_epi32(x3, x4)) + + +#define Round(a, b, c, d, e, f, g, h, i, w) \ + T1 = add5(h, S1(e), Ch(e, f, g), _mm_set1_epi32(i), w); \ + d = _mm_add_epi32(d, T1); \ + T2 = _mm_add_epi32(S0(a), Maj(a, b, c)); \ + h = _mm_add_epi32(T1, T2); + +#define WMIX() \ + w0 = add4(s1(w14), w9, s0(w1), w0); \ + w1 = add4(s1(w15), w10, s0(w2), w1); \ + w2 = add4(s1(w0), w11, s0(w3), w2); \ + w3 = add4(s1(w1), w12, s0(w4), w3); \ + w4 = add4(s1(w2), w13, s0(w5), w4); \ + w5 = add4(s1(w3), w14, s0(w6), w5); \ + w6 = add4(s1(w4), w15, s0(w7), w6); \ + w7 = add4(s1(w5), w0, s0(w8), w7); \ + w8 = add4(s1(w6), w1, s0(w9), w8); \ + w9 = add4(s1(w7), w2, s0(w10), w9); \ + w10 = add4(s1(w8), w3, s0(w11), w10); \ + w11 = add4(s1(w9), w4, s0(w12), w11); \ + w12 = add4(s1(w10), w5, s0(w13), w12); \ + w13 = add4(s1(w11), w6, s0(w14), w13); \ + w14 = add4(s1(w12), w7, s0(w15), w14); \ + w15 = add4(s1(w13), w8, s0(w0), w15); + + // Initialise state + void Initialize(__m128i *s) { + memcpy(s, _init, sizeof(_init)); + } + + // Perform 4 SHA in parallel using SSE2 + void Transform(__m128i *s, uint32_t *b0, uint32_t *b1, uint32_t *b2, uint32_t *b3) + { + __m128i a,b,c,d,e,f,g,h; + __m128i w0, w1, w2, w3, w4, w5, w6, w7; + __m128i w8, w9, w10, w11, w12, w13, w14, w15; + __m128i T1, T2; + + a = _mm_load_si128(s + 0); + b = _mm_load_si128(s + 1); + c = _mm_load_si128(s + 2); + d = _mm_load_si128(s + 3); + e = _mm_load_si128(s + 4); + f = _mm_load_si128(s + 5); + g = _mm_load_si128(s + 6); + h = _mm_load_si128(s + 7); + + w0 = _mm_set_epi32(b0[0], b1[0], b2[0], b3[0]); + w1 = _mm_set_epi32(b0[1], b1[1], b2[1], b3[1]); + w2 = _mm_set_epi32(b0[2], b1[2], b2[2], b3[2]); + w3 = _mm_set_epi32(b0[3], b1[3], b2[3], b3[3]); + w4 = _mm_set_epi32(b0[4], b1[4], b2[4], b3[4]); + w5 = _mm_set_epi32(b0[5], b1[5], b2[5], b3[5]); + w6 = _mm_set_epi32(b0[6], b1[6], b2[6], b3[6]); + w7 = _mm_set_epi32(b0[7], b1[7], b2[7], b3[7]); + w8 = _mm_set_epi32(b0[8], b1[8], b2[8], b3[8]); + w9 = _mm_set_epi32(b0[9], b1[9], b2[9], b3[9]); + w10 = _mm_set_epi32(b0[10], b1[10], b2[10], b3[10]); + w11 = _mm_set_epi32(b0[11], b1[11], b2[11], b3[11]); + w12 = _mm_set_epi32(b0[12], b1[12], b2[12], b3[12]); + w13 = _mm_set_epi32(b0[13], b1[13], b2[13], b3[13]); + w14 = _mm_set_epi32(b0[14], b1[14], b2[14], b3[14]); + w15 = _mm_set_epi32(b0[15], b1[15], b2[15], b3[15]); + + Round(a, b, c, d, e, f, g, h, 0x428A2F98, w0); + Round(h, a, b, c, d, e, f, g, 0x71374491, w1); + Round(g, h, a, b, c, d, e, f, 0xB5C0FBCF, w2); + Round(f, g, h, a, b, c, d, e, 0xE9B5DBA5, w3); + Round(e, f, g, h, a, b, c, d, 0x3956C25B, w4); + Round(d, e, f, g, h, a, b, c, 0x59F111F1, w5); + Round(c, d, e, f, g, h, a, b, 0x923F82A4, w6); + Round(b, c, d, e, f, g, h, a, 0xAB1C5ED5, w7); + Round(a, b, c, d, e, f, g, h, 0xD807AA98, w8); + Round(h, a, b, c, d, e, f, g, 0x12835B01, w9); + Round(g, h, a, b, c, d, e, f, 0x243185BE, w10); + Round(f, g, h, a, b, c, d, e, 0x550C7DC3, w11); + Round(e, f, g, h, a, b, c, d, 0x72BE5D74, w12); + Round(d, e, f, g, h, a, b, c, 0x80DEB1FE, w13); + Round(c, d, e, f, g, h, a, b, 0x9BDC06A7, w14); + Round(b, c, d, e, f, g, h, a, 0xC19BF174, w15); + + WMIX() + + Round(a, b, c, d, e, f, g, h, 0xE49B69C1, w0); + Round(h, a, b, c, d, e, f, g, 0xEFBE4786, w1); + Round(g, h, a, b, c, d, e, f, 0x0FC19DC6, w2); + Round(f, g, h, a, b, c, d, e, 0x240CA1CC, w3); + Round(e, f, g, h, a, b, c, d, 0x2DE92C6F, w4); + Round(d, e, f, g, h, a, b, c, 0x4A7484AA, w5); + Round(c, d, e, f, g, h, a, b, 0x5CB0A9DC, w6); + Round(b, c, d, e, f, g, h, a, 0x76F988DA, w7); + Round(a, b, c, d, e, f, g, h, 0x983E5152, w8); + Round(h, a, b, c, d, e, f, g, 0xA831C66D, w9); + Round(g, h, a, b, c, d, e, f, 0xB00327C8, w10); + Round(f, g, h, a, b, c, d, e, 0xBF597FC7, w11); + Round(e, f, g, h, a, b, c, d, 0xC6E00BF3, w12); + Round(d, e, f, g, h, a, b, c, 0xD5A79147, w13); + Round(c, d, e, f, g, h, a, b, 0x06CA6351, w14); + Round(b, c, d, e, f, g, h, a, 0x14292967, w15); + + WMIX() + + Round(a, b, c, d, e, f, g, h, 0x27B70A85, w0); + Round(h, a, b, c, d, e, f, g, 0x2E1B2138, w1); + Round(g, h, a, b, c, d, e, f, 0x4D2C6DFC, w2); + Round(f, g, h, a, b, c, d, e, 0x53380D13, w3); + Round(e, f, g, h, a, b, c, d, 0x650A7354, w4); + Round(d, e, f, g, h, a, b, c, 0x766A0ABB, w5); + Round(c, d, e, f, g, h, a, b, 0x81C2C92E, w6); + Round(b, c, d, e, f, g, h, a, 0x92722C85, w7); + Round(a, b, c, d, e, f, g, h, 0xA2BFE8A1, w8); + Round(h, a, b, c, d, e, f, g, 0xA81A664B, w9); + Round(g, h, a, b, c, d, e, f, 0xC24B8B70, w10); + Round(f, g, h, a, b, c, d, e, 0xC76C51A3, w11); + Round(e, f, g, h, a, b, c, d, 0xD192E819, w12); + Round(d, e, f, g, h, a, b, c, 0xD6990624, w13); + Round(c, d, e, f, g, h, a, b, 0xF40E3585, w14); + Round(b, c, d, e, f, g, h, a, 0x106AA070, w15); + + WMIX() + + Round(a, b, c, d, e, f, g, h, 0x19A4C116, w0); + Round(h, a, b, c, d, e, f, g, 0x1E376C08, w1); + Round(g, h, a, b, c, d, e, f, 0x2748774C, w2); + Round(f, g, h, a, b, c, d, e, 0x34B0BCB5, w3); + Round(e, f, g, h, a, b, c, d, 0x391C0CB3, w4); + Round(d, e, f, g, h, a, b, c, 0x4ED8AA4A, w5); + Round(c, d, e, f, g, h, a, b, 0x5B9CCA4F, w6); + Round(b, c, d, e, f, g, h, a, 0x682E6FF3, w7); + Round(a, b, c, d, e, f, g, h, 0x748F82EE, w8); + Round(h, a, b, c, d, e, f, g, 0x78A5636F, w9); + Round(g, h, a, b, c, d, e, f, 0x84C87814, w10); + Round(f, g, h, a, b, c, d, e, 0x8CC70208, w11); + Round(e, f, g, h, a, b, c, d, 0x90BEFFFA, w12); + Round(d, e, f, g, h, a, b, c, 0xA4506CEB, w13); + Round(c, d, e, f, g, h, a, b, 0xBEF9A3F7, w14); + Round(b, c, d, e, f, g, h, a, 0xC67178F2, w15); + + s[0] = _mm_add_epi32(a, s[0]); + s[1] = _mm_add_epi32(b, s[1]); + s[2] = _mm_add_epi32(c, s[2]); + s[3] = _mm_add_epi32(d, s[3]); + s[4] = _mm_add_epi32(e, s[4]); + s[5] = _mm_add_epi32(f, s[5]); + s[6] = _mm_add_epi32(g, s[6]); + s[7] = _mm_add_epi32(h, s[7]); + + } + + // Perform 4 SHA(SHA(bi))[0] in parallel using SSE2 + void Transform2(__m128i *s, uint32_t *b0, uint32_t *b1, uint32_t *b2, uint32_t *b3) { + __m128i a, b, c, d, e, f, g, h; + __m128i w0, w1, w2, w3, w4, w5, w6, w7; + __m128i w8, w9, w10, w11, w12, w13, w14, w15; + __m128i T1, T2; + + a = _mm_load_si128(s + 0); + b = _mm_load_si128(s + 1); + c = _mm_load_si128(s + 2); + d = _mm_load_si128(s + 3); + e = _mm_load_si128(s + 4); + f = _mm_load_si128(s + 5); + g = _mm_load_si128(s + 6); + h = _mm_load_si128(s + 7); + + w0 = _mm_set_epi32(b0[0], b1[0], b2[0], b3[0]); + w1 = _mm_set_epi32(b0[1], b1[1], b2[1], b3[1]); + w2 = _mm_set_epi32(b0[2], b1[2], b2[2], b3[2]); + w3 = _mm_set_epi32(b0[3], b1[3], b2[3], b3[3]); + w4 = _mm_set_epi32(b0[4], b1[4], b2[4], b3[4]); + w5 = _mm_set_epi32(b0[5], b1[5], b2[5], b3[5]); + w6 = _mm_set_epi32(b0[6], b1[6], b2[6], b3[6]); + w7 = _mm_set_epi32(b0[7], b1[7], b2[7], b3[7]); + w8 = _mm_set_epi32(b0[8], b1[8], b2[8], b3[8]); + w9 = _mm_set_epi32(b0[9], b1[9], b2[9], b3[9]); + w10 = _mm_set_epi32(b0[10], b1[10], b2[10], b3[10]); + w11 = _mm_set_epi32(b0[11], b1[11], b2[11], b3[11]); + w12 = _mm_set_epi32(b0[12], b1[12], b2[12], b3[12]); + w13 = _mm_set_epi32(b0[13], b1[13], b2[13], b3[13]); + w14 = _mm_set_epi32(b0[14], b1[14], b2[14], b3[14]); + w15 = _mm_set_epi32(b0[15], b1[15], b2[15], b3[15]); + + Round(a, b, c, d, e, f, g, h, 0x428A2F98, w0); + Round(h, a, b, c, d, e, f, g, 0x71374491, w1); + Round(g, h, a, b, c, d, e, f, 0xB5C0FBCF, w2); + Round(f, g, h, a, b, c, d, e, 0xE9B5DBA5, w3); + Round(e, f, g, h, a, b, c, d, 0x3956C25B, w4); + Round(d, e, f, g, h, a, b, c, 0x59F111F1, w5); + Round(c, d, e, f, g, h, a, b, 0x923F82A4, w6); + Round(b, c, d, e, f, g, h, a, 0xAB1C5ED5, w7); + Round(a, b, c, d, e, f, g, h, 0xD807AA98, w8); + Round(h, a, b, c, d, e, f, g, 0x12835B01, w9); + Round(g, h, a, b, c, d, e, f, 0x243185BE, w10); + Round(f, g, h, a, b, c, d, e, 0x550C7DC3, w11); + Round(e, f, g, h, a, b, c, d, 0x72BE5D74, w12); + Round(d, e, f, g, h, a, b, c, 0x80DEB1FE, w13); + Round(c, d, e, f, g, h, a, b, 0x9BDC06A7, w14); + Round(b, c, d, e, f, g, h, a, 0xC19BF174, w15); + + WMIX() + + Round(a, b, c, d, e, f, g, h, 0xE49B69C1, w0); + Round(h, a, b, c, d, e, f, g, 0xEFBE4786, w1); + Round(g, h, a, b, c, d, e, f, 0x0FC19DC6, w2); + Round(f, g, h, a, b, c, d, e, 0x240CA1CC, w3); + Round(e, f, g, h, a, b, c, d, 0x2DE92C6F, w4); + Round(d, e, f, g, h, a, b, c, 0x4A7484AA, w5); + Round(c, d, e, f, g, h, a, b, 0x5CB0A9DC, w6); + Round(b, c, d, e, f, g, h, a, 0x76F988DA, w7); + Round(a, b, c, d, e, f, g, h, 0x983E5152, w8); + Round(h, a, b, c, d, e, f, g, 0xA831C66D, w9); + Round(g, h, a, b, c, d, e, f, 0xB00327C8, w10); + Round(f, g, h, a, b, c, d, e, 0xBF597FC7, w11); + Round(e, f, g, h, a, b, c, d, 0xC6E00BF3, w12); + Round(d, e, f, g, h, a, b, c, 0xD5A79147, w13); + Round(c, d, e, f, g, h, a, b, 0x06CA6351, w14); + Round(b, c, d, e, f, g, h, a, 0x14292967, w15); + + WMIX() + + Round(a, b, c, d, e, f, g, h, 0x27B70A85, w0); + Round(h, a, b, c, d, e, f, g, 0x2E1B2138, w1); + Round(g, h, a, b, c, d, e, f, 0x4D2C6DFC, w2); + Round(f, g, h, a, b, c, d, e, 0x53380D13, w3); + Round(e, f, g, h, a, b, c, d, 0x650A7354, w4); + Round(d, e, f, g, h, a, b, c, 0x766A0ABB, w5); + Round(c, d, e, f, g, h, a, b, 0x81C2C92E, w6); + Round(b, c, d, e, f, g, h, a, 0x92722C85, w7); + Round(a, b, c, d, e, f, g, h, 0xA2BFE8A1, w8); + Round(h, a, b, c, d, e, f, g, 0xA81A664B, w9); + Round(g, h, a, b, c, d, e, f, 0xC24B8B70, w10); + Round(f, g, h, a, b, c, d, e, 0xC76C51A3, w11); + Round(e, f, g, h, a, b, c, d, 0xD192E819, w12); + Round(d, e, f, g, h, a, b, c, 0xD6990624, w13); + Round(c, d, e, f, g, h, a, b, 0xF40E3585, w14); + Round(b, c, d, e, f, g, h, a, 0x106AA070, w15); + + WMIX() + + Round(a, b, c, d, e, f, g, h, 0x19A4C116, w0); + Round(h, a, b, c, d, e, f, g, 0x1E376C08, w1); + Round(g, h, a, b, c, d, e, f, 0x2748774C, w2); + Round(f, g, h, a, b, c, d, e, 0x34B0BCB5, w3); + Round(e, f, g, h, a, b, c, d, 0x391C0CB3, w4); + Round(d, e, f, g, h, a, b, c, 0x4ED8AA4A, w5); + Round(c, d, e, f, g, h, a, b, 0x5B9CCA4F, w6); + Round(b, c, d, e, f, g, h, a, 0x682E6FF3, w7); + Round(a, b, c, d, e, f, g, h, 0x748F82EE, w8); + Round(h, a, b, c, d, e, f, g, 0x78A5636F, w9); + Round(g, h, a, b, c, d, e, f, 0x84C87814, w10); + Round(f, g, h, a, b, c, d, e, 0x8CC70208, w11); + Round(e, f, g, h, a, b, c, d, 0x90BEFFFA, w12); + Round(d, e, f, g, h, a, b, c, 0xA4506CEB, w13); + Round(c, d, e, f, g, h, a, b, 0xBEF9A3F7, w14); + Round(b, c, d, e, f, g, h, a, 0xC67178F2, w15); + + w0 = _mm_add_epi32(a, s[0]); + w1 = _mm_add_epi32(b, s[1]); + w2 = _mm_add_epi32(c, s[2]); + w3 = _mm_add_epi32(d, s[3]); + w4 = _mm_add_epi32(e, s[4]); + w5 = _mm_add_epi32(f, s[5]); + w6 = _mm_add_epi32(g, s[6]); + w7 = _mm_add_epi32(h, s[7]); + w8 = _mm_set1_epi32(0x80000000); + w9 = _mm_xor_si128(w9,w9); + w10 = _mm_xor_si128(w10, w10); + w11 = _mm_xor_si128(w11, w11); + w12 = _mm_xor_si128(w12, w12); + w13 = _mm_xor_si128(w13, w13); + w14 = _mm_xor_si128(w14, w14); + w15 = _mm_set1_epi32(0x100); + + a = _mm_load_si128(s + 0); + b = _mm_load_si128(s + 1); + c = _mm_load_si128(s + 2); + d = _mm_load_si128(s + 3); + e = _mm_load_si128(s + 4); + f = _mm_load_si128(s + 5); + g = _mm_load_si128(s + 6); + h = _mm_load_si128(s + 7); + + Round(a, b, c, d, e, f, g, h, 0x428A2F98, w0); + Round(h, a, b, c, d, e, f, g, 0x71374491, w1); + Round(g, h, a, b, c, d, e, f, 0xB5C0FBCF, w2); + Round(f, g, h, a, b, c, d, e, 0xE9B5DBA5, w3); + Round(e, f, g, h, a, b, c, d, 0x3956C25B, w4); + Round(d, e, f, g, h, a, b, c, 0x59F111F1, w5); + Round(c, d, e, f, g, h, a, b, 0x923F82A4, w6); + Round(b, c, d, e, f, g, h, a, 0xAB1C5ED5, w7); + Round(a, b, c, d, e, f, g, h, 0xD807AA98, w8); + Round(h, a, b, c, d, e, f, g, 0x12835B01, w9); + Round(g, h, a, b, c, d, e, f, 0x243185BE, w10); + Round(f, g, h, a, b, c, d, e, 0x550C7DC3, w11); + Round(e, f, g, h, a, b, c, d, 0x72BE5D74, w12); + Round(d, e, f, g, h, a, b, c, 0x80DEB1FE, w13); + Round(c, d, e, f, g, h, a, b, 0x9BDC06A7, w14); + Round(b, c, d, e, f, g, h, a, 0xC19BF174, w15); + + WMIX() + + Round(a, b, c, d, e, f, g, h, 0xE49B69C1, w0); + Round(h, a, b, c, d, e, f, g, 0xEFBE4786, w1); + Round(g, h, a, b, c, d, e, f, 0x0FC19DC6, w2); + Round(f, g, h, a, b, c, d, e, 0x240CA1CC, w3); + Round(e, f, g, h, a, b, c, d, 0x2DE92C6F, w4); + Round(d, e, f, g, h, a, b, c, 0x4A7484AA, w5); + Round(c, d, e, f, g, h, a, b, 0x5CB0A9DC, w6); + Round(b, c, d, e, f, g, h, a, 0x76F988DA, w7); + Round(a, b, c, d, e, f, g, h, 0x983E5152, w8); + Round(h, a, b, c, d, e, f, g, 0xA831C66D, w9); + Round(g, h, a, b, c, d, e, f, 0xB00327C8, w10); + Round(f, g, h, a, b, c, d, e, 0xBF597FC7, w11); + Round(e, f, g, h, a, b, c, d, 0xC6E00BF3, w12); + Round(d, e, f, g, h, a, b, c, 0xD5A79147, w13); + Round(c, d, e, f, g, h, a, b, 0x06CA6351, w14); + Round(b, c, d, e, f, g, h, a, 0x14292967, w15); + + WMIX() + + Round(a, b, c, d, e, f, g, h, 0x27B70A85, w0); + Round(h, a, b, c, d, e, f, g, 0x2E1B2138, w1); + Round(g, h, a, b, c, d, e, f, 0x4D2C6DFC, w2); + Round(f, g, h, a, b, c, d, e, 0x53380D13, w3); + Round(e, f, g, h, a, b, c, d, 0x650A7354, w4); + Round(d, e, f, g, h, a, b, c, 0x766A0ABB, w5); + Round(c, d, e, f, g, h, a, b, 0x81C2C92E, w6); + Round(b, c, d, e, f, g, h, a, 0x92722C85, w7); + Round(a, b, c, d, e, f, g, h, 0xA2BFE8A1, w8); + Round(h, a, b, c, d, e, f, g, 0xA81A664B, w9); + Round(g, h, a, b, c, d, e, f, 0xC24B8B70, w10); + Round(f, g, h, a, b, c, d, e, 0xC76C51A3, w11); + Round(e, f, g, h, a, b, c, d, 0xD192E819, w12); + Round(d, e, f, g, h, a, b, c, 0xD6990624, w13); + Round(c, d, e, f, g, h, a, b, 0xF40E3585, w14); + Round(b, c, d, e, f, g, h, a, 0x106AA070, w15); + + WMIX() + + Round(a, b, c, d, e, f, g, h, 0x19A4C116, w0); + Round(h, a, b, c, d, e, f, g, 0x1E376C08, w1); + Round(g, h, a, b, c, d, e, f, 0x2748774C, w2); + Round(f, g, h, a, b, c, d, e, 0x34B0BCB5, w3); + Round(e, f, g, h, a, b, c, d, 0x391C0CB3, w4); + Round(d, e, f, g, h, a, b, c, 0x4ED8AA4A, w5); + Round(c, d, e, f, g, h, a, b, 0x5B9CCA4F, w6); + Round(b, c, d, e, f, g, h, a, 0x682E6FF3, w7); + Round(a, b, c, d, e, f, g, h, 0x748F82EE, w8); + Round(h, a, b, c, d, e, f, g, 0x78A5636F, w9); + Round(g, h, a, b, c, d, e, f, 0x84C87814, w10); + Round(f, g, h, a, b, c, d, e, 0x8CC70208, w11); + Round(e, f, g, h, a, b, c, d, 0x90BEFFFA, w12); + Round(d, e, f, g, h, a, b, c, 0xA4506CEB, w13); + Round(c, d, e, f, g, h, a, b, 0xBEF9A3F7, w14); + Round(b, c, d, e, f, g, h, a, 0xC67178F2, w15); + + s[0] = _mm_add_epi32(a, s[0]); + + } + +} // end namespace + +void sha256sse_1B( + uint32_t *i0, + uint32_t *i1, + uint32_t *i2, + uint32_t *i3, + unsigned char *d0, + unsigned char *d1, + unsigned char *d2, + unsigned char *d3) { + + __m128i s[8]; + + _sha256sse::Initialize(s); + _sha256sse::Transform(s,i0,i1,i2,i3); + + // Unpack + __m128i mask = _mm_set_epi8(12, 13, 14, 15, /**/ 4, 5, 6, 7, /**/ 8, 9, 10, 11, /**/ 0, 1, 2, 3 ); + + __m128i u0 = _mm_unpacklo_epi32(s[0], s[1]); // S2_1 S2_0 S3_1 S3_0 + __m128i u1 = _mm_unpackhi_epi32(s[0], s[1]); // S0_1 S0_0 S1_1 S1_0 + + __m128i u2 = _mm_unpacklo_epi32(s[2], s[3]); // S2_3 S2_2 S3_3 S3_2 + __m128i u3 = _mm_unpackhi_epi32(s[2], s[3]); // S0_3 S0_2 S1_3 S1_2 + + __m128i _d3 = _mm_unpacklo_epi32(u0, u2); // S3_3 S3_1 S3_2 S3_0 + __m128i _d2 = _mm_unpackhi_epi32(u0, u2); // S2_3 S2_1 S2_2 S2_0 + __m128i _d1 = _mm_unpacklo_epi32(u1, u3); // S1_3 S1_1 S1_2 S1_0 + __m128i _d0 = _mm_unpackhi_epi32(u1, u3); // S0_3 S0_1 S0_2 S0_0 + + _d0 = _mm_shuffle_epi8(_d0, mask); + _d1 = _mm_shuffle_epi8(_d1, mask); + _d2 = _mm_shuffle_epi8(_d2, mask); + _d3 = _mm_shuffle_epi8(_d3, mask); + + _mm_store_si128((__m128i *)d0, _d0); + _mm_store_si128((__m128i *)d1, _d1); + _mm_store_si128((__m128i *)d2, _d2); + _mm_store_si128((__m128i *)d3, _d3); + + // -------------------- + + u0 = _mm_unpacklo_epi32(s[4], s[5]); + u1 = _mm_unpackhi_epi32(s[4], s[5]); + + u2 = _mm_unpacklo_epi32(s[6], s[7]); + u3 = _mm_unpackhi_epi32(s[6], s[7]); + + _d3 = _mm_unpacklo_epi32(u0, u2); + _d2 = _mm_unpackhi_epi32(u0, u2); + _d1 = _mm_unpacklo_epi32(u1, u3); + _d0 = _mm_unpackhi_epi32(u1, u3); + + _d0 = _mm_shuffle_epi8(_d0, mask); + _d1 = _mm_shuffle_epi8(_d1, mask); + _d2 = _mm_shuffle_epi8(_d2, mask); + _d3 = _mm_shuffle_epi8(_d3, mask); + + _mm_store_si128((__m128i *)(d0 + 16), _d0); + _mm_store_si128((__m128i *)(d1 + 16), _d1); + _mm_store_si128((__m128i *)(d2 + 16), _d2); + _mm_store_si128((__m128i *)(d3 + 16), _d3); + +} + + +void sha256sse_2B( + uint32_t *i0, + uint32_t *i1, + uint32_t *i2, + uint32_t *i3, + unsigned char *d0, + unsigned char *d1, + unsigned char *d2, + unsigned char *d3) { + + __m128i s[8]; + + _sha256sse::Initialize(s); + _sha256sse::Transform(s, i0, i1, i2, i3); + _sha256sse::Transform(s, i0 + 16, i1 + 16, i2 + 16, i3 + 16); + + // Unpack + __m128i mask = _mm_set_epi8(12, 13, 14, 15, /**/ 4, 5, 6, 7, /**/ 8, 9, 10, 11, /**/ 0, 1, 2, 3); + + __m128i u0 = _mm_unpacklo_epi32(s[0], s[1]); // S2_1 S2_0 S3_1 S3_0 + __m128i u1 = _mm_unpackhi_epi32(s[0], s[1]); // S0_1 S0_0 S1_1 S1_0 + + __m128i u2 = _mm_unpacklo_epi32(s[2], s[3]); // S2_3 S2_2 S3_3 S3_2 + __m128i u3 = _mm_unpackhi_epi32(s[2], s[3]); // S0_3 S0_2 S1_3 S1_2 + + __m128i _d3 = _mm_unpacklo_epi32(u0, u2); // S3_3 S3_1 S3_2 S3_0 + __m128i _d2 = _mm_unpackhi_epi32(u0, u2); // S2_3 S2_1 S2_2 S2_0 + __m128i _d1 = _mm_unpacklo_epi32(u1, u3); // S1_3 S1_1 S1_2 S1_0 + __m128i _d0 = _mm_unpackhi_epi32(u1, u3); // S0_3 S0_1 S0_2 S0_0 + + _d0 = _mm_shuffle_epi8(_d0, mask); + _d1 = _mm_shuffle_epi8(_d1, mask); + _d2 = _mm_shuffle_epi8(_d2, mask); + _d3 = _mm_shuffle_epi8(_d3, mask); + + _mm_store_si128((__m128i *)d0, _d0); + _mm_store_si128((__m128i *)d1, _d1); + _mm_store_si128((__m128i *)d2, _d2); + _mm_store_si128((__m128i *)d3, _d3); + + // -------------------- + + u0 = _mm_unpacklo_epi32(s[4], s[5]); + u1 = _mm_unpackhi_epi32(s[4], s[5]); + + u2 = _mm_unpacklo_epi32(s[6], s[7]); + u3 = _mm_unpackhi_epi32(s[6], s[7]); + + _d3 = _mm_unpacklo_epi32(u0, u2); + _d2 = _mm_unpackhi_epi32(u0, u2); + _d1 = _mm_unpacklo_epi32(u1, u3); + _d0 = _mm_unpackhi_epi32(u1, u3); + + _d0 = _mm_shuffle_epi8(_d0, mask); + _d1 = _mm_shuffle_epi8(_d1, mask); + _d2 = _mm_shuffle_epi8(_d2, mask); + _d3 = _mm_shuffle_epi8(_d3, mask); + + _mm_store_si128((__m128i *)(d0 + 16), _d0); + _mm_store_si128((__m128i *)(d1 + 16), _d1); + _mm_store_si128((__m128i *)(d2 + 16), _d2); + _mm_store_si128((__m128i *)(d3 + 16), _d3); + +} + +void sha256sse_checksum(uint32_t *i0, uint32_t *i1, uint32_t *i2, uint32_t *i3, + uint8_t *d0, uint8_t *d1, uint8_t *d2, uint8_t *d3) { + + __m128i s[8]; + + _sha256sse::Initialize(s); + _sha256sse::Transform2(s, i0, i1, i2, i3); + +#ifndef WIN64 + uint32_t *s32 = (uint32_t *)(&s[0]); + *((uint32_t *)d0) = __builtin_bswap32(s32[3]); + *((uint32_t *)d1) = __builtin_bswap32(s32[2]); + *((uint32_t *)d2) = __builtin_bswap32(s32[1]); + *((uint32_t *)d3) = __builtin_bswap32(s32[0]); +#else + *((uint32_t *)d0) = _byteswap_ulong(s[0].m128i_u32[3]); + *((uint32_t *)d1) = _byteswap_ulong(s[0].m128i_u32[2]); + *((uint32_t *)d2) = _byteswap_ulong(s[0].m128i_u32[1]); + *((uint32_t *)d3) = _byteswap_ulong(s[0].m128i_u32[0]); +#endif + +} + +#if 0 +void sha256sse_test() { + + unsigned char h0[32]; + unsigned char h1[32]; + unsigned char h2[32]; + unsigned char h3[32]; + unsigned char ch0[32]; + unsigned char ch1[32]; + unsigned char ch2[32]; + unsigned char ch3[32]; + unsigned char m0[64]; + unsigned char m1[64]; + unsigned char m2[64]; + unsigned char m3[64]; + + strcpy((char *)m0, "This is a test message to test 01"); + strcpy((char *)m1, "This is a test message to test 02"); + strcpy((char *)m2, "This is a test message to test 03"); + strcpy((char *)m3, "This is a test message to test 04"); + + sha256_33(m0, ch0); + sha256_33(m1, ch1); + sha256_33(m2, ch2); + sha256_33(m3, ch3); + + sha256sse_33(m0,m1,m2,m3,h0,h1,h2,h3); + + if((sha256_hex(h0) != sha256_hex(ch0)) || + (sha256_hex(h1) != sha256_hex(ch1)) || + (sha256_hex(h2) != sha256_hex(ch2)) || + (sha256_hex(h3) != sha256_hex(ch3))) { + + printf("SHA() Results Wrong !\n"); + printf("SHA: %s\n", sha256_hex(ch0).c_str()); + printf("SHA: %s\n", sha256_hex(ch1).c_str()); + printf("SHA: %s\n", sha256_hex(ch2).c_str()); + printf("SHA: %s\n\n", sha256_hex(ch3).c_str()); + printf("SSE: %s\n", sha256_hex(h0).c_str()); + printf("SSE: %s\n", sha256_hex(h1).c_str()); + printf("SSE: %s\n", sha256_hex(h2).c_str()); + printf("SSE: %s\n\n", sha256_hex(h3).c_str()); + + } + + printf("SHA() Results OK !\n"); + +} +#endif diff --git a/hash/sha512.cpp b/hash/sha512.cpp new file mode 100644 index 0000000..2ab9bae --- /dev/null +++ b/hash/sha512.cpp @@ -0,0 +1,406 @@ +/* + * This file is part of the VanitySearch distribution (https://github.com/JeanLucPons/VanitySearch). + * Copyright (c) 2019 Jean Luc PONS. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +#include +#include "sha512.h" + +#define BSWAP +#define SHA512_BLOCK_SIZE 128 +#define SHA512_HASH_LENGTH 64 +#define MIN(x,y) (xy)?x:y; + +/// Internal SHA-512 implementation. +namespace _sha512 { + + static const uint64_t K[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, + 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, + 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, + 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, + 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, + 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, + 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, + 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, + 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, + 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, + 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, + 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, + 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, + 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL + }; + +#ifndef WIN64 +#define _byteswap_ulong __builtin_bswap32 +#define _byteswap_uint64 __builtin_bswap64 +inline uint64_t _rotr64(uint64_t x, uint8_t r) { + asm("rorq %1,%0" : "+r" (x) : "c" (r)); + return x; +} +#endif + +#define ROR(x,n) _rotr64(x, n) +#define S0(x) (ROR(x, 28) ^ ROR(x, 34) ^ ROR(x, 39)) +#define S1(x) (ROR(x, 14) ^ ROR(x, 18) ^ ROR(x, 41)) +#define G0(x) (ROR(x, 1) ^ ROR(x, 8) ^ (x >> 7)) +#define G1(x) (ROR(x, 19) ^ ROR(x, 61) ^ (x >> 6)) + +#define ROUND(i, a,b,c,d,e,f,g,h) \ + t = h + S1(e) + (g ^ (e & (f ^ g))) + K[i] + W[i]; \ + d += t; \ + h = t + S0(a) + ( ((a | b) & c) | (a & b) ) + +#ifdef BSWAP + #define READBE64(ptr) _byteswap_uint64(*(uint64_t *)(ptr)); + #define WRITEBE64(ptr,x) *((uint64_t *)(ptr)) = _byteswap_uint64(x); + #define READBE32(i) _byteswap_ulong((uint32_t)(i)); +#else + #define READBE64(ptr) *(uint64_t *)(ptr); + #define WRITEBE64(ptr,x) *(ptr) = x; + #define READBE32(i) (uint32_t)(i); +#endif + +static void Transform(uint64_t state[8], const uint8_t buf[128]) { + + uint64_t W[80], t; + uint64_t a, b, c, d, e, f, g, h; + int i; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + W[0] = READBE64(buf + 0x0); + W[1] = READBE64(buf + 0x8); + W[2] = READBE64(buf + 0x10); + W[3] = READBE64(buf + 0x18); + W[4] = READBE64(buf + 0x20); + W[5] = READBE64(buf + 0x28); + W[6] = READBE64(buf + 0x30); + W[7] = READBE64(buf + 0x38); + W[8] = READBE64(buf + 0x40); + W[9] = READBE64(buf + 0x48); + W[10] = READBE64(buf + 0x50); + W[11] = READBE64(buf + 0x58); + W[12] = READBE64(buf + 0x60); + W[13] = READBE64(buf + 0x68); + W[14] = READBE64(buf + 0x70); + W[15] = READBE64(buf + 0x78); + + for(i = 16; i < 80; i++) + W[i] = W[i - 16] + G0(W[i - 15]) + W[i - 7] + G1(W[i - 2]); + + for (i = 0; i < 80; i += 8) { + ROUND(i + 0, a, b, c, d, e, f, g, h); + ROUND(i + 1, h, a, b, c, d, e, f, g); + ROUND(i + 2, g, h, a, b, c, d, e, f); + ROUND(i + 3, f, g, h, a, b, c, d, e); + ROUND(i + 4, e, f, g, h, a, b, c, d); + ROUND(i + 5, d, e, f, g, h, a, b, c); + ROUND(i + 6, c, d, e, f, g, h, a, b); + ROUND(i + 7, b, c, d, e, f, g, h, a); + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + +} + + +} + + +class CSHA512 { + +private: + uint64_t s[8]; + unsigned char buf[128]; + size_t buffSize; + size_t count; + +public: + + CSHA512(); + void Initialize(); + void Write(const unsigned char* data, size_t len); + void WriteDirect128(const unsigned char* data); + void WriteDirect64(const unsigned char* data); + void Finalize(unsigned char hash[64]); + +}; + +CSHA512::CSHA512() { + + Initialize(); + +} + +void CSHA512::Initialize() { + + buffSize = 0; + count = 0; + s[0] = 0x6a09e667f3bcc908ULL; + s[1] = 0xbb67ae8584caa73bULL; + s[2] = 0x3c6ef372fe94f82bULL; + s[3] = 0xa54ff53a5f1d36f1ULL; + s[4] = 0x510e527fade682d1ULL; + s[5] = 0x9b05688c2b3e6c1fULL; + s[6] = 0x1f83d9abfb41bd6bULL; + s[7] = 0x5be0cd19137e2179ULL; + +} + +void CSHA512::Write(const unsigned char* data, size_t len) { + + if (buffSize > 0) { + + // Fill internal buffer up and transform + size_t fill = MIN(len,128-buffSize); + memcpy(buf+buffSize,data, fill); + len -= fill; + buffSize += fill; + if(buffSize < 128) + return; + _sha512::Transform(s, buf); + count++; + + } + + // Internal buffer is empty + while (len >= 128) { + _sha512::Transform(s, data); + count++; + data += 128; + len -= 128; + } + + // save rest for next time + memcpy(buf,data,len); + buffSize = len; + +} + +// Write 128 bytes aligned (buffsize must be 0) +void CSHA512::WriteDirect128(const unsigned char* data) { + _sha512::Transform(s, data); + count++; +} + +// Write 64 bytes aligned (buffsize must be 0) +void CSHA512::WriteDirect64(const unsigned char* data) { + memcpy(buf, data, 64); + buffSize = 64; +} + +void CSHA512::Finalize(unsigned char hash[64]) { + + size_t rest; + size_t i; + + rest = buffSize; + + // End code + buf[buffSize++] = 0x80; + + if (buffSize > 112) { + memset(buf+buffSize,0,128-buffSize); + _sha512::Transform(s, buf); + buffSize = 0; + } + memset(buf+buffSize,0,112-buffSize); + + // Write length (128bit big-endian) + WRITEBE64(buf + 112, count >> 54); + WRITEBE64(buf + 120, ((count << 7) | rest) << 3); + _sha512::Transform(s, buf); + + for (i = 0; i < 8; i++) + WRITEBE64(hash + 8 * i, s[i]); + +} + + +/* padding */ +#define IPAD 0x36 +#define IPADLL 0x3636363636363636LL +#define OPAD 0x5c +#define OPADLL 0x5c5c5c5c5c5c5c5cLL + +void hmac_sha512_init(CSHA512 &ctx, const uint8_t key[SHA512_BLOCK_SIZE]) { + + uint64_t pad[SHA512_BLOCK_SIZE/8]; + uint64_t *keyPtr = (uint64_t *)key; + int i; + + // Inner padding + for (i = 0; i < SHA512_BLOCK_SIZE/8; i++) + pad[i] = keyPtr[i] ^ IPADLL; + + ctx.Initialize(); + ctx.WriteDirect128((unsigned char *)pad); + +} + + +void hmac_sha512_done(CSHA512 &ctx, const uint8_t key[SHA512_BLOCK_SIZE], uint8_t result[SHA512_HASH_LENGTH]) { + + uint64_t pad[SHA512_BLOCK_SIZE/8]; + uint64_t *keyPtr = (uint64_t *)key; + uint8_t ihash[SHA512_HASH_LENGTH]; + int i; + + // Finalize inner hash + ctx.Finalize(ihash); + + // Construct outer padding + for (i = 0; i < SHA512_BLOCK_SIZE/8; i++) + pad[i] = keyPtr[i] ^ OPADLL; + + // Final hash + CSHA512 c; + c.WriteDirect128((unsigned char *)pad); + c.WriteDirect64(ihash); + c.Finalize(result); + +} + + +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) { + + CSHA512 hmac, hmac_template; + uint32_t i, be32i; + uint64_t j; + int k; + + uint8_t key[SHA512_BLOCK_SIZE]; + uint8_t F[SHA512_HASH_LENGTH], U[SHA512_HASH_LENGTH]; + uint64_t *Fptr = (uint64_t *)F; + uint64_t *Uptr = (uint64_t *)U; + size_t need; + + if (passlen < SHA512_BLOCK_SIZE) { + memcpy(key, passwd, passlen); + memset(key + passlen, 0, SHA512_BLOCK_SIZE - passlen); + } else { + hmac.Write(passwd, passlen); + hmac.Finalize(key); + memset(key + SHA512_HASH_LENGTH, 0, SHA512_BLOCK_SIZE - SHA512_HASH_LENGTH); + } + + hmac_sha512_init(hmac_template, key); + hmac_template.Write(salt, saltlen); + + for (i = 1; outlen > 0; i++) { + + hmac = hmac_template; + be32i = READBE32(i); + hmac.Write((unsigned char *)&be32i, sizeof(be32i)); + hmac_sha512_done(hmac, key, U); + memcpy(F, U, SHA512_HASH_LENGTH); + + for (j = 2; j <= iter; j++) { + hmac_sha512_init(hmac, key); + hmac.WriteDirect64(U); + hmac_sha512_done(hmac, key, U); + for (k = 0; k < SHA512_HASH_LENGTH/8; k++) + Fptr[k] ^= Uptr[k]; + } + + need = MIN(SHA512_HASH_LENGTH, outlen); + + memcpy(out, F, need); + out += need; + outlen -= need; + + } + +} + +void hmac_sha512(unsigned char *key, int key_length, unsigned char *message, int message_length, unsigned char *digest) { + + uint8_t ipad[SHA512_BLOCK_SIZE]; + uint8_t opad[SHA512_BLOCK_SIZE]; + uint8_t hash[SHA512_HASH_LENGTH]; + int i; + + // TODO Handle key larger than 128 + + for (i = 0; i < key_length && i < SHA512_BLOCK_SIZE; i++) { + ipad[i] = key[i] ^ IPAD; + opad[i] = key[i] ^ OPAD; + } + for (; i < SHA512_BLOCK_SIZE; i++) { + ipad[i] = IPAD; + opad[i] = OPAD; + } + + CSHA512 h; + h.WriteDirect128(ipad); + h.Write(message, message_length); + h.Finalize(hash); + + h.Initialize(); + h.WriteDirect128(opad); + h.Write(hash, SHA512_HASH_LENGTH); + h.Finalize(digest); + +} + +void sha512(unsigned char *input, int length, unsigned char *digest) { + + CSHA512 sha; + sha.Write(input, length); + sha.Finalize(digest); + +} + +std::string sha512_hex(unsigned char *digest) { + + char buf[2 * 64 + 1]; + buf[2 * 64] = 0; + for (int i = 0; i < 64; i++) + sprintf(buf + i * 2, "%02x", digest[i]); + return std::string(buf); + +} diff --git a/hash/sha512.h b/hash/sha512.h new file mode 100644 index 0000000..32dc179 --- /dev/null +++ b/hash/sha512.h @@ -0,0 +1,28 @@ +/* + * This file is part of the VanitySearch distribution (https://github.com/JeanLucPons/VanitySearch). + * Copyright (c) 2019 Jean Luc PONS. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +#ifndef SHA512_H +#define SHA512_H +#include + +void sha512(unsigned char *input, int length, unsigned char *digest); +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); +void hmac_sha512(unsigned char *key, int key_length, unsigned char *message, int message_length, unsigned char *digest); + +std::string sha512_hex(unsigned char *digest); + +#endif diff --git a/keyhunt.cpp b/keyhunt.cpp index 2614490..73f6f1c 100644 --- a/keyhunt.cpp +++ b/keyhunt.cpp @@ -14,7 +14,6 @@ email: alberto.bsd@gmail.com #include #include "base58/libbase58.h" #include "rmd160/rmd160.h" -#include "sha256/sha256.h" #include "oldbloom/oldbloom.h" #include "bloom/bloom.h" #include "sha3/sha3.h" @@ -26,6 +25,8 @@ email: alberto.bsd@gmail.com #include "secp256k1/IntGroup.h" #include "secp256k1/Random.h" +#include "hash/sha256.h" +#include "hash/ripemd160.h" #ifdef _WIN64 @@ -46,6 +47,7 @@ email: alberto.bsd@gmail.com #define MODE_BSGS 2 #define MODE_RMD160 3 #define MODE_PUB2RMD 4 +#define MODE_MINIKEYS 5 #define SEARCH_UNCOMPRESS 0 @@ -105,8 +107,9 @@ struct __attribute__((__packed__)) publickey { }; #endif - -const char *version = "0.2.211018 Chocolate ¡Beta!"; +const char *Ccoinbuffer = "S23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + +const char *version = "0.2.211024 Chocolate ¡Beta!"; #define CPU_GRP_SIZE 1024 @@ -141,6 +144,7 @@ int bsgs_searchbinary(struct bsgs_xvalue *arr,char *data,int64_t _N,uint64_t *r_ int bsgs_secondcheck(Int *start_range,uint32_t a,uint32_t k_index,Int *privatekey); #ifdef _WIN64 +DWORD WINAPI thread_process_minikeys(LPVOID vargp); DWORD WINAPI thread_process(LPVOID vargp); DWORD WINAPI thread_process_bsgs(LPVOID vargp); DWORD WINAPI thread_process_bsgs_backward(LPVOID vargp); @@ -151,6 +155,7 @@ DWORD WINAPI thread_bPload(LPVOID vargp); DWORD WINAPI thread_bPloadFile(LPVOID vargp); DWORD WINAPI thread_pub2rmd(LPVOID vargp); #else +void *thread_process_minikeys(void *vargp); void *thread_process(void *vargp); void *thread_process_bsgs(void *vargp); void *thread_process_bsgs_backward(void *vargp); @@ -164,10 +169,14 @@ void *thread_pub2rmd(void *vargp); char *publickeytohashrmd160(char *pkey,int length); +void publickeytohashrmd160_dst(char *pkey,int length,char *dst); char *pubkeytopubaddress(char *pkey,int length); +void pubkeytopubaddress_dst(char *pkey,int length,char *dst); +void rmd160toaddress_dst(char *rmd,char *dst); + void KECCAK_256(uint8_t *source, size_t size,uint8_t *dst); -void generate_binaddress_eth(Point *publickey,unsigned char *dst_address); +void generate_binaddress_eth(Point &publickey,unsigned char *dst_address); void memorycheck_bsgs(); @@ -176,7 +185,7 @@ char *bit_range_str_min; char *bit_range_str_max; const char *bsgs_modes[5] {"secuential","backward","both","random","dance"}; -const char *modes[5] = {"xpoint","address","bsgs","rmd160","pub2rmd"}; +const char *modes[6] = {"xpoint","address","bsgs","rmd160","pub2rmd","minikeys"}; const char *cryptos[3] = {"btc","eth","all"}; const char *publicsearch[3] = {"uncompress","compress","both"}; const char *default_filename = "addresses.txt"; @@ -212,9 +221,9 @@ unsigned int *ends = NULL; uint64_t N = 0; -uint64_t N_SECUENTIAL_MAX = 0xffffffff; -uint64_t DEBUGCOUNT = 0x100000; - +uint64_t N_SECUENTIAL_MAX = 0x100000000; +uint64_t DEBUGCOUNT = 0x400; +uint64_t u64range; Int OUTPUTSECONDS; @@ -235,6 +244,7 @@ int FLAGREADEDFILE3 = 0; int FLAGUPDATEFILE1 = 0; int FLAGUPDATEFILE2 = 0; +int FLAGSTRIDE = 0; int FLAGSEARCH = 2; int FLAGBITRANGE = 0; int FLAGRANGE = 0; @@ -255,6 +265,8 @@ char *str_N; char **vanities; char *range_start; char *range_end; +char *str_stride; +Int stride; uint64_t BSGS_XVALUE_RAM = 6; uint64_t BSGS_BUFFERXPOINTLENGTH = 32; @@ -295,7 +307,6 @@ uint64_t bloom_bP_totalbytes = 0; char *precalculated_p_filename; uint64_t bsgs_m = 4194304; uint64_t bsgs_m2; - unsigned long int bsgs_aux; uint32_t bsgs_point_number; @@ -366,7 +377,6 @@ int main(int argc, char **argv) { int s; #endif - srand (time(NULL)); secp = new Secp256K1(); @@ -384,7 +394,7 @@ int main(int argc, char **argv) { #endif - while ((c = getopt(argc, argv, "dehMqRwzSB:b:c:E:f:k:l:m:n:p:r:s:t:v:V:G:")) != -1) { + while ((c = getopt(argc, argv, "dehMqRwzSB:b:c:E:f:I:k:l:m:N:n:p:r:s:t:v:V:G:")) != -1) { switch(c) { case 'h': printf("\nUsage:\n-h\t\tshow this help\n"); @@ -394,7 +404,7 @@ int main(int argc, char **argv) { printf("-c crypto\tSearch for specific crypo. < btc, eth, all > valid only w/ -m address \n"); printf("\t\tYour file MUST be sordted if no you are going to lose collisions\n"); printf("-f file\t\tSpecify filename with addresses or xpoints or uncompressed public keys\n"); - printf("-g count\tJust for the stats, mark as counted every debugcount keys \n"); + printf("-I stride\tStride for xpoint, rmd160 and address, this option don't work with bsgs \n"); printf("-k value\tUse this only with bsgs mode, k value is factor for M, more speed but more RAM use wisely\n"); printf("-l look\tWhat type of address/hash160 are you looking for < compress , uncompress , both>\n"); printf("-m mode\t\tmode of search for cryptos. ( bsgs , xpoint , rmd160 , address ) default: address (more slow)\n"); @@ -484,6 +494,11 @@ int main(int argc, char **argv) { FLAGFILE = 1; filename = optarg; break; + case 'I': + FLAGSTRIDE = 1; + str_stride = optarg; + break; + case 'k': KFACTOR = (int)strtol(optarg,NULL,10); @@ -514,7 +529,7 @@ int main(int argc, char **argv) { printf("[+] Matrix screen\n"); break; case 'm': - switch(indexOf(optarg,modes,5)) { + switch(indexOf(optarg,modes,6)) { case MODE_XPOINT: //xpoint FLAGMODE = MODE_XPOINT; printf("[+] Mode xpoint\n"); @@ -529,12 +544,17 @@ int main(int argc, char **argv) { break; case MODE_RMD160: FLAGMODE = MODE_RMD160; + FLAGCRYPTO = CRYPTO_BTC; printf("[+] Mode rmd160\n"); break; case MODE_PUB2RMD: FLAGMODE = MODE_PUB2RMD; printf("[+] Mode pub2rmd\n"); break; + case MODE_MINIKEYS: + FLAGMODE = MODE_MINIKEYS; + printf("[+] Mode minikeys\n"); + break; default: fprintf(stderr,"[E] Unknow mode value %s\n",optarg); exit(0); @@ -545,6 +565,7 @@ int main(int argc, char **argv) { FLAG_N = 1; str_N = optarg; break; + case 'q': FLAGQUIET = 1; printf("[+] Quiet thread output\n"); @@ -708,11 +729,27 @@ int main(int argc, char **argv) { FLAGRAWDATA = 1; break; default: - printf("[E] Unknow opcion -%c\n",c); + fprintf(stderr,"[E] Unknow opcion -%c\n",c); break; } } - + if( ( FLAGBSGSMODE == MODE_BSGS || FLAGBSGSMODE == MODE_PUB2RMD || FLAGBSGSMODE == MODE_MINIKEYS ) && FLAGSTRIDE == 1) { + fprintf(stderr,"[E] Stride doesn't work with BSGS, pub2rmd or minikeys\n"); + exit(0); + } + if(FLAGSTRIDE) { + if(str_stride[0] == '0' && str_stride[1] == 'x') { + stride.SetBase16(str_stride+2); + } + else{ + stride.SetBase16(str_stride); + } + printf("[+] Stride : %s\n",stride.GetBase10()); + } + else { + FLAGSTRIDE = 1; + stride.Set(&ONE); + } init_generator(); if(FLAGMODE == MODE_BSGS ) { printf("[+] Mode BSGS %s\n",bsgs_modes[FLAGBSGSMODE]); @@ -730,6 +767,13 @@ int main(int argc, char **argv) { FLAGCRYPTO = CRYPTO_BTC; printf("[+] Setting search for btc adddress\n"); } + /* + if(FLAGCRYPTO == CRYPTO_ETH) { + FLAGCRYPTO = CRYPTO_BTC; + printf("[+] Setting search for btc adddress\n"); + + } + */ if(FLAGRANGE) { n_range_start.SetBase16(range_start); if(n_range_start.IsZero()) { @@ -793,14 +837,30 @@ int main(int argc, char **argv) { if(N_SECUENTIAL_MAX < 1024) { fprintf(stderr,"[I] n value need to be equal or great than 1024, back to defaults\n"); FLAG_N = 0; - N_SECUENTIAL_MAX = 0xFFFFFFFF; + N_SECUENTIAL_MAX = 0x100000000; } if(N_SECUENTIAL_MAX % 1024 != 0) { fprintf(stderr,"[I] n value need to be multiplier of 1024\n"); FLAG_N = 0; - N_SECUENTIAL_MAX = 0xFFFFFFFF; + N_SECUENTIAL_MAX = 0x100000000; } } + printf("[+] N = %p\n",N_SECUENTIAL_MAX); + + if(FLAGBITRANGE) { // Bit Range + printf("[+] Bit Range %i\n",bitrange); + + } + else { + printf("[+] Range \n"); + } + + hextemp = n_range_start.GetBase16(); + printf("[+] -- from : 0x%s\n",hextemp); + free(hextemp); + hextemp = n_range_end.GetBase16(); + printf("[+] -- to : 0x%s\n",hextemp); + free(hextemp); aux =(char*) malloc(1000); if(aux == NULL) { @@ -808,23 +868,31 @@ int main(int argc, char **argv) { } switch(FLAGMODE) { case MODE_ADDRESS: - while(!feof(fd)) { - hextemp = fgets(aux,998,fd); - if(hextemp == aux) { - trim(aux," \t\n\r"); - r = strlen(aux); - if(r > 10) { //Any length for invalid Address? - if(r > MAXLENGTHADDRESS) { - MAXLENGTHADDRESS = r; + /* We need to count how many lines are in the file */ + while(!feof(fd)) { + hextemp = fgets(aux,998,fd); + if(hextemp == aux) { + trim(aux," \t\n\r"); + r = strlen(aux); + if(r > 10) { //Any length for invalid Address? + if(r > MAXLENGTHADDRESS) { + MAXLENGTHADDRESS = r; + } + N++; } - N++; } } - } - MAXLENGTHADDRESS = 32; + if(FLAGCRYPTO == CRYPTO_BTC) { + MAXLENGTHADDRESS = 32; + } + if(FLAGCRYPTO == CRYPTO_ETH) { + MAXLENGTHADDRESS = 20; /*20 bytes beacuase we only need the data in binary*/ + } break; + case MODE_MINIKEYS: case MODE_PUB2RMD: case MODE_RMD160: + /* RMD160 marked as RAWDATA is a binary file and each register is 20 bytes */ if(FLAGRAWDATA) { while(!feof(fd)) { if(fread(aux,1,20,fd) == 20) { @@ -844,7 +912,7 @@ int main(int argc, char **argv) { } } } - MAXLENGTHADDRESS = 20; + MAXLENGTHADDRESS = 20; /* MAXLENGTHADDRESS is 20 because we save the data in binary format */ break; case MODE_XPOINT: if(FLAGRAWDATA) { @@ -901,25 +969,70 @@ int main(int argc, char **argv) { i = 0; switch (FLAGMODE) { case MODE_ADDRESS: - aux =(char*) malloc(2*MAXLENGTHADDRESS); - if(aux == NULL) { - fprintf(stderr,"[E] error malloc()\n"); - exit(0); + if(FLAGCRYPTO == CRYPTO_BTC) { // BTC address + aux =(char*) malloc(2*MAXLENGTHADDRESS); + if(aux == NULL) { + fprintf(stderr,"[E] error malloc()\n"); + exit(0); + } + while(i < N) { + memset(aux,0,2*MAXLENGTHADDRESS); + memset(addressTable[i].value,0,sizeof(struct address_value)); + hextemp = fgets(aux,2*MAXLENGTHADDRESS,fd); + if(hextemp == aux) { + trim(aux," \t\n\r"); + bloom_add(&bloom, aux,MAXLENGTHADDRESS); + memcpy(addressTable[i].value,aux,20); + i++; + } + else { + trim(aux," \t\n\r"); + fprintf(stderr,"[E] Omiting line : %s\n",aux); + } + } } - while(i < N) { - memset(aux,0,2*MAXLENGTHADDRESS); - memset((void *)&addressTable[i],0,sizeof(struct address_value)); - hextemp = fgets(aux,2*MAXLENGTHADDRESS,fd); - if(hextemp == aux) { - trim(aux," \t\n\r"); - bloom_add(&bloom, aux,MAXLENGTHADDRESS); - memcpy(addressTable[i].value,aux,20); + if(FLAGCRYPTO == CRYPTO_ETH) { // ETH address + aux =(char*) malloc(2*MAXLENGTHADDRESS + 4); // 40 bytes + 0x and the charecter \0 + if(aux == NULL) { + fprintf(stderr,"[E] error malloc()\n"); + exit(0); + } + while(i < N) { + memset(addressTable[i].value,0,sizeof(struct address_value)); + memset(aux,0,2*MAXLENGTHADDRESS + 4); + memset((void *)&addressTable[i],0,sizeof(struct address_value)); + hextemp = fgets(aux,2*MAXLENGTHADDRESS + 4,fd); + if(hextemp == aux) { + trim(aux," \t\n\r"); + switch(strlen(aux)) { + case 42: /*Address with 0x */ + if(isValidHex(aux+2)) { + hexs2bin(aux+2,addressTable[i].value); + bloom_add(&bloom, addressTable[i].value,MAXLENGTHADDRESS); + } + else { + fprintf(stderr,"[E] Omiting line : %s\n",aux); + } + break; + case 40: /*Address without 0x */ + if(isValidHex(aux)) { + hexs2bin(aux,addressTable[i].value); + bloom_add(&bloom, addressTable[i].value,MAXLENGTHADDRESS); + } + else { + fprintf(stderr,"[E] Omiting line : %s\n",aux); + } + break; + + } + } + else { + trim(aux," \t\n\r"); + fprintf(stderr,"[E] Omiting line : %s\n",aux); + } i++; } - else { - trim(aux," \t\n\r"); - fprintf(stderr,"[E] Omiting line : %s\n",aux); - } + } break; case MODE_XPOINT: @@ -1001,11 +1114,11 @@ int main(int argc, char **argv) { fprintf(stderr,"[E] Omiting line : %s\n",aux); N--; } - i++; } } break; + case MODE_MINIKEYS: case MODE_PUB2RMD: case MODE_RMD160: if(FLAGRAWDATA) { @@ -1031,7 +1144,7 @@ int main(int argc, char **argv) { while(i < N) { memset(aux,0,3*MAXLENGTHADDRESS); hextemp = fgets(aux,3*MAXLENGTHADDRESS,fd); - memset(addressTable[i].value,0,20); + memset(addressTable[i].value,0,sizeof(struct address_value)); if(hextemp == aux) { trim(aux," \t\n\r"); lenaux = strlen(aux); @@ -1289,14 +1402,13 @@ int main(int argc, char **argv) { exit(0); } - //if(FLAGDEBUG) bloom_print(&bloom_bPx2nd); printf("[+] Bloom filter for %" PRIu64 " elements : %.2f MB\n",bsgs_m2,(double)((double)bloom_bPx2nd.bytes/(double)1048576)); BSGS_MP = secp->ComputePublicKey(&BSGS_M); BSGS_MP2 = secp->ComputePublicKey(&BSGS_M2); - BSGS_AMP2.reserve(bsgs_m2); + BSGS_AMP2.reserve(20); GSn.reserve(CPU_GRP_SIZE/2); i= 0; @@ -1366,7 +1478,7 @@ int main(int argc, char **argv) { } memset(rawvalue,0,32); - sha256((char*)bloom_bP[i].bf,bloom_bP[i].bytes,rawvalue); + sha256((uint8_t*)bloom_bP[i].bf,bloom_bP[i].bytes,(uint8_t*)rawvalue); if(memcmp(bloom_bP_checksums[i].data,rawvalue,32) != 0 || memcmp(bloom_bP_checksums[i].backup,rawvalue,32) != 0 ) { /* Verification */ fprintf(stderr,"[E] Error checksum file mismatch!\n"); exit(0); @@ -1422,7 +1534,7 @@ int main(int argc, char **argv) { memcpy(bloom_bP_checksums[i].data,oldbloom_bP.checksum,32); memcpy(bloom_bP_checksums[i].backup,oldbloom_bP.checksum_backup,32); memset(rawvalue,0,32); - sha256((char*)bloom_bP[i].bf,bloom_bP[i].bytes,rawvalue); + sha256((uint8_t*)bloom_bP[i].bf,bloom_bP[i].bytes,(uint8_t*)rawvalue); if(memcmp(bloom_bP_checksums[i].data,rawvalue,32) != 0 || memcmp(bloom_bP_checksums[i].backup,rawvalue,32) != 0 ) { /* Verification */ fprintf(stderr,"[E] Error checksum file mismatch!\n"); exit(0); @@ -1484,7 +1596,7 @@ int main(int argc, char **argv) { exit(0); } memset(rawvalue,0,32); - sha256((char*)bloom_bPx2nd.bf,bloom_bPx2nd.bytes,rawvalue); + sha256((uint8_t*)bloom_bPx2nd.bf,bloom_bPx2nd.bytes,(uint8_t*)rawvalue); if(memcmp(bloom_bPx2nd_checksum.data,rawvalue,32) != 0 || memcmp(bloom_bPx2nd_checksum.backup,rawvalue,32) != 0 ) { /* Verification */ fprintf(stderr,"[E] Error checksum file mismatch!\n"); exit(0); @@ -1531,7 +1643,7 @@ int main(int argc, char **argv) { memcpy(bloom_bPx2nd_checksum.data,oldbloom_bP.checksum,32); memcpy(bloom_bPx2nd_checksum.backup,oldbloom_bP.checksum_backup,32); - sha256((char*)bloom_bPx2nd.bf,bloom_bPx2nd.bytes,rawvalue); + sha256((uint8_t*)(char*)bloom_bPx2nd.bf,bloom_bPx2nd.bytes,(uint8_t*)rawvalue); if(memcmp(bloom_bPx2nd_checksum.data,rawvalue,32) != 0 || memcmp(bloom_bPx2nd_checksum.backup,rawvalue,32) != 0 ) { /* Verification */ fprintf(stderr,"[E] Error checksum file mismatch!\n"); exit(0); @@ -1558,7 +1670,7 @@ int main(int argc, char **argv) { exit(0); } fread(checksum,32,1,fd_aux3); - sha256((char*)bPtable,bytes,checksum_backup); + sha256((uint8_t*)bPtable,bytes,(uint8_t*)checksum_backup); if(memcmp(checksum,checksum_backup,32) != 0) { fprintf(stderr,"[E] Checksum from file %s mismatch!!\n",buffer_bloom_file); exit(0); @@ -1710,12 +1822,12 @@ int main(int argc, char **argv) { } if(!FLAGREADEDFILE1) { for(i = 0; i < 256 ; i++) { - sha256((char*)bloom_bP[i].bf, bloom_bP[i].bytes, bloom_bP_checksums[i].data); + sha256((uint8_t*)bloom_bP[i].bf, bloom_bP[i].bytes,(uint8_t*) bloom_bP_checksums[i].data); memcpy(bloom_bP_checksums[i].backup,bloom_bP_checksums[i].data,32); } } if(!FLAGREADEDFILE2) { - sha256((char*)bloom_bPx2nd.bf, bloom_bPx2nd.bytes, bloom_bPx2nd_checksum.data); + sha256((uint8_t*)bloom_bPx2nd.bf, bloom_bPx2nd.bytes,(uint8_t*) bloom_bPx2nd_checksum.data); memcpy(bloom_bPx2nd_checksum.backup,bloom_bPx2nd_checksum.data,32); } if(!FLAGREADEDFILE1 || !FLAGREADEDFILE2 ) { @@ -1726,7 +1838,7 @@ int main(int argc, char **argv) { printf("[+] Sorting %lu elements... ",bsgs_m2); fflush(stdout); bsgs_sort(bPtable,bsgs_m2); - sha256((char*)bPtable, bytes, checksum); + sha256((uint8_t*)bPtable, bytes,(uint8_t*) checksum); memcpy(checksum_backup,checksum,32); printf("Done!\n"); fflush(stdout); @@ -1938,7 +2050,7 @@ int main(int argc, char **argv) { tid[i] = CreateThread(NULL, 0, thread_process, (void*)tt, 0, &s); break; case MODE_PUB2RMD: - tid[i] = CreateThread(NULL, 0, thread_pub2rmd, (void*)tt, 0, &s); + //tid[i] = CreateThread(NULL, 0, thread_pub2rmd, (void*)tt, 0, &s); break; #else case MODE_ADDRESS: @@ -1949,6 +2061,9 @@ int main(int argc, char **argv) { case MODE_PUB2RMD: s = pthread_create(&tid[i],NULL,thread_pub2rmd,(void *)tt); break; + case MODE_MINIKEYS: + s = pthread_create(&tid[i],NULL,thread_process_minikeys,(void *)tt); + break; #endif } if(s != 0) { @@ -2061,9 +2176,34 @@ int main(int argc, char **argv) { CloseHandle(write_random); CloseHandle(bsgs_thread); #endif - } +void pubkeytopubaddress_dst(char *pkey,int length,char *dst) { + char digest[60]; + size_t pubaddress_size = 40; + sha256((uint8_t*)pkey, length,(uint8_t*) digest); + RMD160Data((const unsigned char*)digest,32, digest+1); + digest[0] = 0; + sha256((uint8_t*)digest, 21,(uint8_t*) digest+21); + sha256((uint8_t*)digest+21, 32,(uint8_t*) digest+21); + if(!b58enc(dst,&pubaddress_size,digest,25)){ + fprintf(stderr,"error b58enc\n"); + } +} + +void rmd160toaddress_dst(char *rmd,char *dst){ + char digest[60]; + size_t pubaddress_size = 40; + digest[0] = 0; + memcpy(digest+1,rmd,20); + sha256((uint8_t*)digest, 21,(uint8_t*) digest+21); + sha256((uint8_t*)digest+21, 32,(uint8_t*) digest+21); + if(!b58enc(dst,&pubaddress_size,digest,25)){ + fprintf(stderr,"error b58enc\n"); + } +} + + char *pubkeytopubaddress(char *pkey,int length) { char *pubaddress = (char*) calloc(MAXLENGTHADDRESS+10,1); char *digest = (char*) calloc(60,1); @@ -2073,15 +2213,15 @@ char *pubkeytopubaddress(char *pkey,int length) { exit(0); } //digest [000...0] - sha256(pkey, length, digest); + sha256((uint8_t*)pkey, length,(uint8_t*) digest); //digest [SHA256 32 bytes+000....0] RMD160Data((const unsigned char*)digest,32, digest+1); //digest [? +RMD160 20 bytes+????000....0] digest[0] = 0; //digest [0 +RMD160 20 bytes+????000....0] - sha256(digest, 21, digest+21); + sha256((uint8_t*)digest, 21,(uint8_t*) digest+21); //digest [0 +RMD160 20 bytes+SHA256 32 bytes+....0] - sha256(digest+21, 32, digest+21); + sha256((uint8_t*)digest+21, 32,(uint8_t*) digest+21); //digest [0 +RMD160 20 bytes+SHA256 32 bytes+....0] if(!b58enc(pubaddress,&pubaddress_size,digest,25)){ fprintf(stderr,"error b58enc\n"); @@ -2090,6 +2230,15 @@ char *pubkeytopubaddress(char *pkey,int length) { return pubaddress; // pubaddress need to be free by te caller funtion } +void publickeytohashrmd160_dst(char *pkey,int length,char *dst) { + char digest[32]; + //digest [000...0] + sha256((uint8_t*)pkey, length,(uint8_t*) digest); + //digest [SHA256 32 bytes] + RMD160Data((const unsigned char*)digest,32, dst); + //hash160 [RMD160 20 bytes] +} + char *publickeytohashrmd160(char *pkey,int length) { char *hash160 = (char*) malloc(20); char *digest = (char*) malloc(32); @@ -2098,7 +2247,7 @@ char *publickeytohashrmd160(char *pkey,int length) { exit(0); } //digest [000...0] - sha256(pkey, length, digest); + sha256((uint8_t*)pkey, length,(uint8_t*) digest); //digest [SHA256 32 bytes] RMD160Data((const unsigned char*)digest,32, hash160); //hash160 [RMD160 20 bytes] @@ -2131,6 +2280,133 @@ int searchbinary(struct address_value *buffer,char *data,int64_t _N) { } return r; } + + +#ifdef _WIN64 +DWORD WINAPI thread_process_minikeys(LPVOID vargp) { +#else +void *thread_process_minikeys(void *vargp) { +#endif + FILE *keys; + Point publickey[4]; + Int key_mpz[4]; + struct tothread *tt; + uint64_t count; + char publickeyhashrmd160_uncompress[4][20]; + char public_key_compressed_hex[67],public_key_uncompressed_hex[131]; + char hexstrpoint[65],rawvalue[4][32]; + char address[4][40],minikeys[4][40];; + char *hextemp,*rawbuffer; + int r,thread_number,continue_flag = 1,k,j; + size_t len_dst; + size_t len_source; + Int counter; + tt = (struct tothread *)vargp; + thread_number = tt->nt; + free(tt); + rawbuffer = (char*) &counter.bits64 ; + len_dst = 23; + len_source = 16; + minikeys[0][0] = 'S'; + minikeys[1][0] = 'S'; + minikeys[2][0] = 'S'; + minikeys[3][0] = 'S'; + do { + if(FLAGRANDOM){ + counter.Rand(&n_range_start,&n_range_end); + } + else { + if(n_range_start.IsLower(&n_range_end)) { +#ifdef _WIN64 + WaitForSingleObject(write_random, INFINITE); + counter.Set(&n_range_start); + n_range_start.Add(N_SECUENTIAL_MAX); + ReleaseMutex(write_random); +#else + pthread_mutex_lock(&write_random); + counter.Set(&n_range_start); + n_range_start.Add(N_SECUENTIAL_MAX); + pthread_mutex_unlock(&write_random); +#endif + } + else { + continue_flag = 0; + } + } + if(continue_flag) { + count = 0; + b58enc_custom( minikeys[0] + 1, &len_dst, rawbuffer, len_source,(char*)Ccoinbuffer); + if(FLAGMATRIX) { + hextemp = counter.GetBase16(); + printf("[+] Base key: 0x%s => %s\n",hextemp,minikeys[0]); + fflush(stdout); + free(hextemp); + } + else { + if(FLAGQUIET == 0){ + hextemp = counter.GetBase16(); + printf("\r[+] Base key: 0x%s => %s\r",hextemp,minikeys[0]); + fflush(stdout); + free(hextemp); + THREADOUTPUT = 1; + } + } + do { + for(j = 0;j<256; j++) { + for(k = 0; k < 4; k++){ + do{ + b58enc_custom(minikeys[k] + 1, &len_dst, rawbuffer, len_source,(char*)Ccoinbuffer); + if(len_dst == 23) { + minikeys[k][22] = '?'; + sha256((uint8_t*)minikeys[k],23,(uint8_t*)rawvalue[k]); + } + else { + len_dst = 23; + rawvalue[k][0] = 0x01; + } + counter.AddOne(); + count++; + }while(rawvalue[k][0] != 0x00); + //if(FLAGDEBUG) { printf("minikeys %s\n",minikeys[k]); } + sha256((uint8_t*)minikeys[k],22,(uint8_t*)rawvalue[k]); + key_mpz[k].Set32Bytes((uint8_t*)rawvalue[k]); + publickey[k] = secp->ComputePublicKey(&key_mpz[k]); + //if(FLAGDEBUG) { printf("minikeys %s\n",minikeys[k]); } + } + + secp->GetHash160(P2PKH,false,publickey[0],publickey[1],publickey[2],publickey[3],(uint8_t*)publickeyhashrmd160_uncompress[0],(uint8_t*)publickeyhashrmd160_uncompress[1],(uint8_t*)publickeyhashrmd160_uncompress[2],(uint8_t*)publickeyhashrmd160_uncompress[3]); + for(k = 0; k < 4; k++) { + r = bloom_check(&bloom,publickeyhashrmd160_uncompress[k],20); + if(r) { + r = searchbinary(addressTable,publickeyhashrmd160_uncompress[k],N); + + if(r) { + /* hit */ + hextemp = key_mpz[k].GetBase16(); + secp->GetPublicKeyHex(false,publickey[k],public_key_uncompressed_hex); + pthread_mutex_lock(&write_keys); + keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); + rmd160toaddress_dst(publickeyhashrmd160_uncompress[k],address[k]); + minikeys[k][22] = '\0'; + if(keys != NULL) { + fprintf(keys,"PrivKey: %s\npubkey: %s\nminikey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,minikeys[k],address[k]); + fclose(keys); + } + printf("\nHIT!! PrivKey: %s\npubkey: %s\nminikey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,minikeys[k],address[k]); + pthread_mutex_unlock(&write_keys); + free(hextemp); + } + } + } + } + steps[thread_number]++; + }while(count < N_SECUENTIAL_MAX && continue_flag); + } + }while(continue_flag); + + return NULL; +} + #ifdef _WIN64 DWORD WINAPI thread_process(LPVOID vargp) { #else @@ -2150,19 +2426,21 @@ void *thread_process(void *vargp) { int hLength = (CPU_GRP_SIZE / 2 - 1); uint64_t i,j,count; Point R,temporal; - int r,thread_number,found,continue_flag = 1,i_vanity; - char *public_key_compressed = NULL,*public_key_uncompressed = NULL,hexstrpoint[65],rawvalue[32]; - char *publickeyhashrmd160_compress = NULL,*publickeyhashrmd160_uncompress = NULL; - char *hextemp = NULL,*public_key_compressed_hex = NULL,*public_key_uncompressed_hex = NULL; + int r,thread_number,continue_flag = 1,i_vanity,k; + char *hextemp = NULL; char *eth_address = NULL; - char *public_address_compressed = NULL,*public_address_uncompressed = NULL; + char publickeyhashrmd160_uncompress[4][20],publickeyhashrmd160_compress[4][20]; + char public_key_compressed_hex[67],public_key_uncompressed_hex[131]; + char public_key_compressed[33],public_key_uncompressed[65]; + char hexstrpoint[65],rawvalue[32]; + char address_compressed[4][40],address_uncompressed[4][40]; + unsigned long longtemp; FILE *keys,*vanityKeys; - Int key_mpz,mpz_bit_range_min,mpz_bit_range_max,mpz_bit_range_diff; + Int key_mpz,keyfound,temp_stride; tt = (struct tothread *)vargp; thread_number = tt->nt; free(tt); - found = 0; grp->Set(dx); do { if(FLAGRANDOM){ @@ -2172,18 +2450,15 @@ void *thread_process(void *vargp) { if(n_range_start.IsLower(&n_range_end)) { #ifdef _WIN64 WaitForSingleObject(write_random, INFINITE); -#else - pthread_mutex_lock(&write_random); -#endif key_mpz.Set(&n_range_start); n_range_start.Add(N_SECUENTIAL_MAX); - -#ifdef _WIN64 ReleaseMutex(write_random); #else + pthread_mutex_lock(&write_random); + key_mpz.Set(&n_range_start); + n_range_start.Add(N_SECUENTIAL_MAX); pthread_mutex_unlock(&write_random); #endif - } else { continue_flag = 0; @@ -2191,204 +2466,269 @@ void *thread_process(void *vargp) { } if(continue_flag) { count = 0; + if(FLAGMATRIX) { + hextemp = key_mpz.GetBase16(); + printf("Base key: %s thread %i\n",hextemp,thread_number); + fflush(stdout); + free(hextemp); + } + else { + if(FLAGQUIET == 0){ + hextemp = key_mpz.GetBase16(); + printf("\rBase key: %s \r",hextemp); + fflush(stdout); + free(hextemp); + THREADOUTPUT = 1; + } + } do { - if(FLAGMATRIX) { - hextemp = key_mpz.GetBase16(); - printf("Base key: %s\n",hextemp); - fflush(stdout); - free(hextemp); - } - else { - if(FLAGQUIET == 0){ - hextemp = key_mpz.GetBase16(); - printf("\rBase key: %s \r",hextemp); - fflush(stdout); - free(hextemp); - THREADOUTPUT = 1; - } - } - key_mpz.Add((uint64_t)CPU_GRP_SIZE / 2); + temp_stride.SetInt32(CPU_GRP_SIZE / 2); + temp_stride.Mult(&stride); + key_mpz.Add(&temp_stride); startP = secp->ComputePublicKey(&key_mpz); - key_mpz.Sub((uint64_t)CPU_GRP_SIZE / 2); + key_mpz.Sub(&temp_stride); for(i = 0; i < hLength; i++) { dx[i].ModSub(&Gn[i].x,&startP.x); } - dx[i].ModSub(&Gn[i].x,&startP.x); // For the first point - dx[i + 1].ModSub(&_2Gn.x,&startP.x); // For the next center point - grp->ModInv(); + dx[i].ModSub(&Gn[i].x,&startP.x); // For the first point + dx[i + 1].ModSub(&_2Gn.x,&startP.x); // For the next center point + grp->ModInv(); - pts[CPU_GRP_SIZE / 2] = startP; + pts[CPU_GRP_SIZE / 2] = startP; - for(i = 0; iGetPublicKeyRaw(false,pts[j]); - break; - case SEARCH_COMPRESS: - public_key_compressed = secp->GetPublicKeyRaw(true,pts[j]); - break; - case SEARCH_BOTH: - public_key_uncompressed = secp->GetPublicKeyRaw(false,pts[j]); - public_key_compressed = secp->GetPublicKeyRaw(true,pts[j]); - break; - } - break; + pts[0] = pn; + for(j = 0; j < CPU_GRP_SIZE/4;j++){ + if(FLAGCRYPTO == CRYPTO_BTC){ + switch(FLAGMODE) { + case MODE_ADDRESS: + case MODE_RMD160: + switch(FLAGSEARCH) { + case SEARCH_UNCOMPRESS: + secp->GetHash160(P2PKH,false,pts[(j*4)],pts[(j*4)+1],pts[(j*4)+2],pts[(j*4)+3],(uint8_t*)publickeyhashrmd160_uncompress[0],(uint8_t*)publickeyhashrmd160_uncompress[1],(uint8_t*)publickeyhashrmd160_uncompress[2],(uint8_t*)publickeyhashrmd160_uncompress[3]); + break; + case SEARCH_COMPRESS: + secp->GetHash160(P2PKH,true,pts[(j*4)],pts[(j*4)+1],pts[(j*4)+2],pts[(j*4)+3],(uint8_t*)publickeyhashrmd160_compress[0],(uint8_t*)publickeyhashrmd160_compress[1],(uint8_t*)publickeyhashrmd160_compress[2],(uint8_t*)publickeyhashrmd160_compress[3]); + break; + case SEARCH_BOTH: + secp->GetHash160(P2PKH,true,pts[(j*4)],pts[(j*4)+1],pts[(j*4)+2],pts[(j*4)+3],(uint8_t*)publickeyhashrmd160_compress[0],(uint8_t*)publickeyhashrmd160_compress[1],(uint8_t*)publickeyhashrmd160_compress[2],(uint8_t*)publickeyhashrmd160_compress[3]); + secp->GetHash160(P2PKH,false,pts[(j*4)],pts[(j*4)+1],pts[(j*4)+2],pts[(j*4)+3],(uint8_t*)publickeyhashrmd160_uncompress[0],(uint8_t*)publickeyhashrmd160_uncompress[1],(uint8_t*)publickeyhashrmd160_uncompress[2],(uint8_t*)publickeyhashrmd160_uncompress[3]); + break; + } + break; + } } switch(FLAGMODE) { case MODE_ADDRESS: - if( (FLAGCRYPTO | CRYPTO_BTC) != 0) { - + if( FLAGCRYPTO == CRYPTO_BTC) { switch(FLAGSEARCH) { case SEARCH_UNCOMPRESS: - public_address_uncompressed = pubkeytopubaddress(public_key_uncompressed,65); + for(k = 0; k < 4;k++) { + rmd160toaddress_dst(publickeyhashrmd160_uncompress[k],address_uncompressed[k]); + } break; case SEARCH_COMPRESS: - public_address_compressed = pubkeytopubaddress(public_key_compressed,33); + for(k = 0; k < 4;k++) { + rmd160toaddress_dst(publickeyhashrmd160_compress[k],address_compressed[k]); + } break; case SEARCH_BOTH: - public_address_compressed = pubkeytopubaddress(public_key_compressed,33); - public_address_uncompressed = pubkeytopubaddress(public_key_uncompressed,65); + for(k = 0; k < 4;k++) { + rmd160toaddress_dst(publickeyhashrmd160_uncompress[k],address_uncompressed[k]); + rmd160toaddress_dst(publickeyhashrmd160_compress[k],address_compressed[k]); + } break; } if(FLAGVANITY) { - i_vanity = 0; - while(i_vanity < COUNT_VANITIES) { - if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){ - if(strncmp(public_address_uncompressed,vanities[i_vanity],len_vanities[i_vanity]) == 0) { - hextemp = key_mpz.GetBase16(); - vanityKeys = fopen("vanitykeys.txt","a+"); - if(vanityKeys != NULL) { - fprintf(vanityKeys,"PrivKey: %s\nAddress uncompressed: %s\n",hextemp,public_address_uncompressed); - fclose(vanityKeys); + for(k = 0; k < 4;k++) { + i_vanity = 0; + while(i_vanity < COUNT_VANITIES) { + if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){ + if(strncmp(address_uncompressed[k],vanities[i_vanity],len_vanities[i_vanity]) == 0) { + keyfound.SetInt32(k); + keyfound.Mult(&stride); + keyfound.Add(&key_mpz); + hextemp = keyfound.GetBase16(); + vanityKeys = fopen("vanitykeys.txt","a+"); + if(vanityKeys != NULL) { + fprintf(vanityKeys,"PrivKey: %s\nAddress uncompressed: %s\n",hextemp,address_uncompressed[k]); + fclose(vanityKeys); + } + printf("\nVanity privKey: %s\nAddress uncompressed: %s\n",hextemp,address_uncompressed[k]); + free(hextemp); } - printf("\nVanity privKey: %s\nAddress uncompressed: %s\n",hextemp,public_address_uncompressed); - free(hextemp); } - } - if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){ - if(strncmp(public_address_compressed,vanities[i_vanity],len_vanities[i_vanity]) == 0) { - hextemp = key_mpz.GetBase16(); - vanityKeys = fopen("vanitykeys.txt","a+"); - if(vanityKeys != NULL) { - fprintf(vanityKeys,"PrivKey: %s\nAddress compressed: %s\n",hextemp,public_address_compressed); - fclose(vanityKeys); + if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){ + if(strncmp(address_compressed[k],vanities[i_vanity],len_vanities[i_vanity]) == 0) { + keyfound.SetInt32(k); + keyfound.Mult(&stride); + keyfound.Add(&key_mpz); + hextemp = keyfound.GetBase16(); + vanityKeys = fopen("vanitykeys.txt","a+"); + if(vanityKeys != NULL) { + fprintf(vanityKeys,"PrivKey: %s\nAddress compressed: %s\n",hextemp,address_compressed[k]); + fclose(vanityKeys); + } + printf("\nVanity privKey: %s\nAddress compressed: %s\n",hextemp,address_compressed[k]); + free(hextemp); } - printf("\nVanity privKey: %s\nAddress compressed: %s\n",hextemp,public_address_compressed); - free(hextemp); } + i_vanity ++; } - i_vanity ++; } } if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){ - r = bloom_check(&bloom,public_address_compressed,MAXLENGTHADDRESS); - if(r) { - r = searchbinary(addressTable,public_address_compressed,N); + for(k = 0; k < 4;k++) { + r = bloom_check(&bloom,address_compressed[k],MAXLENGTHADDRESS); if(r) { - found++; - hextemp = key_mpz.GetBase16(); - public_key_compressed_hex = tohex(public_key_compressed,33); + r = searchbinary(addressTable,address_compressed[k],N); + if(r) { + keyfound.SetInt32(k); + keyfound.Mult(&stride); + keyfound.Add(&key_mpz); + hextemp = keyfound.GetBase16(); + secp->GetPublicKeyHex(true,pts[(4*j)+k],public_key_compressed_hex); + #ifdef _WIN64 - WaitForSingleObject(write_keys, INFINITE); + WaitForSingleObject(write_keys, INFINITE); #else - pthread_mutex_lock(&write_keys); + pthread_mutex_lock(&write_keys); #endif - keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); - if(keys != NULL) { - fprintf(keys,"PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_compressed_hex,public_address_compressed); - fclose(keys); + keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); + if(keys != NULL) { + fprintf(keys,"PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_compressed_hex,address_compressed[k]); + fclose(keys); + } + printf("\nHIT!! PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_compressed_hex,address_compressed[k]); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else + pthread_mutex_unlock(&write_keys); +#endif + + free(hextemp); } - printf("\nHIT!! PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_compressed_hex,public_address_compressed); -#ifdef _WIN64 - ReleaseMutex(write_keys); -#else - pthread_mutex_unlock(&write_keys); -#endif - - free(public_key_compressed_hex); - free(hextemp); } } - free(public_address_compressed); } if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){ - r = bloom_check(&bloom,public_address_uncompressed,MAXLENGTHADDRESS); - if(r) { - r = searchbinary(addressTable,public_address_uncompressed,N); + for(k = 0; k < 4;k++) { + r = bloom_check(&bloom,address_uncompressed[k],MAXLENGTHADDRESS); if(r) { - found++; - hextemp = key_mpz.GetBase16(); - public_key_uncompressed_hex = tohex(public_key_uncompressed,65); + r = searchbinary(addressTable,address_uncompressed[k],N); + if(r) { + keyfound.SetInt32(k); + keyfound.Mult(&stride); + keyfound.Add(&key_mpz); + hextemp = keyfound.GetBase16(); + secp->GetPublicKeyHex(false,pts[(4*j)+k],public_key_uncompressed_hex); +#ifdef _WIN64 + WaitForSingleObject(write_keys, INFINITE); +#else + pthread_mutex_lock(&write_keys); +#endif + + keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); + if(keys != NULL) { + fprintf(keys,"PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,address_uncompressed[k]); + fclose(keys); + } + printf("\nHIT!! PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,address_uncompressed[k]); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else + pthread_mutex_unlock(&write_keys); +#endif + free(hextemp); + } + } + } + + } + } + if( FLAGCRYPTO == CRYPTO_ETH) { + for(k = 0; k < 4;k++) { + generate_binaddress_eth(pts[(4*j)+k],(unsigned char*)rawvalue); + /* + hextemp = tohex(rawvalue+12,20); + printf("Eth Address 0x%s\n",hextemp); + free(hextemp); + */ + r = bloom_check(&bloom,rawvalue+12,MAXLENGTHADDRESS); + if(r) { + r = searchbinary(addressTable,rawvalue+12,N); + if(r) { + keyfound.SetInt32(k); + keyfound.Mult(&stride); + keyfound.Add(&key_mpz); + hextemp = keyfound.GetBase16(); + hexstrpoint[0] = '0'; + hexstrpoint[1] = 'x'; + tohex_dst(rawvalue+12,20,hexstrpoint+2); + #ifdef _WIN64 WaitForSingleObject(write_keys, INFINITE); #else @@ -2397,84 +2737,105 @@ void *thread_process(void *vargp) { keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); if(keys != NULL) { - fprintf(keys,"PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,public_address_uncompressed); + fprintf(keys,"PrivKey: %s\naddress: %s\n",hextemp,hexstrpoint); fclose(keys); } - printf("\nHIT!! PrivKey: %s\npubkey: %s\naddress: %s\n",hextemp,public_key_uncompressed_hex,public_address_uncompressed); + printf("\n Hit!!!! PrivKey: %s\naddress: %s\n",hextemp,hexstrpoint); #ifdef _WIN64 ReleaseMutex(write_keys); #else pthread_mutex_unlock(&write_keys); #endif - free(public_key_uncompressed_hex); + free(hextemp); } } - free(public_address_uncompressed); - } - } - if( ( FLAGCRYPTO | CRYPTO_ETH ) != 0) { - - generate_binaddress_eth(&pts[j],(unsigned char*)rawvalue); - - r = bloom_check(&bloom,rawvalue+12,MAXLENGTHADDRESS); - if(r) { - r = searchbinary(addressTable,rawvalue+12,N); - if(r) { - found++; - hextemp = key_mpz.GetBase16(); - hexstrpoint[0] = '0'; - hexstrpoint[1] = 'x'; - tohex_dst(rawvalue+12,20,hexstrpoint+2); - -#ifdef _WIN64 - WaitForSingleObject(write_keys, INFINITE); -#else - pthread_mutex_lock(&write_keys); -#endif - - keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); - if(keys != NULL) { - fprintf(keys,"PrivKey: %s\naddress: %s\n",hextemp,hexstrpoint); - fclose(keys); - } - printf("\n Hit!!!! PrivKey: %s\naddress: %s\n",hextemp,hexstrpoint); -#ifdef _WIN64 - ReleaseMutex(write_keys); -#else - pthread_mutex_unlock(&write_keys); -#endif - - free(hextemp); - } } } break; case MODE_RMD160: - switch(FLAGSEARCH) { - case SEARCH_UNCOMPRESS: - publickeyhashrmd160_uncompress = publickeytohashrmd160(public_key_uncompressed,65); - break; - case SEARCH_COMPRESS: - publickeyhashrmd160_compress = publickeytohashrmd160(public_key_compressed,33); - break; - case SEARCH_BOTH: - publickeyhashrmd160_compress = publickeytohashrmd160(public_key_compressed,33); - publickeyhashrmd160_uncompress = publickeytohashrmd160(public_key_uncompressed,65); - break; - } - - if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){ - r = bloom_check(&bloom,publickeyhashrmd160_compress,MAXLENGTHADDRESS); - if(r) { - r = searchbinary(addressTable,publickeyhashrmd160_compress,N); + for(k = 0; k < 4;k++) { + if(FLAGSEARCH == SEARCH_COMPRESS || FLAGSEARCH == SEARCH_BOTH){ + r = bloom_check(&bloom,publickeyhashrmd160_compress[k],MAXLENGTHADDRESS); if(r) { - found++; - hextemp = key_mpz.GetBase16(); - public_key_compressed_hex = tohex(public_key_compressed,33); + r = searchbinary(addressTable,publickeyhashrmd160_compress[k],N); + if(r) { + keyfound.SetInt32(k); + keyfound.Mult(&stride); + keyfound.Add(&key_mpz); + hextemp = keyfound.GetBase16(); + secp->GetPublicKeyHex(true,pts[(4*j)+k],public_key_compressed_hex); #ifdef _WIN64 - WaitForSingleObject(write_keys, INFINITE); + WaitForSingleObject(write_keys, INFINITE); +#else + pthread_mutex_lock(&write_keys); +#endif + + keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); + if(keys != NULL) { + fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex); + fclose(keys); + } + printf("\nHIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else + pthread_mutex_unlock(&write_keys); +#endif + free(hextemp); + } + } + } + if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH) { + r = bloom_check(&bloom,publickeyhashrmd160_uncompress[k],MAXLENGTHADDRESS); + if(r) { + r = searchbinary(addressTable,publickeyhashrmd160_uncompress[k],N); + if(r) { + keyfound.SetInt32(k); + keyfound.Mult(&stride); + keyfound.Add(&key_mpz); + hextemp = keyfound.GetBase16(); + + secp->GetPublicKeyHex(false,pts[(4*j)+k],public_key_uncompressed_hex); +#ifdef _WIN64 + WaitForSingleObject(write_keys, INFINITE); +#else + pthread_mutex_lock(&write_keys); +#endif + keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); + if(keys != NULL) { + fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_uncompressed_hex); + fclose(keys); + } + printf("\nHIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_uncompressed_hex); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else + pthread_mutex_unlock(&write_keys); +#endif + free(hextemp); + } + } + } + } + break; + case MODE_XPOINT: + for(k = 0; k < 4;k++) { + pts[(4*j)+k].x.Get32Bytes((unsigned char *)rawvalue); + r = bloom_check(&bloom,rawvalue,MAXLENGTHADDRESS); + if(r) { + r = searchbinary(addressTable,rawvalue,N); + if(r) { + keyfound.SetInt32(k); + keyfound.Mult(&stride); + keyfound.Add(&key_mpz); + hextemp = keyfound.GetBase16(); + R = secp->ComputePublicKey(&keyfound); + secp->GetPublicKeyHex(true,R,public_key_compressed_hex); + printf("\nHIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex); +#ifdef _WIN64 + WaitForSingleObject(write_keys, INFINITE); #else pthread_mutex_lock(&write_keys); #endif @@ -2484,130 +2845,48 @@ void *thread_process(void *vargp) { fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex); fclose(keys); } - printf("\nHIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex); -#ifdef _WIN64 - ReleaseMutex(write_keys); -#else - pthread_mutex_unlock(&write_keys); -#endif - - free(public_key_compressed_hex); - free(hextemp); - } - } - free(publickeyhashrmd160_compress); - } - if(FLAGSEARCH == SEARCH_UNCOMPRESS || FLAGSEARCH == SEARCH_BOTH){ - r = bloom_check(&bloom,publickeyhashrmd160_uncompress,MAXLENGTHADDRESS); - if(r) { - r = searchbinary(addressTable,publickeyhashrmd160_uncompress,N); - if(r) { - found++; - hextemp = key_mpz.GetBase16(); - public_key_uncompressed_hex = tohex(public_key_uncompressed,65); -#ifdef _WIN64 - WaitForSingleObject(write_keys, INFINITE); -#else - pthread_mutex_lock(&write_keys); -#endif - keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); - if(keys != NULL) { - fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_uncompressed_hex); - fclose(keys); - } - printf("\nHIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_uncompressed_hex); #ifdef _WIN64 ReleaseMutex(write_keys); #else pthread_mutex_unlock(&write_keys); #endif - free(public_key_uncompressed_hex); free(hextemp); } } - free(publickeyhashrmd160_uncompress); - } - break; - case MODE_XPOINT: - pts[j].x.Get32Bytes((unsigned char *)rawvalue); - r = bloom_check(&bloom,rawvalue,MAXLENGTHADDRESS); - if(r) { - r = searchbinary(addressTable,rawvalue,N); - if(r) { - found++; - hextemp = key_mpz.GetBase16(); - R = secp->ComputePublicKey(&key_mpz); - public_key_compressed = secp->GetPublicKeyHex(true,R); - printf("\nHIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed); -#ifdef _WIN64 - WaitForSingleObject(write_keys, INFINITE); -#else - pthread_mutex_lock(&write_keys); -#endif - - keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); - if(keys != NULL) { - fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed); - fclose(keys); - } -#ifdef _WIN64 - ReleaseMutex(write_keys); -#else - pthread_mutex_unlock(&write_keys); -#endif - - free(public_key_compressed); - free(hextemp); - } } break; } - if(FLAGMODE == MODE_ADDRESS || FLAGMODE == MODE_RMD160) { - switch(FLAGSEARCH) { - case SEARCH_UNCOMPRESS: - free(public_key_uncompressed); - break; - case SEARCH_COMPRESS: - free(public_key_compressed); - break; - case SEARCH_BOTH: - free(public_key_compressed); - free(public_key_uncompressed); - break; - } - } - count++; - if(count % DEBUGCOUNT == 0 ) { - steps[thread_number]++; - } - key_mpz.AddOne(); + count+=4; + temp_stride.SetInt32(4); + temp_stride.Mult(&stride); + key_mpz.Add(&temp_stride); } - - + steps[thread_number]++; // Next start point (startP + GRP_SIZE*G) - pp = startP; - dy.ModSub(&_2Gn.y,&pp.y); + pp = startP; + dy.ModSub(&_2Gn.y,&pp.y); - _s.ModMulK1(&dy,&dx[i + 1]); - _p.ModSquareK1(&_s); + _s.ModMulK1(&dy,&dx[i + 1]); + _p.ModSquareK1(&_s); - pp.x.ModNeg(); - pp.x.ModAdd(&_p); - pp.x.ModSub(&_2Gn.x); + pp.x.ModNeg(); + pp.x.ModAdd(&_p); + pp.x.ModSub(&_2Gn.x); - pp.y.ModSub(&_2Gn.x,&pp.x); - pp.y.ModMulK1(&_s); - pp.y.ModSub(&_2Gn.y); - startP = pp; - }while(count <= N_SECUENTIAL_MAX && continue_flag); + pp.y.ModSub(&_2Gn.x,&pp.x); + pp.y.ModMulK1(&_s); + pp.y.ModSub(&_2Gn.y); + startP = pp; + }while(count < N_SECUENTIAL_MAX && continue_flag); } } while(continue_flag); ends[thread_number] = 1; return NULL; } + void _swap(struct address_value *a,struct address_value *b) { struct address_value t; t = *a; @@ -3133,7 +3412,6 @@ void *thread_process_bsgs(void *vargp) { }// end else }// End if } - steps[thread_number]++; #ifdef _WIN64 WaitForSingleObject(bsgs_thread, INFINITE); @@ -3684,7 +3962,7 @@ void *thread_pub2rmd(void *vargp) { } for(i = 0 ; i < limit ; i++) { pub.parity = 0x02; - sha256((char*)&pub, 33, digest256); + sha256((uint8_t*)&pub, 33, (uint8_t*)digest256); RMD160Data((const unsigned char*)digest256,32, digest160); r = bloom_check(&bloom,digest160,MAXLENGTHADDRESS); if(r) { @@ -3717,7 +3995,7 @@ void *thread_pub2rmd(void *vargp) { } } pub.parity = 0x03; - sha256((char*)&pub, 33, digest256); + sha256((uint8_t*)&pub, 33,(uint8_t*) digest256); RMD160Data((const unsigned char*)digest256,32, digest160); r = bloom_check(&bloom,digest160,MAXLENGTHADDRESS); if(r) { @@ -3753,21 +4031,23 @@ void *thread_pub2rmd(void *vargp) { if(pub.X.data32[7] % DEBUGCOUNT == 0) { steps[thread_number]++; } - } /* End for */ - } /* End if */ + } + } }while(pub2rmd_continue); ends[thread_number] = 1; return NULL; } void init_generator() { - Point g = secp->G; + Point G = secp->ComputePublicKey(&stride); + Point g; + g.Set(G); Gn.reserve(CPU_GRP_SIZE / 2); Gn[0] = g; g = secp->DoubleDirect(g); Gn[1] = g; for(int i = 2; i < CPU_GRP_SIZE / 2; i++) { - g = secp->AddDirect(g,secp->G); + g = secp->AddDirect(g,G); Gn[i] = g; } _2Gn = secp->DoubleDirect(Gn[CPU_GRP_SIZE / 2 - 1]); @@ -3974,13 +4254,10 @@ void KECCAK_256(uint8_t *source, size_t size,uint8_t *dst) { KECCAK_256_Final(dst,&ctx); } -void generate_binaddress_eth(Point *publickey,unsigned char *dst_address) { +void generate_binaddress_eth(Point &publickey,unsigned char *dst_address) { unsigned char bin_publickey[64]; - unsigned char bin_sha256[32]; - size_t pubaddress_size = 50; - memset(dst_address,0,32); - publickey->x.Get32Bytes(bin_publickey); - publickey->y.Get32Bytes(bin_publickey+32); + publickey.x.Get32Bytes(bin_publickey); + publickey.y.Get32Bytes(bin_publickey+32); KECCAK_256(bin_publickey, 64, dst_address); } @@ -5005,7 +5282,7 @@ void memorycheck_bsgs() { char current_checksum[32]; char *hextemp,*aux_c; //if(FLAGDEBUG )printf("[D] Performing Memory checksum \n"); - sha256((char*)bPtable,bytes,current_checksum); + sha256((uint8_t*)bPtable,bytes,(uint8_t*)current_checksum); if(memcmp(current_checksum,checksum,32) != 0 || memcmp(current_checksum,checksum_backup,32) != 0) { fprintf(stderr,"[E] Memory checksum mismatch, this should not happen but actually happened\nA bit in the memory was flipped by : electrical malfuntion, radiation or a cosmic ray\n"); hextemp = tohex(current_checksum,32); @@ -5017,3 +5294,297 @@ void memorycheck_bsgs() { exit(0); } } + +#ifdef _WIN64 +DWORD WINAPI thread_rmdcustom(LPVOID vargp) { +#else +void *thread_rmdcustom(void *vargp) { +#endif + struct tothread *tt; + Point pts[CPU_GRP_SIZE]; + Int dx[CPU_GRP_SIZE / 2 + 1]; + IntGroup *grp = new IntGroup(CPU_GRP_SIZE / 2 + 1); + Point startP; + Int dy; + Int dyn; + Int _s; + Int _p; + Point pp; + Point pn; + int hLength = (CPU_GRP_SIZE / 2 - 1); + char *ptr_u64range; + uint64_t i,j,count; + Point R,temporal; + int r,thread_number,continue_flag = 1,i_vanity,k; + char public_key_compressed[33],publickeyhashrmd160_compress[4][20],public_key_compressed_hex[68]; + char *public_key_uncompressed = NULL,hexstrpoint[65],rawvalue[32]; + char *publickeyhashrmd160_uncompress = NULL; + char *hextemp = NULL,*public_key_uncompressed_hex = NULL; + char *eth_address = NULL; + char *public_address_compressed = NULL,*public_address_uncompressed = NULL; + unsigned long longtemp; + FILE *keys,*vanityKeys; + Int key_mpz,mpz_bit_range_min,mpz_bit_range_max,mpz_bit_range_diff; + tt = (struct tothread *)vargp; + thread_number = tt->nt; + free(tt); + grp->Set(dx); + /* + ptr_u64range = (char*) &u64range; + + pthread_mutex_lock(&write_random); + ptr_u64range[0] = n_range_start.GetByte(3); + ptr_u64range[1] = n_range_start.GetByte(4); + ptr_u64range[2] = n_range_start.GetByte(5); + ptr_u64range[3] = n_range_start.GetByte(6); + ptr_u64range[4] = n_range_start.GetByte(7); + pthread_mutex_unlock(&write_random); + + pthread_mutex_lock(&write_random); + next_average(&u64range,0.45,0.65,0x10000000000,40); + pthread_mutex_unlock(&write_random); + printf("[+] u64range : %p\n",(void*)u64range); + */ + + do { + if(FLAGRANDOM){ + key_mpz.Rand(&n_range_start,&n_range_end); + } + else { + if(n_range_start.IsLower(&n_range_end)) { +#ifdef _WIN64 + WaitForSingleObject(write_random, INFINITE); +#else + pthread_mutex_lock(&write_random); +#endif + key_mpz.Set(&n_range_start); + n_range_start.Add(N_SECUENTIAL_MAX); + +#ifdef _WIN64 + ReleaseMutex(write_random); +#else + pthread_mutex_unlock(&write_random); +#endif + + } + else { + continue_flag = 0; + } + } + if(continue_flag) { + count = 0; + do { + /* + key_mpz.SetByte(0,0); + key_mpz.SetByte(1,0); + key_mpz.SetByte(2,0); + */ + if(FLAGMATRIX) { + hextemp = key_mpz.GetBase16(); + printf("Base key: %s\n",hextemp); + fflush(stdout); + free(hextemp); + } + else { + if(FLAGQUIET == 0){ + hextemp = key_mpz.GetBase16(); + printf("\rBase key: %s \r",hextemp); + fflush(stdout); + free(hextemp); + THREADOUTPUT = 1; + } + } + key_mpz.Add((uint64_t)(CPU_GRP_SIZE / 2)); + startP = secp->ComputePublicKey(&key_mpz); + key_mpz.Sub((uint64_t)(CPU_GRP_SIZE / 2)); + + for(i = 0; i < hLength; i++) { + dx[i].ModSub(&Gn[i].x,&startP.x); + } + + dx[i].ModSub(&Gn[i].x,&startP.x); // For the first point + dx[i + 1].ModSub(&_2Gn.x,&startP.x); // For the next center point + grp->ModInv(); + + pts[CPU_GRP_SIZE / 2] = startP; + + for(i = 0; iGetPublicKeyRaw(true,pts[j],public_key_compressed); + /* + void Secp256K1::GetHash160(int type,bool compressed, + Point &k0,Point &k1,Point &k2,Point &k3, + uint8_t *h0,uint8_t *h1,uint8_t *h2,uint8_t *h3) { + */ + secp->GetHash160(P2PKH,true,pts[(j*4)],pts[(j*4)+1],pts[(j*4)+2],pts[(j*4)+3],(uint8_t*)publickeyhashrmd160_compress[0],(uint8_t*)publickeyhashrmd160_compress[1],(uint8_t*)publickeyhashrmd160_compress[2],(uint8_t*)publickeyhashrmd160_compress[3]); + for(k=0;k < 4;k++) { + + r = bloom_check(&bloom,publickeyhashrmd160_compress[k],MAXLENGTHADDRESS); + if(r) { + r = searchbinary(addressTable,publickeyhashrmd160_compress[k],N); + if(r) { + secp->GetPublicKeyRaw(true,pts[(j*4)+k],public_key_compressed); + hextemp = key_mpz.GetBase16(); + tohex_dst(public_key_compressed,33,public_key_compressed_hex); +#ifdef _WIN64 + WaitForSingleObject(write_keys, INFINITE); +#else + pthread_mutex_lock(&write_keys); +#endif + keys = fopen("KEYFOUNDKEYFOUND.txt","a+"); + if(keys != NULL) { + fprintf(keys,"PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex); + fclose(keys); + } + printf("\nHIT!! PrivKey: %s\npubkey: %s\n",hextemp,public_key_compressed_hex); +#ifdef _WIN64 + ReleaseMutex(write_keys); +#else + pthread_mutex_unlock(&write_keys); +#endif + + free(hextemp); + } + } + key_mpz.AddOne(); + count++; + } + } + /* + This increment the step counter for the speed calculations + each steps is goin to be 1024 keys more to the counter + */ + steps[thread_number]++; + + + // Next start point (startP + GRP_SIZE*G) + pp = startP; + dy.ModSub(&_2Gn.y,&pp.y); + + _s.ModMulK1(&dy,&dx[i + 1]); + _p.ModSquareK1(&_s); + + pp.x.ModNeg(); + pp.x.ModAdd(&_p); + pp.x.ModSub(&_2Gn.x); + + pp.y.ModSub(&_2Gn.x,&pp.x); + pp.y.ModMulK1(&_s); + pp.y.ModSub(&_2Gn.y); + startP = pp; + }while(count < N_SECUENTIAL_MAX && continue_flag); + /* + pthread_mutex_lock(&write_random); + next_average(&u64range,0.40,0.65,0x10000000000,40); + pthread_mutex_unlock(&write_random); + printf("[+] u64range : %p\n",(void*)u64range); + */ + } + } while(continue_flag); + ends[thread_number] = 1; + return NULL; +} + +/* +bool next_average(uint64_t *value,float min,float max, uint64_t value_max,int bits) { + char buffer[20]; + uint64_t counter; + uint8_t *values; + int bytes,i,repeated,len; + int ones; + float ratio; + bytes = bits/8; + values = (uint8_t *)value; + counter = 0; + do { + do{ + do { + ones = 0; + value[0]++; + for(i = 0; i < bytes; i++) { + ones+= one_counter[values[i]]; + } + ratio = (float)((float)ones/(float)bits); + counter++; + }while( (ratio < min || ratio > max ) && value[0] < value_max ); + repeated = 0; + for(i = 0; i < bytes-1 && !repeated; i++) { + if(values[i] == values[i+1]) { + repeated = 1; + } + } + }while(repeated && value[0] < value_max); + + snprintf(buffer,20,"%p",value[0]); + len = strlen(buffer); + for(i = 2; i < len-2 && !repeated; i++) { + if(buffer[i] == buffer[i+1] && buffer[i+1] == buffer[i+2]) { + repeated = 1; + } + } + }while(repeated && value[0] < value_max); + + if(value[0] < value_max) + return true; + else + return false; +}*/ \ No newline at end of file diff --git a/rmd160/rmd160.h b/rmd160/rmd160.h index 225470e..9ba7804 100644 --- a/rmd160/rmd160.h +++ b/rmd160/rmd160.h @@ -28,15 +28,23 @@ typedef struct RMD160Context { #define RIPEMD160Context RMD160Context +#ifdef _WIN64 +#else #include __BEGIN_DECLS +#endif + void RMD160Init(RMD160_CTX *); void RMD160Update(RMD160_CTX *, const unsigned char *, unsigned int); void RMD160Final(unsigned char [RMD160_HASHBYTES], RMD160_CTX *); char * RMD160End(RMD160_CTX *, char *); char * RMD160File(const char *, char *); void RMD160Data(const unsigned char *, unsigned int, char *); +#ifdef _WIN64 +#else __END_DECLS +#endif + #endif /* _RMD160_H_ */ diff --git a/secp256k1/SECP256K1.cpp b/secp256k1/SECP256K1.cpp index 221a09a..a7afc8d 100644 --- a/secp256k1/SECP256K1.cpp +++ b/secp256k1/SECP256K1.cpp @@ -20,6 +20,8 @@ #include "SECP256k1.h" #include "Point.h" #include "../util.h" +#include "../hash/sha256.h" +#include "../hash/ripemd160.h" Secp256K1::Secp256K1() { } @@ -506,4 +508,215 @@ Point Secp256K1::ScalarMultiplication(Point &P,Int *scalar) { } R.Reduce(); return R; -} \ No newline at end of file +} + +#define KEYBUFFCOMP(buff,p) \ +(buff)[0] = ((p).x.bits[7] >> 8) | ((uint32_t)(0x2 + (p).y.IsOdd()) << 24); \ +(buff)[1] = ((p).x.bits[6] >> 8) | ((p).x.bits[7] <<24); \ +(buff)[2] = ((p).x.bits[5] >> 8) | ((p).x.bits[6] <<24); \ +(buff)[3] = ((p).x.bits[4] >> 8) | ((p).x.bits[5] <<24); \ +(buff)[4] = ((p).x.bits[3] >> 8) | ((p).x.bits[4] <<24); \ +(buff)[5] = ((p).x.bits[2] >> 8) | ((p).x.bits[3] <<24); \ +(buff)[6] = ((p).x.bits[1] >> 8) | ((p).x.bits[2] <<24); \ +(buff)[7] = ((p).x.bits[0] >> 8) | ((p).x.bits[1] <<24); \ +(buff)[8] = 0x00800000 | ((p).x.bits[0] <<24); \ +(buff)[9] = 0; \ +(buff)[10] = 0; \ +(buff)[11] = 0; \ +(buff)[12] = 0; \ +(buff)[13] = 0; \ +(buff)[14] = 0; \ +(buff)[15] = 0x108; + +#define KEYBUFFUNCOMP(buff,p) \ +(buff)[0] = ((p).x.bits[7] >> 8) | 0x04000000; \ +(buff)[1] = ((p).x.bits[6] >> 8) | ((p).x.bits[7] <<24); \ +(buff)[2] = ((p).x.bits[5] >> 8) | ((p).x.bits[6] <<24); \ +(buff)[3] = ((p).x.bits[4] >> 8) | ((p).x.bits[5] <<24); \ +(buff)[4] = ((p).x.bits[3] >> 8) | ((p).x.bits[4] <<24); \ +(buff)[5] = ((p).x.bits[2] >> 8) | ((p).x.bits[3] <<24); \ +(buff)[6] = ((p).x.bits[1] >> 8) | ((p).x.bits[2] <<24); \ +(buff)[7] = ((p).x.bits[0] >> 8) | ((p).x.bits[1] <<24); \ +(buff)[8] = ((p).y.bits[7] >> 8) | ((p).x.bits[0] <<24); \ +(buff)[9] = ((p).y.bits[6] >> 8) | ((p).y.bits[7] <<24); \ +(buff)[10] = ((p).y.bits[5] >> 8) | ((p).y.bits[6] <<24); \ +(buff)[11] = ((p).y.bits[4] >> 8) | ((p).y.bits[5] <<24); \ +(buff)[12] = ((p).y.bits[3] >> 8) | ((p).y.bits[4] <<24); \ +(buff)[13] = ((p).y.bits[2] >> 8) | ((p).y.bits[3] <<24); \ +(buff)[14] = ((p).y.bits[1] >> 8) | ((p).y.bits[2] <<24); \ +(buff)[15] = ((p).y.bits[0] >> 8) | ((p).y.bits[1] <<24); \ +(buff)[16] = 0x00800000 | ((p).y.bits[0] <<24); \ +(buff)[17] = 0; \ +(buff)[18] = 0; \ +(buff)[19] = 0; \ +(buff)[20] = 0; \ +(buff)[21] = 0; \ +(buff)[22] = 0; \ +(buff)[23] = 0; \ +(buff)[24] = 0; \ +(buff)[25] = 0; \ +(buff)[26] = 0; \ +(buff)[27] = 0; \ +(buff)[28] = 0; \ +(buff)[29] = 0; \ +(buff)[30] = 0; \ +(buff)[31] = 0x208; + +#define KEYBUFFSCRIPT(buff,h) \ +(buff)[0] = 0x00140000 | (uint32_t)h[0] << 8 | (uint32_t)h[1]; \ +(buff)[1] = (uint32_t)h[2] << 24 | (uint32_t)h[3] << 16 | (uint32_t)h[4] << 8 | (uint32_t)h[5];\ +(buff)[2] = (uint32_t)h[6] << 24 | (uint32_t)h[7] << 16 | (uint32_t)h[8] << 8 | (uint32_t)h[9];\ +(buff)[3] = (uint32_t)h[10] << 24 | (uint32_t)h[11] << 16 | (uint32_t)h[12] << 8 | (uint32_t)h[13];\ +(buff)[4] = (uint32_t)h[14] << 24 | (uint32_t)h[15] << 16 | (uint32_t)h[16] << 8 | (uint32_t)h[17];\ +(buff)[5] = (uint32_t)h[18] << 24 | (uint32_t)h[19] << 16 | 0x8000; \ +(buff)[6] = 0; \ +(buff)[7] = 0; \ +(buff)[8] = 0; \ +(buff)[9] = 0; \ +(buff)[10] = 0; \ +(buff)[11] = 0; \ +(buff)[12] = 0; \ +(buff)[13] = 0; \ +(buff)[14] = 0; \ +(buff)[15] = 0xB0; + + +void Secp256K1::GetHash160(int type,bool compressed, + Point &k0,Point &k1,Point &k2,Point &k3, + uint8_t *h0,uint8_t *h1,uint8_t *h2,uint8_t *h3) { + +#ifdef WIN64 + __declspec(align(16)) unsigned char sh0[64]; + __declspec(align(16)) unsigned char sh1[64]; + __declspec(align(16)) unsigned char sh2[64]; + __declspec(align(16)) unsigned char sh3[64]; +#else + unsigned char sh0[64] __attribute__((aligned(16))); + unsigned char sh1[64] __attribute__((aligned(16))); + unsigned char sh2[64] __attribute__((aligned(16))); + unsigned char sh3[64] __attribute__((aligned(16))); +#endif + + switch (type) { + + case P2PKH: + case BECH32: + { + + if (!compressed) { + + uint32_t b0[32]; + uint32_t b1[32]; + uint32_t b2[32]; + uint32_t b3[32]; + + KEYBUFFUNCOMP(b0, k0); + KEYBUFFUNCOMP(b1, k1); + KEYBUFFUNCOMP(b2, k2); + KEYBUFFUNCOMP(b3, k3); + + sha256sse_2B(b0, b1, b2, b3, sh0, sh1, sh2, sh3); + ripemd160sse_32(sh0, sh1, sh2, sh3, h0, h1, h2, h3); + + } else { + + uint32_t b0[16]; + uint32_t b1[16]; + uint32_t b2[16]; + uint32_t b3[16]; + + KEYBUFFCOMP(b0, k0); + KEYBUFFCOMP(b1, k1); + KEYBUFFCOMP(b2, k2); + KEYBUFFCOMP(b3, k3); + + sha256sse_1B(b0, b1, b2, b3, sh0, sh1, sh2, sh3); + ripemd160sse_32(sh0, sh1, sh2, sh3, h0, h1, h2, h3); + + } + + } + break; + + case P2SH: + { + + unsigned char kh0[20]; + unsigned char kh1[20]; + unsigned char kh2[20]; + unsigned char kh3[20]; + + GetHash160(P2PKH,compressed,k0,k1,k2,k3,kh0,kh1,kh2,kh3); + + // Redeem Script (1 to 1 P2SH) + uint32_t b0[16]; + uint32_t b1[16]; + uint32_t b2[16]; + uint32_t b3[16]; + + KEYBUFFSCRIPT(b0, kh0); + KEYBUFFSCRIPT(b1, kh1); + KEYBUFFSCRIPT(b2, kh2); + KEYBUFFSCRIPT(b3, kh3); + + sha256sse_1B(b0, b1, b2, b3, sh0, sh1, sh2, sh3); + ripemd160sse_32(sh0, sh1, sh2, sh3, h0, h1, h2, h3); + + } + break; + + } +} + +void Secp256K1::GetHash160(int type, bool compressed, Point &pubKey, unsigned char *hash) { + + unsigned char shapk[64]; + + switch (type) { + + case P2PKH: + case BECH32: + { + unsigned char publicKeyBytes[128]; + + if (!compressed) { + + // Full public key + publicKeyBytes[0] = 0x4; + pubKey.x.Get32Bytes(publicKeyBytes + 1); + pubKey.y.Get32Bytes(publicKeyBytes + 33); + sha256_65(publicKeyBytes, shapk); + + } else { + + // Compressed public key + publicKeyBytes[0] = pubKey.y.IsEven() ? 0x2 : 0x3; + pubKey.x.Get32Bytes(publicKeyBytes + 1); + sha256_33(publicKeyBytes, shapk); + + } + + ripemd160_32(shapk, hash); + } + break; + + case P2SH: + { + + // Redeem Script (1 to 1 P2SH) + unsigned char script[64]; + + script[0] = 0x00; // OP_0 + script[1] = 0x14; // PUSH 20 bytes + GetHash160(P2PKH, compressed, pubKey, script + 2); + + sha256(script, 22, shapk); + ripemd160_32(shapk, hash); + + } + break; + + } + +} + diff --git a/secp256k1/SECP256k1.h b/secp256k1/SECP256k1.h index 0f6d678..dddac30 100644 --- a/secp256k1/SECP256k1.h +++ b/secp256k1/SECP256k1.h @@ -21,6 +21,12 @@ #include "Point.h" #include +// Address type +#define P2PKH 0 +#define P2SH 1 +#define BECH32 2 + + class Secp256K1 { public: @@ -42,6 +48,13 @@ public: bool ParsePublicKeyHex(char *str,Point &p,bool &isCompressed); + void GetHash160(int type,bool compressed, + Point &k0, Point &k1, Point &k2, Point &k3, + uint8_t *h0, uint8_t *h1, uint8_t *h2, uint8_t *h3); + + void GetHash160(int type,bool compressed, Point &pubKey, unsigned char *hash); + + Point Add(Point &p1, Point &p2); Point Add2(Point &p1, Point &p2); Point AddDirect(Point &p1, Point &p2); diff --git a/sha256/sha256.c b/sha256/sha256.c deleted file mode 100644 index 6b1c579..0000000 --- a/sha256/sha256.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - SHA256 implementation, source file. - - This implementation was written by Kent "ethereal" Williams-King and is - hereby released into the public domain. Do what you wish with it. - - No guarantees as to the correctness of the implementation are provided. -*/ - -#include -#include - -const uint32_t sha256_initial_h[8] - = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; - -const uint32_t sha256_round_k[64] - = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, - 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, - 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, - 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, - 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, - 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; - -void sha256_endian_reverse64(uint64_t input, uint8_t *output) { - output[7] = (input >> 0) & 0xff; - output[6] = (input >> 8) & 0xff; - output[5] = (input >> 16) & 0xff; - output[4] = (input >> 24) & 0xff; - output[3] = (input >> 32) & 0xff; - output[2] = (input >> 40) & 0xff; - output[1] = (input >> 48) & 0xff; - output[0] = (input >> 56) & 0xff; -} - -uint32_t sha256_endian_read32(uint8_t *input) { - uint32_t output = 0; - output |= (input[0] << 24); - output |= (input[1] << 16); - output |= (input[2] << 8); - output |= (input[3] << 0); - - return output; -} - -void sha256_endian_reverse32(uint32_t input, uint8_t *output) { - output[3] = (input >> 0) & 0xff; - output[2] = (input >> 8) & 0xff; - output[1] = (input >> 16) & 0xff; - output[0] = (input >> 24) & 0xff; -} - -uint32_t sha256_ror(uint32_t input, uint32_t by) { - return (input >> by) | (((input & ((1 << by) - 1))) << (32 - by)); -} - -void sha256(const void *data, uint64_t len, void *output) { - uint8_t padding[80]; - uint64_t current = (len + 1) % 64; - // want to be == 56 % 64. - uint64_t needed = (64 + 56 - current) % 64; - uint64_t extra = needed + 9; - uint64_t total = len + extra; - - for(int i = 1; i < 80; i++) - padding[i] = 0; - padding[0] = 0x80; - sha256_endian_reverse64(len * 8, padding + total - len - 8); - - uint32_t v[8]; - for(int i = 0; i < 8; i++) - v[i] = sha256_initial_h[i]; - - for(uint64_t cursor = 0; cursor * 64 < total; cursor++) { - uint32_t t[8]; - for(int i = 0; i < 8; i++) - t[i] = v[i]; - - uint32_t w[64]; - if(cursor * 64 + 64 <= len) { - for(int j = 0; j < 16; j++) { - w[j] = sha256_endian_read32( - (uint8_t *)data + cursor * 64 + j * 4); - } - } - else { - if(cursor * 64 < len) { - uint64_t size = len - cursor * 64; - if(size > 0) memcpy(w, (uint8_t *)data + cursor * 64, size); - memcpy((uint8_t *)w + size, padding, 64 - size); - } - else { - uint64_t off = (cursor * 64 - len) % 64; - memcpy((uint8_t *)w, padding + off, 64); - } - - for(int j = 0; j < 16; j++) { - w[j] = sha256_endian_read32((uint8_t *)&w[j]); - } - } - - for(int j = 16; j < 64; j++) { - uint32_t s1 = sha256_ror(w[j - 2], 17) ^ sha256_ror(w[j - 2], 19) - ^ (w[j - 2] >> 10); - uint32_t s0 = sha256_ror(w[j - 15], 7) ^ sha256_ror(w[j - 15], 18) - ^ (w[j - 15] >> 3); - w[j] = s1 + w[j - 7] + s0 + w[j - 16]; - } - - for(int j = 0; j < 64; j++) { - uint32_t ch = (t[4] & t[5]) ^ (~t[4] & t[6]); - uint32_t maj = (t[0] & t[1]) ^ (t[0] & t[2]) ^ (t[1] & t[2]); - uint32_t S0 = sha256_ror(t[0], 2) ^ sha256_ror(t[0], 13) - ^ sha256_ror(t[0], 22); - uint32_t S1 = sha256_ror(t[4], 6) ^ sha256_ror(t[4], 11) - ^ sha256_ror(t[4], 25); - - uint32_t t1 = t[7] + S1 + ch + sha256_round_k[j] + w[j]; - uint32_t t2 = S0 + maj; - - t[7] = t[6]; - t[6] = t[5]; - t[5] = t[4]; - t[4] = t[3] + t1; - t[3] = t[2]; - t[2] = t[1]; - t[1] = t[0]; - t[0] = t1 + t2; - } - - for(int i = 0; i < 8; i++) - v[i] += t[i]; - } - - for(int i = 0; i < 8; i++) - sha256_endian_reverse32(v[i], (uint8_t *)output + i * 4); -} diff --git a/sha256/sha256.h b/sha256/sha256.h deleted file mode 100644 index 5b169b9..0000000 --- a/sha256/sha256.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - SHA256 implementation, header file. - - This implementation was written by Kent "ethereal" Williams-King and is - hereby released into the public domain. Do what you wish with it. - - No guarantees as to the correctness of the implementation are provided. -*/ - -#ifndef SHA256_H -#define SHA256_H - -#include - -void sha256(const void *data, uint64_t len, void *output); - -#endif diff --git a/tests/1to32.eth b/tests/1to32.eth new file mode 100644 index 0000000..1ecaed3 --- /dev/null +++ b/tests/1to32.eth @@ -0,0 +1,32 @@ +0x7e5f4552091a69125d5dfcb7b8c2659029395bdf +0x6813eb9362372eef6200f3b1dbc3f819671cba69 +0xd41c057fd1c78805aac12b0a94a405c0461a6fbb +0xf1f6619b38a98d6de0800f1defc0a6399eb6d30c +0x157bfbecd023fd6384dad2bded5dad7e27bf92e4 +0xf472086186382fca55cd182de196520abd76f69d +0x1ac6f9601f2f616badcea8a0a307e1a3c14767a4 +0xf084bbaabee1a700a8faa404027db620a5aa0059 +0x4aff4d8fa086e079584c5532569135d1ac620a87 +0x86b1b106aeac5c5d2b16f9596755811cf976f34e +0x2c559fed4b8a8e12e170740d4dabb4fc7d3f9b49 +0xd15a50df0d1d54b0931f462fda35a458aa301e42 +0xdba02a942650eb93cf2566dbcb7d945b9544afcd +0x0fc0e54f047efb3fd041837213ecb572ad594263 +0x8b7696dca505e006408f9b0e8bdffdd20993e15e +0xf1527b97640c3935df498110dccd4ce9181c7743 +0x6ef0691fa9edd5a21e6be331d5c4aa21c18a520d +0x3224ebd2c99ca8afa709701d40868f16b38c70a2 +0xf050fe24f538bf83140a0af5a725b4f8d16f242e +0x5abfc823a8b0691ebada0a41cd6fab2f15a0a628 +0x4ec431274ed8e1996f1451775b9e11e7db613955 +0x504ec8f62a160702b3414a2b460789e9c36b7a2a +0x86df25873cb695d3fa3781f34a6b55e5f17dba74 +0xd2c71c0b28f045d0e6facc19a3a6a81a85a17ce4 +0xa96e58a5ca39ed6baf8bc7692e7d79df039fbcb8 +0xe392229bd7664f4ce539303ce60a2235d915caca +0x2dc9fb4b9ffa330b3c3371311a31e08e962241af +0xfda5c442e76a95f96c09782f1a15d3b58e32404f +0x5f3358241c45ac7987f5ed24e4003843d4c369cb +0x083522c909665aa7ac151892a3a847cbb382b5d4 +0xbd21f11c662cad4fa062e5741310083004086e52 +0xa1401f0c1e75cc40055d9e6a3f25adf11ea876ec diff --git a/tests/minikeys.txt b/tests/minikeys.txt new file mode 100644 index 0000000..053a11e --- /dev/null +++ b/tests/minikeys.txt @@ -0,0 +1,3 @@ +da88f47133b93a1cc0c9dcf0163b2b48e2e0a20a +24b6ed321b3ccfe1fc2e6860e3f89d4d5ab257da +2312e3b76db5b91c5ad34eaea194c2ee6ece6f13