ethereum, minikeys, stride,rmd double speed

This commit is contained in:
AlbertoBSD 2021-10-25 19:38:06 +02:00
parent a69ec16ab7
commit 93b5aaf2ad
21 changed files with 3837 additions and 563 deletions

View File

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

View File

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

172
README.md
View File

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

View File

@ -5,7 +5,7 @@
* under the terms of the standard MIT license. See COPYING for more details.
*/
#ifndef WIN32
#ifndef _WIN64
#include <arpa/inet.h>
#else
#include <winsock2.h>
@ -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];

View File

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

316
hash/ripemd160.cpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "ripemd160.h"
#include <string.h>
/// 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);
}

56
hash/ripemd160.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef RIPEMD160_H
#define RIPEMD160_H
#include <stdint.h>
#include <stdlib.h>
#include <string>
/** 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

409
hash/ripemd160_sse.cpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "ripemd160.h"
#include <string.h>
#include <immintrin.h>
// 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");
}

502
hash/sha256.cpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#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);
}

35
hash/sha256.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef SHA256_H
#define SHA256_H
#include <string>
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

627
hash/sha256_sse.cpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "sha256.h"
#include <immintrin.h>
#include <string.h>
#include <stdint.h>
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

406
hash/sha512.cpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "sha512.h"
#define BSWAP
#define SHA512_BLOCK_SIZE 128
#define SHA512_HASH_LENGTH 64
#define MIN(x,y) (x<y)?x:y;
#define MAX(x,y) (x>y)?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);
}

28
hash/sha512.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef SHA512_H
#define SHA512_H
#include <string>
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

File diff suppressed because it is too large Load Diff

View File

@ -28,15 +28,23 @@ typedef struct RMD160Context {
#define RIPEMD160Context RMD160Context
#ifdef _WIN64
#else
#include <sys/cdefs.h>
__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_ */

View File

@ -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;
}
}
#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;
}
}

View File

@ -21,6 +21,12 @@
#include "Point.h"
#include <vector>
// 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);

View File

@ -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 <stdint.h>
#include <string.h>
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);
}

View File

@ -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 <stdint.h>
void sha256(const void *data, uint64_t len, void *output);
#endif

32
tests/1to32.eth Normal file
View File

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

3
tests/minikeys.txt Normal file
View File

@ -0,0 +1,3 @@
da88f47133b93a1cc0c9dcf0163b2b48e2e0a20a
24b6ed321b3ccfe1fc2e6860e3f89d4d5ab257da
2312e3b76db5b91c5ad34eaea194c2ee6ece6f13