mirror of
https://github.com/albertobsd/keyhunt.git
synced 2025-03-17 13:21:46 +01:00
ethereum, minikeys, stride,rmd double speed
This commit is contained in:
parent
a69ec16ab7
commit
93b5aaf2ad
@ -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
|
||||
|
8
Makefile
8
Makefile
@ -1,7 +1,7 @@
|
||||
default:
|
||||
g++ -O3 -c oldbloom/bloom.cpp -o oldbloom.o
|
||||
g++ -O3 -c bloom/bloom.cpp -o bloom.o
|
||||
g++ -O3 -c sha256/sha256.c -o sha256.o
|
||||
# g++ -O3 -c sha256/sha256.c -o sha256.o
|
||||
gcc -O3 -c base58/base58.c -o base58.o
|
||||
gcc -O3 -c rmd160/rmd160.c -o rmd160.o
|
||||
g++ -O3 -c sha3/sha3.c -o sha3.o
|
||||
@ -14,7 +14,11 @@ default:
|
||||
g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/IntMod.cpp -o IntMod.o
|
||||
g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/Random.cpp -o Random.o
|
||||
g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/IntGroup.cpp -o IntGroup.o
|
||||
g++ -o keyhunt keyhunt.cpp base58.o rmd160.o sha256.o bloom.o oldbloom.o xxhash.o util.o Int.o Point.o SECP256K1.o IntMod.o Random.o IntGroup.o sha3.o keccak.o -lm -lpthread
|
||||
g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/ripemd160.o -c hash/ripemd160.cpp
|
||||
g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/sha256.o -c hash/sha256.cpp
|
||||
g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/ripemd160_sse.o -c hash/ripemd160_sse.cpp
|
||||
g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/sha256_sse.o -c hash/sha256_sse.cpp
|
||||
g++ -o keyhunt keyhunt.cpp base58.o rmd160.o hash/ripemd160.o hash/ripemd160_sse.o hash/sha256.o hash/sha256_sse.o bloom.o oldbloom.o xxhash.o util.o Int.o Point.o SECP256K1.o IntMod.o Random.o IntGroup.o sha3.o keccak.o -lm -lpthread
|
||||
rm -r *.o
|
||||
clean:
|
||||
rm keyhunt
|
||||
|
172
README.md
172
README.md
@ -1,12 +1,16 @@
|
||||
# keyhunt
|
||||
|
||||
Tool for hunt privatekeys for crypto currencies that use secp256k1 elliptic curve
|
||||
|
||||
Post: https://bitcointalk.org/index.php?topic=5322040.0
|
||||
|
||||
Work for btc in this moment, only legacy Addresses that start with '1'
|
||||
|
||||
Ethereum addresses is a work in develop
|
||||
Work for Bitcoin
|
||||
- address compress or uncompress
|
||||
- hashes rmd160 compress or uncompress
|
||||
- publickeys compress or uncompress
|
||||
|
||||
Work for Ethereum
|
||||
- address
|
||||
|
||||
## For regulars users
|
||||
|
||||
@ -25,28 +29,38 @@ don't forget change to the keyhunt directory
|
||||
`cd keyhunt`
|
||||
|
||||
# How to build
|
||||
|
||||
First compile:
|
||||
|
||||
`make`
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
and then execute with `-h` to see the help
|
||||
|
||||
```./keyhunt -h```
|
||||
```
|
||||
./keyhunt -h
|
||||
```
|
||||
|
||||
|
||||
## ¡Beta!
|
||||
This version is still a *beta* version, there are a lot of things that can be fail. And absoluly there are some bugs
|
||||
|
||||
This version is still a **beta** version, there are a lot of things that can be fail. And absoluly there are some bugs
|
||||
|
||||
# Modes
|
||||
|
||||
Keyhunt can work in diferents ways at different speeds.
|
||||
|
||||
The current availables modes are:
|
||||
- address
|
||||
- rmd160
|
||||
- xpoint
|
||||
- bsgs
|
||||
|
||||
you can select them with `-m`
|
||||
## Experimental modes
|
||||
|
||||
- minikeys
|
||||
- pub2rmd
|
||||
|
||||
## address mode
|
||||
|
||||
@ -496,6 +510,7 @@ Output:
|
||||
|
||||
|
||||
## pub2rmd mode
|
||||
|
||||
This method is made to try to get the puzzles publickey key it works a little more faster because it skip the EC Operations
|
||||
|
||||
The input file need to have the hash RMD160 of the address without publickey leaked:
|
||||
@ -1049,6 +1064,148 @@ user 2m15.706s
|
||||
sys 0m13.009s
|
||||
```
|
||||
|
||||
## minikeys Mode
|
||||
|
||||
This mode is some experimental.
|
||||
|
||||
For the moment only Minikeys of 22 characters are available
|
||||
|
||||
The minikey are generated from a 16 byte buffer using the base58 encode funtion using the next string `S23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz` any sugestion please let me know.
|
||||
|
||||
|
||||
|
||||
This minikeys are generated in a deterministic way using one Intenger number from `1` to `0x100000000000000000000000000000000` that is why the range is from `-r 1:100000000000000000000000000000000`
|
||||
|
||||
|
||||
|
||||
Command:
|
||||
|
||||
```
|
||||
./keyhunt -m minikeys -f minkey_h160.txt -r 1:100000000000000000000000000000000 -n 0x1000000 -M
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
[+] Version 0.2.211024 Chocolate ¡Beta!, developed by AlbertoBSD
|
||||
[+] Mode minikeys
|
||||
[+] Matrix screen
|
||||
[+] Stride : 1
|
||||
[+] Opening file minkey_h160.txt
|
||||
[+] N = 0x1000000
|
||||
[+] Range
|
||||
[+] -- from : 0x1
|
||||
[+] -- to : 0x100000000000000000000000000000000
|
||||
[+] Allocating memory for 61560 elements: 1.17 MB
|
||||
[+] Bloom filter for 61560 elements.
|
||||
[+] Loading data to the bloomfilter total: 0.21 MB
|
||||
[+] Bloomfilter completed
|
||||
[+] Sorting data ... done! 61560 values were loaded and sorted
|
||||
[+] Base key: 0x1 => S8AQGAut7N92awznwCnjuR
|
||||
[+] Base key: 0x1000001 => S8AQGFk5PpkiBMwcrkM943
|
||||
[+] Base key: 0x2000001 => S8AQGLaGgHNPmmtSnHuYCf
|
||||
[+] Total 141312 keys in 30 seconds: 4710 keys/s
|
||||
```
|
||||
|
||||
Please note that total keys tested at the moment are only 141312, those are the valid keys that pass the check-test.
|
||||
|
||||
the input file need to be a list of the RMD160 hash from the target address, example `tests/minikeys.txt`
|
||||
|
||||
```
|
||||
da88f47133b93a1cc0c9dcf0163b2b48e2e0a20a
|
||||
24b6ed321b3ccfe1fc2e6860e3f89d4d5ab257da
|
||||
2312e3b76db5b91c5ad34eaea194c2ee6ece6f13
|
||||
```
|
||||
|
||||
command
|
||||
|
||||
```
|
||||
./keyhunt -m minikeys -f tests/minikeys.txt -r 1:100000000000000000000000000000000 -n 0x1000000 -M
|
||||
```
|
||||
|
||||
output:
|
||||
|
||||
```
|
||||
[+] Version 0.2.211024 Chocolate ¡Beta!, developed by AlbertoBSD
|
||||
[+] Mode minikeys
|
||||
[+] Matrix screen
|
||||
[+] Stride : 1
|
||||
[+] Opening file tests/minikeys.txt
|
||||
[+] N = 0x1000000
|
||||
[+] Range
|
||||
[+] -- from : 0x1
|
||||
[+] -- to : 0x100000000000000000000000000000000
|
||||
[+] Allocating memory for 3 elements: 0.00 MB
|
||||
[+] Bloom filter for 3 elements.
|
||||
[+] Loading data to the bloomfilter total: 0.00 MB
|
||||
[+] Bloomfilter completed
|
||||
[+] Sorting data ... done! 3 values were loaded and sorted
|
||||
[+] Base key: 0x1 => S8AQGAut7N92awznwCnjuR
|
||||
|
||||
HIT!! PrivKey: c4302796060742e218520bc5a4d3282ad4b8e3bf32ea2faeb1cc75cbbda33eed
|
||||
pubkey: 04fe4fee3a7f5fbc9289e1857cb2a84e0fc532a470b37635f419fdfcac9379c4c7fe2c29d36add668f38ddc18e0064a18f22467dd02a902406b7aa61112eec5249
|
||||
minikey: SUCsVzCwXiNaW4bnBuzx8Q
|
||||
address: 14CTHBV5S2fd9DPbKmMhrAe5se54Q85wqN
|
||||
|
||||
HIT!! PrivKey: 3711a88da553ea782f9f8935cc10a9642191041e6d8e22ba1e48b7abf613047d
|
||||
pubkey: 04c5180db6ad25ba53d0c39ca95925f8554e71fbf15024f64cd105be307633975bc54ad824fcb85682053158a4a22ea4c61267a4d53b23b0c114d32ad581a5fe30
|
||||
minikey: SUpxjSMeoHoXuTVhy9VYQm
|
||||
address: 14M8TsBG3ntFiTm8XcDiBmHaECfZarfSw8
|
||||
|
||||
HIT!! PrivKey: 82d02f3df7b73d7e6d8be2e3636461d3680263a07bd2e63e92e855840ecc2740
|
||||
pubkey: 04e6ebe21d214d13e547c74c8bf81fdf85cee2ba5d80e3ff1d4d0ef2d4542da9f938ae79f4c6f07f7ad4205794fc5e6e613146e6d218d5ddcb06377765a00baf7e
|
||||
minikey: SNQeNHzJXCJ3PcFUKB7bNv
|
||||
address: 1LvWNcKf4LuWcyCmZkEev8hMusQ4qr55L8
|
||||
^C
|
||||
```
|
||||
|
||||
|
||||
|
||||
# Ethereum
|
||||
|
||||
Finally ethreum address are supported, for ethreum there are no modes exect for address.
|
||||
|
||||
if you have publickeys for ethereum you can use xpoint or bsgs mode.
|
||||
|
||||
to test the functionality of ethereum you can use the sample file `tests/1to32.eth`
|
||||
|
||||
command:
|
||||
|
||||
```
|
||||
./keyhunt -c eth -f tests/1to32.eth -r 1:100000000 -M
|
||||
```
|
||||
|
||||
output:
|
||||
|
||||
```
|
||||
[+] Version 0.2.211024 Chocolate ¡Beta!, developed by AlbertoBSD
|
||||
[+] Setting search for ETH adddress.
|
||||
[+] Matrix screen
|
||||
[+] Stride : 1
|
||||
[+] Opening file tests/1to32.eth
|
||||
[+] N = 0x100000000
|
||||
[+] Range
|
||||
[+] -- from : 0x1
|
||||
[+] -- to : 0x100000000
|
||||
[+] Allocating memory for 32 elements: 0.00 MB
|
||||
[+] Bloom filter for 32 elements.
|
||||
[+] Loading data to the bloomfilter total: 0.00 MB
|
||||
[+] Bloomfilter completed
|
||||
[+] Sorting data ... done! 32 values were loaded and sorted
|
||||
Base key: 1 thread 0
|
||||
|
||||
Hit!!!! PrivKey: 1
|
||||
address: 0x7e5f4552091a69125d5dfcb7b8c2659029395bdf
|
||||
|
||||
Hit!!!! PrivKey: 3
|
||||
address: 0x6813eb9362372eef6200f3b1dbc3f819671cba69
|
||||
|
||||
Hit!!!! PrivKey: 7
|
||||
address: 0xd41c057fd1c78805aac12b0a94a405c0461a6fbb
|
||||
....
|
||||
```
|
||||
|
||||
|
||||
|
||||
## FAQ
|
||||
|
||||
@ -1084,7 +1241,6 @@ R: No, is just to help to speed up a little the load process and no more, but th
|
||||
|
||||
## Dependencies
|
||||
- pthread
|
||||
|
||||
Tested under Debian, Ubuntu Shell for windows 10
|
||||
|
||||
## Thanks
|
||||
|
@ -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];
|
||||
|
@ -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
316
hash/ripemd160.cpp
Normal 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
56
hash/ripemd160.h
Normal 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
409
hash/ripemd160_sse.cpp
Normal 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
502
hash/sha256.cpp
Normal 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
35
hash/sha256.h
Normal 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
627
hash/sha256_sse.cpp
Normal 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
406
hash/sha512.cpp
Normal 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
28
hash/sha512.h
Normal 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
|
1353
keyhunt.cpp
1353
keyhunt.cpp
File diff suppressed because it is too large
Load Diff
@ -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_ */
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
142
sha256/sha256.c
142
sha256/sha256.c
@ -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);
|
||||
}
|
@ -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
32
tests/1to32.eth
Normal 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
3
tests/minikeys.txt
Normal file
@ -0,0 +1,3 @@
|
||||
da88f47133b93a1cc0c9dcf0163b2b48e2e0a20a
|
||||
24b6ed321b3ccfe1fc2e6860e3f89d4d5ab257da
|
||||
2312e3b76db5b91c5ad34eaea194c2ee6ece6f13
|
Loading…
x
Reference in New Issue
Block a user