Skip to content
This repository was archived by the owner on Apr 11, 2022. It is now read-only.

Commit 5a920da

Browse files
authored
Merge pull request #20 from kmyk/issue/5
#5: add sha256 support
2 parents 250f1cb + 420c97e commit 5a920da

File tree

8 files changed

+96
-3
lines changed

8 files changed

+96
-3
lines changed

CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,19 @@ if (OPENMP_FOUND)
1717
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
1818
endif ()
1919

20+
# check OpenSSL
21+
find_package(OpenSSL REQUIRED)
22+
2023
include_directories (include)
2124
set (sources
2225
src/md5-avx2.c
2326
src/sha1-avx2.c
27+
src/sha256-openssl.c
2428
src/common.c
2529
)
2630
add_library (proofofwork-shared SHARED ${sources})
2731
add_library (proofofwork-static STATIC ${sources})
2832
set_target_properties (proofofwork-shared PROPERTIES OUTPUT_NAME proofofwork)
2933
set_target_properties (proofofwork-static PROPERTIES OUTPUT_NAME proofofwork)
34+
target_link_libraries(proofofwork-shared ${OPENSSL_LIBRARIES})
35+
target_link_libraries(proofofwork-static ${OPENSSL_LIBRARIES})

bindings/python/proofofwork/__init__.py

+21
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
library.pow_set_num_threads.argtypes = (ctypes.c_int, )
1818
library.pow_md5_mine.restype = ctypes.c_bool
1919
library.pow_sha1_mine.restype = ctypes.c_bool
20+
library.pow_sha256_mine.restype = ctypes.c_bool
2021

2122
def _call(
2223
func, hash, text,
@@ -174,3 +175,23 @@ def sha1(hash, text=None, num_threads=None, alphabet=None):
174175
text_length_limit=sha1_text_length_limit,
175176
indices_length=8,
176177
)
178+
179+
SHA256_DIGEST_LENGTH = 32
180+
SHA256_BLOCK_LENGTH = 64
181+
sha256_text_length_limit = 44
182+
def sha256(hash, text=None, num_threads=None, alphabet=None):
183+
'''
184+
:type hash: str or None
185+
:type text: bytes or None
186+
:rtype: bytes
187+
'''
188+
return _call(
189+
library.pow_sha256_mine,
190+
hash, text,
191+
num_threads=num_threads,
192+
alphabet=alphabet,
193+
digest_length=SHA256_DIGEST_LENGTH,
194+
block_length=SHA256_BLOCK_LENGTH,
195+
text_length_limit=sha256_text_length_limit,
196+
indices_length=8,
197+
)

bindings/python/setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def run(self):
4040

