ethash 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,79 @@
1
+ #pragma once
2
+
3
+ #include <stdint.h>
4
+ #include "compiler.h"
5
+
6
+ #if defined(__MINGW32__) || defined(_WIN32)
7
+ # define LITTLE_ENDIAN 1234
8
+ # define BYTE_ORDER LITTLE_ENDIAN
9
+ #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
10
+ # include <sys/endian.h>
11
+ #elif defined(__OpenBSD__) || defined(__SVR4)
12
+ # include <sys/types.h>
13
+ #elif defined(__APPLE__)
14
+ # include <machine/endian.h>
15
+ #elif defined( BSD ) && (BSD >= 199103)
16
+ # include <machine/endian.h>
17
+ #elif defined( __QNXNTO__ ) && defined( __LITTLEENDIAN__ )
18
+ # define LITTLE_ENDIAN 1234
19
+ # define BYTE_ORDER LITTLE_ENDIAN
20
+ #elif defined( __QNXNTO__ ) && defined( __BIGENDIAN__ )
21
+ # define BIG_ENDIAN 1234
22
+ # define BYTE_ORDER BIG_ENDIAN
23
+ #else
24
+ # include <endian.h>
25
+ #endif
26
+
27
+ #if defined(_WIN32)
28
+ #include <stdlib.h>
29
+ #define ethash_swap_u32(input_) _byteswap_ulong(input_)
30
+ #define ethash_swap_u64(input_) _byteswap_uint64(input_)
31
+ #elif defined(__APPLE__)
32
+ #include <libkern/OSByteOrder.h>
33
+ #define ethash_swap_u32(input_) OSSwapInt32(input_)
34
+ #define ethash_swap_u64(input_) OSSwapInt64(input_)
35
+ #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
36
+ #define ethash_swap_u32(input_) bswap32(input_)
37
+ #define ethash_swap_u64(input_) bswap64(input_)
38
+ #elif defined(__OpenBSD__)
39
+ #include <endian.h>
40
+ #define ethash_swap_u32(input_) swap32(input_)
41
+ #define ethash_swap_u64(input_) swap64(input_)
42
+ #else // posix
43
+ #include <byteswap.h>
44
+ #define ethash_swap_u32(input_) bswap_32(input_)
45
+ #define ethash_swap_u64(input_) bswap_64(input_)
46
+ #endif
47
+
48
+
49
+ #if LITTLE_ENDIAN == BYTE_ORDER
50
+
51
+ #define fix_endian32(dst_ ,src_) dst_ = src_
52
+ #define fix_endian32_same(val_)
53
+ #define fix_endian64(dst_, src_) dst_ = src_
54
+ #define fix_endian64_same(val_)
55
+ #define fix_endian_arr32(arr_, size_)
56
+ #define fix_endian_arr64(arr_, size_)
57
+
58
+ #elif BIG_ENDIAN == BYTE_ORDER
59
+
60
+ #define fix_endian32(dst_, src_) dst_ = ethash_swap_u32(src_)
61
+ #define fix_endian32_same(val_) val_ = ethash_swap_u32(val_)
62
+ #define fix_endian64(dst_, src_) dst_ = ethash_swap_u64(src_
63
+ #define fix_endian64_same(val_) val_ = ethash_swap_u64(val_)
64
+ #define fix_endian_arr32(arr_, size_) \
65
+ do { \
66
+ for (unsigned i_ = 0; i_ < (size_), ++i_) { \
67
+ arr_[i_] = ethash_swap_u32(arr_[i_]); \
68
+ } \
69
+ while (0)
70
+ #define fix_endian_arr64(arr_, size_) \
71
+ do { \
72
+ for (unsigned i_ = 0; i_ < (size_), ++i_) { \
73
+ arr_[i_] = ethash_swap_u64(arr_[i_]); \
74
+ } \
75
+ while (0) \
76
+
77
+ #else
78
+ # error "endian not supported"
79
+ #endif // BYTE_ORDER
@@ -0,0 +1,147 @@
1
+ /*
2
+ This file is part of ethash.
3
+
4
+ ethash is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ ethash is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU General Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License
15
+ along with ethash. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ /** @file ethash.h
19
+ * @date 2015
20
+ */
21
+ #pragma once
22
+
23
+ #include <stdint.h>
24
+ #include <stdbool.h>
25
+ #include <string.h>
26
+ #include <stddef.h>
27
+ #include "compiler.h"
28
+
29
+ #define ETHASH_REVISION 23
30
+ #define ETHASH_DATASET_BYTES_INIT 1073741824U // 2**30
31
+ #define ETHASH_DATASET_BYTES_GROWTH 8388608U // 2**23
32
+ #define ETHASH_CACHE_BYTES_INIT 1073741824U // 2**24
33
+ #define ETHASH_CACHE_BYTES_GROWTH 131072U // 2**17
34
+ #define ETHASH_EPOCH_LENGTH 30000U
35
+ #define ETHASH_MIX_BYTES 128
36
+ #define ETHASH_HASH_BYTES 64
37
+ #define ETHASH_DATASET_PARENTS 256
38
+ #define ETHASH_CACHE_ROUNDS 3
39
+ #define ETHASH_ACCESSES 64
40
+ #define ETHASH_DAG_MAGIC_NUM_SIZE 8
41
+ #define ETHASH_DAG_MAGIC_NUM 0xFEE1DEADBADDCAFE
42
+
43
+ #ifdef __cplusplus
44
+ extern "C" {
45
+ #endif
46
+
47
+ /// Type of a seedhash/blockhash e.t.c.
48
+ typedef struct ethash_h256 { uint8_t b[32]; } ethash_h256_t;
49
+
50
+ // convenience macro to statically initialize an h256_t
51
+ // usage:
52
+ // ethash_h256_t a = ethash_h256_static_init(1, 2, 3, ... )
53
+ // have to provide all 32 values. If you don't provide all the rest
54
+ // will simply be unitialized (not guranteed to be 0)
55
+ #define ethash_h256_static_init(...) \
56
+ { {__VA_ARGS__} }
57
+
58
+ struct ethash_light;
59
+ typedef struct ethash_light* ethash_light_t;
60
+ struct ethash_full;
61
+ typedef struct ethash_full* ethash_full_t;
62
+ typedef int(*ethash_callback_t)(unsigned);
63
+
64
+ typedef struct ethash_return_value {
65
+ ethash_h256_t result;
66
+ ethash_h256_t mix_hash;
67
+ bool success;
68
+ } ethash_return_value_t;
69
+
70
+ /**
71
+ * Allocate and initialize a new ethash_light handler
72
+ *
73
+ * @param block_number The block number for which to create the handler
74
+ * @return Newly allocated ethash_light handler or NULL in case of
75
+ * ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
76
+ */
77
+ ethash_light_t ethash_light_new(uint64_t block_number);
78
+ /**
79
+ * Frees a previously allocated ethash_light handler
80
+ * @param light The light handler to free
81
+ */
82
+ void ethash_light_delete(ethash_light_t light);
83
+ /**
84
+ * Calculate the light client data
85
+ *
86
+ * @param light The light client handler
87
+ * @param header_hash The header hash to pack into the mix
88
+ * @param nonce The nonce to pack into the mix
89
+ * @return an object of ethash_return_value_t holding the return values
90
+ */
91
+ ethash_return_value_t ethash_light_compute(
92
+ ethash_light_t light,
93
+ ethash_h256_t const header_hash,
94
+ uint64_t nonce
95
+ );
96
+
97
+ /**
98
+ * Allocate and initialize a new ethash_full handler
99
+ *
100
+ * @param light The light handler containing the cache.
101
+ * @param callback A callback function with signature of @ref ethash_callback_t
102
+ * It accepts an unsigned with which a progress of DAG calculation
103
+ * can be displayed. If all goes well the callback should return 0.
104
+ * If a non-zero value is returned then DAG generation will stop.
105
+ * Be advised. A progress value of 100 means that DAG creation is
106
+ * almost complete and that this function will soon return succesfully.
107
+ * It does not mean that the function has already had a succesfull return.
108
+ * @return Newly allocated ethash_full handler or NULL in case of
109
+ * ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
110
+ */
111
+ ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback);
112
+
113
+ /**
114
+ * Frees a previously allocated ethash_full handler
115
+ * @param full The light handler to free
116
+ */
117
+ void ethash_full_delete(ethash_full_t full);
118
+ /**
119
+ * Calculate the full client data
120
+ *
121
+ * @param full The full client handler
122
+ * @param header_hash The header hash to pack into the mix
123
+ * @param nonce The nonce to pack into the mix
124
+ * @return An object of ethash_return_value to hold the return value
125
+ */
126
+ ethash_return_value_t ethash_full_compute(
127
+ ethash_full_t full,
128
+ ethash_h256_t const header_hash,
129
+ uint64_t nonce
130
+ );
131
+ /**
132
+ * Get a pointer to the full DAG data
133
+ */
134
+ void const* ethash_full_dag(ethash_full_t full);
135
+ /**
136
+ * Get the size of the DAG data
137
+ */
138
+ uint64_t ethash_full_dag_size(ethash_full_t full);
139
+
140
+ /**
141
+ * Calculate the seedhash for a given block number
142
+ */
143
+ ethash_h256_t ethash_get_seedhash(uint64_t block_number);
144
+
145
+ #ifdef __cplusplus
146
+ }
147
+ #endif
@@ -0,0 +1,43 @@
1
+ /*
2
+ This file is part of cpp-ethereum.
3
+
4
+ cpp-ethereum is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ cpp-ethereum is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU General Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License
15
+ along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+ /** @file fnv.h
18
+ * @author Matthew Wampler-Doty <negacthulhu@gmail.com>
19
+ * @date 2015
20
+ */
21
+
22
+ #pragma once
23
+ #include <stdint.h>
24
+ #include "compiler.h"
25
+
26
+ #ifdef __cplusplus
27
+ extern "C" {
28
+ #endif
29
+
30
+ #define FNV_PRIME 0x01000193
31
+
32
+ /* The FNV-1 spec multiplies the prime with the input one byte (octet) in turn.
33
+ We instead multiply it with the full 32-bit input.
34
+ This gives a different result compared to a canonical FNV-1 implementation.
35
+ */
36
+ static inline uint32_t fnv_hash(uint32_t const x, uint32_t const y)
37
+ {
38
+ return x * FNV_PRIME ^ y;
39
+ }
40
+
41
+ #ifdef __cplusplus
42
+ }
43
+ #endif
@@ -0,0 +1,179 @@
1
+ #pragma once
2
+ #include "compiler.h"
3
+ #include "endian.h"
4
+ #include "ethash.h"
5
+ #include <stdio.h>
6
+
7
+ #define ENABLE_SSE 0
8
+
9
+ #if defined(_M_X64) && ENABLE_SSE
10
+ #include <smmintrin.h>
11
+ #endif
12
+
13
+ #ifdef __cplusplus
14
+ extern "C" {
15
+ #endif
16
+
17
+ // compile time settings
18
+ #define NODE_WORDS (64/4)
19
+ #define MIX_WORDS (ETHASH_MIX_BYTES/4)
20
+ #define MIX_NODES (MIX_WORDS / NODE_WORDS)
21
+ #include <stdint.h>
22
+
23
+ typedef union node {
24
+ uint8_t bytes[NODE_WORDS * 4];
25
+ uint32_t words[NODE_WORDS];
26
+ uint64_t double_words[NODE_WORDS / 2];
27
+
28
+ #if defined(_M_X64) && ENABLE_SSE
29
+ __m128i xmm[NODE_WORDS/4];
30
+ #endif
31
+
32
+ } node;
33
+
34
+ static inline uint8_t ethash_h256_get(ethash_h256_t const* hash, unsigned int i)
35
+ {
36
+ return hash->b[i];
37
+ }
38
+
39
+ static inline void ethash_h256_set(ethash_h256_t* hash, unsigned int i, uint8_t v)
40
+ {
41
+ hash->b[i] = v;
42
+ }
43
+
44
+ static inline void ethash_h256_reset(ethash_h256_t* hash)
45
+ {
46
+ memset(hash, 0, 32);
47
+ }
48
+
49
+ // Returns if hash is less than or equal to boundary (2^256/difficulty)
50
+ static inline bool ethash_check_difficulty(
51
+ ethash_h256_t const* hash,
52
+ ethash_h256_t const* boundary
53
+ )
54
+ {
55
+ // Boundary is big endian
56
+ for (int i = 0; i < 32; i++) {
57
+ if (ethash_h256_get(hash, i) == ethash_h256_get(boundary, i)) {
58
+ continue;
59
+ }
60
+ return ethash_h256_get(hash, i) < ethash_h256_get(boundary, i);
61
+ }
62
+ return true;
63
+ }
64
+
65
+ /**
66
+ * Difficulty quick check for POW preverification
67
+ *
68
+ * @param header_hash The hash of the header
69
+ * @param nonce The block's nonce
70
+ * @param mix_hash The mix digest hash
71
+ * @param boundary The boundary is defined as (2^256 / difficulty)
72
+ * @return true for succesful pre-verification and false otherwise
73
+ */
74
+ bool ethash_quick_check_difficulty(
75
+ ethash_h256_t const* header_hash,
76
+ uint64_t const nonce,
77
+ ethash_h256_t const* mix_hash,
78
+ ethash_h256_t const* boundary
79
+ );
80
+
81
+ struct ethash_light {
82
+ void* cache;
83
+ uint64_t cache_size;
84
+ uint64_t block_number;
85
+ };
86
+
87
+ /**
88
+ * Allocate and initialize a new ethash_light handler. Internal version
89
+ *
90
+ * @param cache_size The size of the cache in bytes
91
+ * @param seed Block seedhash to be used during the computation of the
92
+ * cache nodes
93
+ * @return Newly allocated ethash_light handler or NULL in case of
94
+ * ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
95
+ */
96
+ ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed);
97
+
98
+ /**
99
+ * Calculate the light client data. Internal version.
100
+ *
101
+ * @param light The light client handler
102
+ * @param full_size The size of the full data in bytes.
103
+ * @param header_hash The header hash to pack into the mix
104
+ * @param nonce The nonce to pack into the mix
105
+ * @return The resulting hash.
106
+ */
107
+ ethash_return_value_t ethash_light_compute_internal(
108
+ ethash_light_t light,
109
+ uint64_t full_size,
110
+ ethash_h256_t const header_hash,
111
+ uint64_t nonce
112
+ );
113
+
114
+ struct ethash_full {
115
+ FILE* file;
116
+ uint64_t file_size;
117
+ node* data;
118
+ };
119
+
120
+ /**
121
+ * Allocate and initialize a new ethash_full handler. Internal version.
122
+ *
123
+ * @param dirname The directory in which to put the DAG file.
124
+ * @param seedhash The seed hash of the block. Used in the DAG file naming.
125
+ * @param full_size The size of the full data in bytes.
126
+ * @param cache A cache object to use that was allocated with @ref ethash_cache_new().
127
+ * Iff this function succeeds the ethash_full_t will take memory
128
+ * memory ownership of the cache and free it at deletion. If
129
+ * not then the user still has to handle freeing of the cache himself.
130
+ * @param callback A callback function with signature of @ref ethash_callback_t
131
+ * It accepts an unsigned with which a progress of DAG calculation
132
+ * can be displayed. If all goes well the callback should return 0.
133
+ * If a non-zero value is returned then DAG generation will stop.
134
+ * @return Newly allocated ethash_full handler or NULL in case of
135
+ * ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
136
+ */
137
+ ethash_full_t ethash_full_new_internal(
138
+ char const* dirname,
139
+ ethash_h256_t const seed_hash,
140
+ uint64_t full_size,
141
+ ethash_light_t const light,
142
+ ethash_callback_t callback
143
+ );
144
+
145
+ void ethash_calculate_dag_item(
146
+ node* const ret,
147
+ uint32_t node_index,
148
+ ethash_light_t const cache
149
+ );
150
+
151
+ void ethash_quick_hash(
152
+ ethash_h256_t* return_hash,
153
+ ethash_h256_t const* header_hash,
154
+ const uint64_t nonce,
155
+ ethash_h256_t const* mix_hash
156
+ );
157
+
158
+ uint64_t ethash_get_datasize(uint64_t const block_number);
159
+ uint64_t ethash_get_cachesize(uint64_t const block_number);
160
+
161
+ /**
162
+ * Compute the memory data for a full node's memory
163
+ *
164
+ * @param mem A pointer to an ethash full's memory
165
+ * @param full_size The size of the full data in bytes
166
+ * @param cache A cache object to use in the calculation
167
+ * @param callback The callback function. Check @ref ethash_full_new() for details.
168
+ * @return true if all went fine and false for invalid parameters
169
+ */
170
+ bool ethash_compute_full_data(
171
+ void* mem,
172
+ uint64_t full_size,
173
+ ethash_light_t const light,
174
+ ethash_callback_t callback
175
+ );
176
+
177
+ #ifdef __cplusplus
178
+ }
179
+ #endif