4141
setup(
4242
name='proofofwork',
43-
version='0.0.11',
43+
version='0.0.12',
4444
description='Simple hash-mining library',
4545
author='Kimiyuki Onaka',
4646
author_email='[email protected]',

bindings/python/tests/main.py

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ def test_md5(self):
1818
def test_sha1(self):
1919
self.snippet_random_test(proofofwork.sha1, hashlib.sha1)
2020

21+
def test_sha256(self):
22+
self.snippet_random_test(proofofwork.sha256, hashlib.sha256)
23+
2124
def snippet_random_test_full(self, mine, answer):
2225
digest_length = len(answer(b'').hexdigest())
2326
for _ in range(10):
@@ -48,6 +51,9 @@ def test_md5_full(self):
4851
def test_sha1_full(self):
4952
self.snippet_random_test_full(proofofwork.sha1, hashlib.sha1)
5053

54+
def test_sha256_full(self):
55+
self.snippet_random_test_full(proofofwork.sha256, hashlib.sha256)
56+
5157
def snippet_hand_test(self, mine, answer):
5258
s = '012'
5359
result = mine(s, text=br'\\\?????')
@@ -62,6 +68,9 @@ def test_md5_hand(self):
6268
def test_sha1_hand(self):
6369
self.snippet_hand_test(proofofwork.sha1, hashlib.sha1)
6470

71+
def test_sha256_hand(self):
72+
self.snippet_hand_test(proofofwork.sha256, hashlib.sha256)
73+
6574

6675

6776
if __name__ == '__main__':

include/proofofwork-private.h

+1
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,6 @@ extern size_t alphabet_size;
4545
// for benchmark
4646
extern uint64_t pow_md5_count;
4747
extern uint64_t pow_sha1_count;
48+
extern uint64_t pow_sha256_count;
4849

4950
#endif

include/proofofwork.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ enum { pow_md5_digest_length = 16 };
2929
/**
3030
* @param [in] mask the length must be pow_md5_digest_length.
3131
* @param [in] target the length must be pow_md5_digest_length.
32-
* @param [in,out] buffer the length must be pow_md5_digest_length.
32+
* @param [in,out] buffer the length must be at most pow_md5_block_length.
3333
* @param [in] size
3434
* @param [in] indices indices of buffer to modify. the length must be pow_indices.
3535
* @return whether a text is found or not.
@@ -40,4 +40,8 @@ enum { pow_sha1_block_length = 64 };
4040
enum { pow_sha1_digest_length = 20 };
4141
bool pow_sha1_mine(uint8_t const *mask, uint8_t const *target, uint8_t *buffer, uint64_t size, int32_t const *indices);
4242

43+
enum { pow_sha256_block_length = 64 };
44+
enum { pow_sha256_digest_length = 32 };
45+
bool pow_sha256_mine(uint8_t const *mask, uint8_t const *target, uint8_t *buffer, uint64_t size, int32_t const *indices);
46+
4347
#endif

src/md5-avx2.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ bool pow_md5_mine(uint8_t const *mask, uint8_t const *target, uint8_t *buffer, u
3838
if (indices[i] < -1 or (int64_t)size <= indices[i]) return false;
3939
}
4040
if (indices[0] == -1) return false;
41-
if (size > pow_sha1_block_length - sizeof(uint64_t) / CHAR_BIT - 1) return false;
41+
if (size > pow_md5_block_length - sizeof(uint64_t) / CHAR_BIT - 1) return false;
4242

4343
// load hash
4444
const uint32_t mask_a = ((uint32_t *)mask)[0];

src/sha256-openssl.c

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#define _BSD_SOURCE
2+
#include <stdint.h>
3+
#include <iso646.h>
4+
#include <stdbool.h>
5+
#include <string.h>
6+
#include <openssl/sha.h>
7+
#include "proofofwork-private.h"
8+
9+
uint64_t pow_sha256_count = 0; // for benchmark
10+
bool pow_sha256_mine(uint8_t const *mask, uint8_t const *target, uint8_t *buffer, uint64_t size, int32_t const *indices) {
11+
// check arguments
12+
static_assert (__BYTE_ORDER == __LITTLE_ENDIAN, "");
13+
if (mask == NULL) return false;
14+
if (target == NULL) return false;
15+
if (buffer == NULL) return false;
16+
if (indices == NULL) return false;
17+
for (int i = 0; i < pow_indices_length; ++ i) {
18+
if (indices[i] < -1 or (int64_t)size <= indices[i]) return false;
19+
}
20+
if (indices[0] == -1) return false;
21+
if (size > pow_sha256_block_length - sizeof(uint64_t) / CHAR_BIT - 1) return false;
22+
23+
// search
24+
bool found = false;
25+
uint64_t cnt = 0;
26+
static_assert (pow_indices_length == 8, "");
27+
repeat (i7, alphabet_size) { if (indices[7] != -1) buffer[indices[7]] = alphabet[i7];
28+
repeat (i6, alphabet_size) { if (indices[6] != -1) buffer[indices[6]] = alphabet[i6];
29+
repeat (i5, alphabet_size) { if (indices[5] != -1) buffer[indices[5]] = alphabet[i5];
30+
repeat (i4, alphabet_size) { if (indices[4] != -1) buffer[indices[4]] = alphabet[i4];
31+
repeat (i3, alphabet_size) { if (indices[3] != -1) buffer[indices[3]] = alphabet[i3];
32+
repeat (i2, alphabet_size) { if (indices[2] != -1) buffer[indices[2]] = alphabet[i2];
33+
repeat (i1, alphabet_size) { if (indices[1] != -1) buffer[indices[1]] = alphabet[i1];
34+
repeat (i0, alphabet_size) { if (indices[0] != -1) buffer[indices[0]] = alphabet[i0];
35+
uint8_t digest[pow_sha256_digest_length];
36+
SHA256(buffer, size, digest);
37+
++ cnt;
38+
found = true;
39+
repeat (j, pow_sha256_digest_length) {
40+
if ((digest[j] & mask[j]) != (target[j] & mask[j])) {
41+
found = false;
42+
break;
43+
}
44+
}
45+
if (found) goto done;
46+
}}}}}}}}
47+
done: ;
48+
49+
// leave
50+
pow_sha256_count = cnt;
51+
return found;
52+
}

0 commit comments

Comments
 (0)