Merge pull request #87 from BitMaker-hub/dev

Dev
This commit is contained in:
BitMaker 2023-07-11 17:00:55 +02:00 committed by GitHub
commit 87a20f6813
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 2327 additions and 120 deletions

View File

@ -1,14 +0,0 @@
{
"folders": [
{
"path": "../../../../../../../Documents/Proyectos/Electrotec/DISPLAYS/SERIES/SERIE DP/SOFTWARE DE TESTEO/PythonScripts/GenerateXMLDPI"
},
{
"name": "NerdMinerV2",
"path": "."
}
],
"settings": {
"platformio-ide.useDevelopmentPIOCore": true
}
}

View File

@ -37,7 +37,15 @@ Every time an stratum job notification is received miner update its current work
- 3D BOX
### Flash firmware
Create your own miner using the online tool **ESPtool** and the **binary files** that you will find in the src/bin folder.
#### microMiners Flashtool
**Recommended flasher**
Easyiest way to flash firmware. Build your own miner using the folowing firwmare flash tool:
1. Get a TTGO T-display S3
1. Go to NM2 flasher online: https://bitmaker-hub.github.io/diyflasher/
#### Standard tool
Create your own miner using the online firwmare flash tool **ESPtool** and the **binary files** that you will find in the src/bin folder.
If you want you can compile the entire project using Arduino, PlatformIO or Expressif IDF.
1. Get a TTGO T-display S3

Binary file not shown.

View File

@ -10,6 +10,7 @@
[platformio]
globallib_dir = lib
default_envs = NerminerV2 ;, ESP32-devKitv1 TTGO-T-Display
[env:NerminerV2]
platform = espressif32
@ -41,3 +42,61 @@ lib_deps =
https://github.com/tzapu/WiFiManager.git
mathertel/OneButton @ ^2.0.3
arduino-libraries/NTPClient
https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4
[env:ESP32-devKitv1]
platform = espressif32
board = esp32dev
framework = arduino
monitor_filters =
esp32_exception_decoder
time
log2file
;board_build.arduino.memory_type = qio_opi
monitor_speed = 115200
upload_speed = 115200
# 2 x 4.5MB app, 6.875MB SPIFFS
;board_build.partitions = large_spiffs_16MB.csv
;board_build.partitions = default_8MB.csv
;board_build.partitions = huge_app.csv
board_build.partitions = default.csv
build_flags =
-D ARDUINO_USB_MODE=1
-U FREERTOS
;-D DEBUG_MINING=1
lib_deps =
https://github.com/takkaO/OpenFontRender
bblanchon/ArduinoJson@^6.21.2
https://github.com/tzapu/WiFiManager.git
mathertel/OneButton @ ^2.0.3
arduino-libraries/NTPClient
https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4
[env:TTGO-T-Display]
platform = espressif32
board = esp-wrover-kit
framework = arduino
monitor_filters =
esp32_exception_decoder
time
log2file
board_build.arduino.memory_type = qio_opi
monitor_speed = 115200
upload_speed = 115200
# 2 x 4.5MB app, 6.875MB SPIFFS
board_build.partitions = huge_app.csv
;build_flags =
; -D ARDUINO_USB_MODE=1
;-D DEBUG_MINING=1
lib_deps =
https://github.com/takkaO/OpenFontRender
bblanchon/ArduinoJson@^6.21.2
https://github.com/tzapu/WiFiManager.git
mathertel/OneButton @ ^2.0.3
arduino-libraries/NTPClient
https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4

View File

@ -10,11 +10,14 @@
#include "mbedtls/md.h"
#include "media/images.h"
#include "media/myFonts.h"
#include "media/Free_Fonts.h"
#include "OpenFontRender.h"
#include "wManager.h"
#include "mining.h"
#include "monitor.h"
#define CURRENT_VERSION "V1.5.2"
//3 seconds WDT
#define WDT_TIMEOUT 3
OneButton button1(PIN_BUTTON_1);
@ -98,7 +101,8 @@ void setup()
/******** PRINT INIT SCREEN *****/
tft.fillScreen(TFT_BLACK);
tft.pushImage(0, 0, initWidth, initHeight, initScreen);
tft.setTextColor(TFT_BLACK);
tft.drawString(CURRENT_VERSION, 24, 130, FONT2);
delay(2000);
/******** INIT WIFI ************/
@ -126,11 +130,15 @@ void setup()
// Start stratum tasks
sprintf(name, "(%s)", "Miner0");
//BaseType_t res = xTaskCreatePinnedToCore(runMiner, "0", 10000, (void*)name, 1, NULL, 0);
BaseType_t res3 = xTaskCreatePinnedToCore(runMiner, "0", 10000, (void*)name, 1,NULL, 0);
//BaseType_t res3 = xTaskCreatePinnedToCore(runMiner, "0", 10000, (void*)name, 1,NULL, 0);
//sprintf(name, "(%s)", "Miner1");
//BaseType_t res4 = xTaskCreatePinnedToCore(runMiner, "1", 10000, (void*)name, 1,NULL, 0);
//Serial.printf("Starting %s %s!\n", "1", res3 == pdPASS? "successful":"failed");
// Start mining tasks
//BaseType_t res = xTaskCreate(runWorker, name, 35000, (void*)name, 1, NULL);
xTaskCreate(runMiner, "Miner0", 15000, NULL, 1, NULL);
xTaskCreate(runMiner, "Miner1", 15000, NULL, 1, NULL);
/******** MONITOR SETUP *****/
setup_monitor();

View File

@ -0,0 +1,222 @@
#include "customSHA256.h"
#define TOTAL_LEN_LEN 8
/*
* Comments from pseudo-code at https://en.wikipedia.org/wiki/SHA-2 are reproduced here.
* When useful for clarification, portions of the pseudo-code are reproduced here too.
*/
/*
* @brief Rotate a 32-bit value by a number of bits to the right.
* @param value The value to be rotated.
* @param count The number of bits to rotate by.
* @return The rotated value.
*/
static inline uint32_t right_rot(uint32_t value, unsigned int count)
{
/*
* Defined behaviour in standard C for all count where 0 < count < 32, which is what we need here.
*/
return value >> count | value << (32 - count);
}
/*
* @brief Update a hash value under calculation with a new chunk of data.
* @param h Pointer to the first hash item, of a total of eight.
* @param p Pointer to the chunk data, which has a standard length.
*
* @note This is the SHA-256 work horse.
*/
static inline void consume_chunk(uint32_t *h, const uint8_t *p)
{
unsigned i, j;
uint32_t ah[8];
/* Initialize working variables to current hash value: */
for (i = 0; i < 8; i++)
ah[i] = h[i];
/*
* The w-array is really w[64], but since we only need 16 of them at a time, we save stack by
* calculating 16 at a time.
*
* This optimization was not there initially and the rest of the comments about w[64] are kept in their
* initial state.
*/
/*
* create a 64-entry message schedule array w[0..63] of 32-bit words (The initial values in w[0..63]
* don't matter, so many implementations zero them here) copy chunk into first 16 words w[0..15] of the
* message schedule array
*/
uint32_t w[16];
/* Compression function main loop: */
for (i = 0; i < 4; i++) {
for (j = 0; j < 16; j++) {
if (i == 0) {
w[j] =
(uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | (uint32_t)p[3];
p += 4;
} else {
/* Extend the first 16 words into the remaining 48 words w[16..63] of the
* message schedule array: */
const uint32_t s0 = right_rot(w[(j + 1) & 0xf], 7) ^ right_rot(w[(j + 1) & 0xf], 18) ^
(w[(j + 1) & 0xf] >> 3);
const uint32_t s1 = right_rot(w[(j + 14) & 0xf], 17) ^
right_rot(w[(j + 14) & 0xf], 19) ^ (w[(j + 14) & 0xf] >> 10);
w[j] = w[j] + s0 + w[(j + 9) & 0xf] + s1;
}
const uint32_t s1 = right_rot(ah[4], 6) ^ right_rot(ah[4], 11) ^ right_rot(ah[4], 25);
const uint32_t ch = (ah[4] & ah[5]) ^ (~ah[4] & ah[6]);
/*
* Initialize array of round constants:
* (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
*/
static const uint32_t k[] = {
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};
const uint32_t temp1 = ah[7] + s1 + ch + k[i << 4 | j] + w[j];
const uint32_t s0 = right_rot(ah[0], 2) ^ right_rot(ah[0], 13) ^ right_rot(ah[0], 22);
const uint32_t maj = (ah[0] & ah[1]) ^ (ah[0] & ah[2]) ^ (ah[1] & ah[2]);
const uint32_t temp2 = s0 + maj;
ah[7] = ah[6];
ah[6] = ah[5];
ah[5] = ah[4];
ah[4] = ah[3] + temp1;
ah[3] = ah[2];
ah[2] = ah[1];
ah[1] = ah[0];
ah[0] = temp1 + temp2;
}
}
/* Add the compressed chunk to the current hash value: */
for (i = 0; i < 8; i++)
h[i] += ah[i];
}
/*
* Public functions. See header file for documentation.
*/
void sha_256_init(struct Sha_256 *sha_256, uint8_t hash[SIZE_OF_SHA_256_HASH])
{
sha_256->hash = hash;
sha_256->chunk_pos = sha_256->chunk;
sha_256->space_left = SIZE_OF_SHA_256_CHUNK;
sha_256->total_len = 0;
/*
* Initialize hash values (first 32 bits of the fractional parts of the square roots of the first 8 primes
* 2..19):
*/
sha_256->h[0] = 0x6a09e667;
sha_256->h[1] = 0xbb67ae85;
sha_256->h[2] = 0x3c6ef372;
sha_256->h[3] = 0xa54ff53a;
sha_256->h[4] = 0x510e527f;
sha_256->h[5] = 0x9b05688c;
sha_256->h[6] = 0x1f83d9ab;
sha_256->h[7] = 0x5be0cd19;
}
void sha_256_write(struct Sha_256 *sha_256, const uint8_t *data, size_t len)
{
sha_256->total_len += len;
const uint8_t *p = data;
while (len > 0) {
/*
* If the input chunks have sizes that are multiples of the calculation chunk size, no copies are
* necessary. We operate directly on the input data instead.
*/
if (sha_256->space_left == SIZE_OF_SHA_256_CHUNK && len >= SIZE_OF_SHA_256_CHUNK) {
consume_chunk(sha_256->h, p);
len -= SIZE_OF_SHA_256_CHUNK;
p += SIZE_OF_SHA_256_CHUNK;
continue;
}
/* General case, no particular optimization. */
const size_t consumed_len = len < sha_256->space_left ? len : sha_256->space_left;
memcpy(sha_256->chunk_pos, p, consumed_len);
sha_256->space_left -= consumed_len;
len -= consumed_len;
p += consumed_len;
if (sha_256->space_left == 0) {
consume_chunk(sha_256->h, sha_256->chunk);
sha_256->chunk_pos = sha_256->chunk;
sha_256->space_left = SIZE_OF_SHA_256_CHUNK;
} else {
sha_256->chunk_pos += consumed_len;
}
}
}
uint8_t *sha_256_close(struct Sha_256 *sha_256)
{
uint8_t *pos = sha_256->chunk_pos;
size_t space_left = sha_256->space_left;
uint32_t *const h = sha_256->h;
/*
* The current chunk cannot be full. Otherwise, it would already have been consumed. I.e. there is space left for
* at least one byte. The next step in the calculation is to add a single one-bit to the data.
*/
*pos++ = 0x80;
--space_left;
/*
* Now, the last step is to add the total data length at the end of the last chunk, and zero padding before
* that. But we do not necessarily have enough space left. If not, we pad the current chunk with zeroes, and add
* an extra chunk at the end.
*/
if (space_left < TOTAL_LEN_LEN) {
memset(pos, 0x00, space_left);
consume_chunk(h, sha_256->chunk);
pos = sha_256->chunk;
space_left = SIZE_OF_SHA_256_CHUNK;
}
const size_t left = space_left - TOTAL_LEN_LEN;
memset(pos, 0x00, left);
pos += left;
size_t len = sha_256->total_len;
pos[7] = (uint8_t)(len << 3);
len >>= 5;
int i;
for (i = 6; i >= 0; --i) {
pos[i] = (uint8_t)len;
len >>= 8;
}
consume_chunk(h, sha_256->chunk);
/* Produce the final hash value (big-endian): */
int j;
uint8_t *const hash = sha_256->hash;
for (i = 0, j = 0; i < 8; i++) {
hash[j++] = (uint8_t)(h[i] >> 24);
hash[j++] = (uint8_t)(h[i] >> 16);
hash[j++] = (uint8_t)(h[i] >> 8);
hash[j++] = (uint8_t)h[i];
}
return sha_256->hash;
}
void calc_sha_256(uint8_t hash[SIZE_OF_SHA_256_HASH], const uint8_t *input, size_t len)
{
struct Sha_256 sha_256;
sha_256_init(&sha_256, hash);
sha_256_write(&sha_256, input, len);
(void)sha_256_close(&sha_256);
}

103
src/ShaTests/customSHA256.h Normal file
View File

@ -0,0 +1,103 @@
#ifndef SHA_256_H
#define SHA_256_H
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* @brief Size of the SHA-256 sum. This times eight is 256 bits.
*/
#define SIZE_OF_SHA_256_HASH 32
/*
* @brief Size of the chunks used for the calculations.
*
* @note This should mostly be ignored by the user, although when using the streaming API, it has an impact for
* performance. Add chunks whose size is a multiple of this, and you will avoid a lot of superfluous copying in RAM!
*/
#define SIZE_OF_SHA_256_CHUNK 64
/*
* @brief The opaque SHA-256 type, that should be instantiated when using the streaming API.
*
* @note Although the details are exposed here, in order to make instantiation easy, you should refrain from directly
* accessing the fields, as they may change in the future.
*/
struct Sha_256 {
uint8_t *hash;
uint8_t chunk[SIZE_OF_SHA_256_CHUNK];
uint8_t *chunk_pos;
size_t space_left;
size_t total_len;
uint32_t h[8];
};
/*
* @brief The simple SHA-256 calculation function.
* @param hash Hash array, where the result is delivered.
* @param input Pointer to the data the hash shall be calculated on.
* @param len Length of the input data, in byte.
*
* @note If all of the data you are calculating the hash value on is available in a contiguous buffer in memory, this is
* the function you should use.
*
* @note If either of the passed pointers is NULL, the results are unpredictable.
*/
void calc_sha_256(uint8_t hash[SIZE_OF_SHA_256_HASH], const uint8_t *input, size_t len);
/*
* @brief Initialize a SHA-256 streaming calculation.
* @param sha_256 A pointer to a SHA-256 structure.
* @param hash Hash array, where the result will be delivered.
*
* @note If all of the data you are calculating the hash value on is not available in a contiguous buffer in memory, this is
* where you should start. Instantiate a SHA-256 structure, for instance by simply declaring it locally, make your hash
* buffer available, and invoke this function. Once a SHA-256 hash has been calculated (see further below) a SHA-256
* structure can be initialized again for the next calculation.
*
* @note If either of the passed pointers is NULL, the results are unpredictable.
*/
void sha_256_init(struct Sha_256 *sha_256, uint8_t hash[SIZE_OF_SHA_256_HASH]);
/*
* @brief Stream more input data for an on-going SHA-256 calculation.
* @param sha_256 A pointer to a previously initialized SHA-256 structure.
* @param data Pointer to the data to be added to the calculation.
* @param len Length of the data to add, in byte.
*
* @note This function may be invoked an arbitrary number of times between initialization and closing, but the maximum
* data length is limited by the SHA-256 algorithm: the total number of bits (i.e. the total number of bytes times
* eight) must be representable by a 64-bit unsigned integer. While that is not a practical limitation, the results are
* unpredictable if that limit is exceeded.
*
* @note This function may be invoked on empty data (zero length), although that obviously will not add any data.
*
* @note If either of the passed pointers is NULL, the results are unpredictable.
*/
void sha_256_write(struct Sha_256 *sha_256, const uint8_t *data, size_t len);
/*
* @brief Conclude a SHA-256 streaming calculation, making the hash value available.
* @param sha_256 A pointer to a previously initialized SHA-256 structure.
* @return Pointer to the hash array, where the result is delivered.
*
* @note After this function has been invoked, the result is available in the hash buffer that initially was provided. A
* pointer to the hash value is returned for convenience, but you should feel free to ignore it: it is simply a pointer
* to the first byte of your initially provided hash array.
*
* @note If the passed pointer is NULL, the results are unpredictable.
*
* @note Invoking this function for a calculation with no data (the writing function has never been invoked, or it only
* has been invoked with empty data) is legal. It will calculate the SHA-256 value of the empty string.
*/
uint8_t *sha_256_close(struct Sha_256 *sha_256);
#ifdef __cplusplus
}
#endif
#endif

574
src/ShaTests/jadeSHA256.cpp Normal file
View File

@ -0,0 +1,574 @@
#define NDEBUG
#include <stdio.h>
#include <string.h>
#include <Arduino.h>
//#include <wally_address.h>
//#include <wally_transaction.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <esp_log.h>
#include <esp_timer.h>
#include "jadeSHA256.h"
#include <math.h>
#include <string.h>
#define HASH_SIZE 32
#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n, data, offset) \
{ \
u.num = n; \
p = (data) + (offset); \
*p = u.b[3]; \
*(p + 1) = u.b[2]; \
*(p + 2) = u.b[1]; \
*(p + 3) = u.b[0]; \
}
#endif
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(b, i) \
(((uint32_t)(b)[(i)] << 24) | ((uint32_t)(b)[(i) + 1] << 16) | ((uint32_t)(b)[(i) + 2] << 8) \
| ((uint32_t)(b)[(i) + 3]))
#endif
DRAM_ATTR static const uint32_t K[] = {
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,
};
#define SHR(x, n) ((x & 0xFFFFFFFF) >> n)
#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
#define F0(x, y, z) ((x & y) | (z & (x | y)))
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define R(t) (W[t] = S1(W[t - 2]) + W[t - 7] + S0(W[t - 15]) + W[t - 16])
#define P(a, b, c, d, e, f, g, h, x, K) \
{ \
temp1 = h + S3(e) + F1(e, f, g) + K + x; \
temp2 = S2(a) + F0(a, b, c); \
d += temp1; \
h = temp1 + temp2; \
}
#define CHECK_BYTES(u1, u2, offset) \
{ \
temp1 = u1 + u2; \
for (int i = 0; i < 4; ++i) { \
temp3 = (uint8_t)((temp1 >> (i * 8)) & 0xff); \
temp4 = *(target + offset + i); \
if (__builtin_expect(temp4 < temp3, true)) { \
return false; \
} \
if (__builtin_expect(temp4 > temp3, false)) { \
return true; \
} \
} \
}
#define MAINET_TESTNET_INTERVAL 210000
#define REGTEST_INTERVAL 150
const char* TAG = "MINER";
typedef struct {
uint32_t version;
uint8_t prev_block[32];
uint8_t merkle_root[32];
uint32_t timestamp;
uint32_t bits;
uint32_t nonce;
} block_header;
typedef struct headerandtarget {
block_header bh;
uint8_t target[32];
} headerandtarget;
typedef struct task_ctx {
headerandtarget ht;
uint32_t hashespersec;
uint32_t nonce_start;
uint32_t* nonce_solution;
uint8_t task_n;
bool* solution_found;
bool newwork;
} task_ctx;
typedef struct miner_ctx {
uint8_t rawtx[300];
block_header bh;
int64_t start;
TaskHandle_t xHandle1;
TaskHandle_t xHandle2;
solution_cb cb;
void* cbctx;
task_ctx ctx1;
task_ctx ctx2;
size_t txlen;
bool solution_found;
} miner_ctx;
IRAM_ATTR void calc_midstate(uint8_t* buf_ptr, _sha256_context* midstate)
{
uint32_t A[8] = { 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };
uint32_t temp1, temp2, W[64];
W[0] = GET_UINT32_BE(buf_ptr, 0);
W[1] = GET_UINT32_BE(buf_ptr, 4);
W[2] = GET_UINT32_BE(buf_ptr, 8);
W[3] = GET_UINT32_BE(buf_ptr, 12);
W[4] = GET_UINT32_BE(buf_ptr, 16);
W[5] = GET_UINT32_BE(buf_ptr, 20);
W[6] = GET_UINT32_BE(buf_ptr, 24);
W[7] = GET_UINT32_BE(buf_ptr, 28);
W[8] = GET_UINT32_BE(buf_ptr, 32);
W[9] = GET_UINT32_BE(buf_ptr, 36);
W[10] = GET_UINT32_BE(buf_ptr, 40);
W[11] = GET_UINT32_BE(buf_ptr, 44);
W[12] = GET_UINT32_BE(buf_ptr, 48);
W[13] = GET_UINT32_BE(buf_ptr, 52);
W[14] = GET_UINT32_BE(buf_ptr, 56);
W[15] = GET_UINT32_BE(buf_ptr, 60);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[0], K[0]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[1], K[1]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[2], K[2]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[3], K[3]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[4], K[4]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[5], K[5]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[6], K[6]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[7], K[7]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[8], K[8]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[9], K[9]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[10], K[10]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[11], K[11]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[12], K[12]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[13], K[13]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[14], K[14]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[15], K[15]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(16), K[16]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(17), K[17]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(18), K[18]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(19), K[19]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(20), K[20]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(21), K[21]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(22), K[22]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(23), K[23]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(24), K[24]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(25), K[25]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(26), K[26]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(27), K[27]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(28), K[28]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(29), K[29]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(30), K[30]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(31), K[31]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(32), K[32]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(33), K[33]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(34), K[34]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(35), K[35]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(36), K[36]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(37), K[37]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(38), K[38]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(39), K[39]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(40), K[40]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(41), K[41]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(42), K[42]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(43), K[43]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(44), K[44]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(45), K[45]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(46), K[46]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(47), K[47]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(48), K[48]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(49), K[49]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(50), K[50]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(51), K[51]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(52), K[52]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(53), K[53]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(54), K[54]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(55), K[55]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(56), K[56]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(57), K[57]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(58), K[58]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(59), K[59]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(60), K[60]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(61), K[61]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(62), K[62]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(63), K[63]);
midstate->state[0] = 0x6A09E667 + A[0];
midstate->state[1] = 0xBB67AE85 + A[1];
midstate->state[2] = 0x3C6EF372 + A[2];
midstate->state[3] = 0xA54FF53A + A[3];
midstate->state[4] = 0x510E527F + A[4];
midstate->state[5] = 0x9B05688C + A[5];
midstate->state[6] = 0x1F83D9AB + A[6];
midstate->state[7] = 0x5BE0CD19 + A[7];
midstate->buffer[16] = 0x80;
memcpy(midstate->buffer, buf_ptr + 64, 12);
}
IRAM_ATTR bool make_double_sha(_sha256_context* midstate)
{
uint32_t temp1, temp2;
uint8_t temp3, temp4;
uint32_t W[64] = { GET_UINT32_BE(midstate->buffer, 0), GET_UINT32_BE(midstate->buffer, 4),
GET_UINT32_BE(midstate->buffer, 8), GET_UINT32_BE(midstate->buffer, 12), 2147483648, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint32_t A[8] = { midstate->state[0], midstate->state[1], midstate->state[2], midstate->state[3],
midstate->state[4], midstate->state[5], midstate->state[6], midstate->state[7] };
union {
uint32_t num;
uint8_t b[4];
} u;
uint8_t* p = NULL;
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[0], K[0]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[1], K[1]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[2], K[2]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[3], K[3]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[4], K[4]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[5], K[5]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[6], K[6]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[7], K[7]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[8], K[8]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[9], K[9]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[10], K[10]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[11], K[11]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[12], K[12]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[13], K[13]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[14], K[14]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[15], K[15]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(16), K[16]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(17), K[17]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(18), K[18]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(19), K[19]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(20), K[20]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(21), K[21]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(22), K[22]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(23), K[23]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(24), K[24]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(25), K[25]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(26), K[26]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(27), K[27]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(28), K[28]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(29), K[29]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(30), K[30]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(31), K[31]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(32), K[32]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(33), K[33]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(34), K[34]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(35), K[35]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(36), K[36]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(37), K[37]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(38), K[38]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(39), K[39]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(40), K[40]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(41), K[41]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(42), K[42]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(43), K[43]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(44), K[44]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(45), K[45]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(46), K[46]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(47), K[47]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(48), K[48]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(49), K[49]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(50), K[50]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(51), K[51]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(52), K[52]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(53), K[53]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(54), K[54]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(55), K[55]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(56), K[56]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(57), K[57]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(58), K[58]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(59), K[59]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(60), K[60]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(61), K[61]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(62), K[62]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(63), K[63]);
PUT_UINT32_BE(midstate->state[0] + A[0], midstate->buffer, 0);
PUT_UINT32_BE(midstate->state[1] + A[1], midstate->buffer, 4);
PUT_UINT32_BE(midstate->state[2] + A[2], midstate->buffer, 8);
PUT_UINT32_BE(midstate->state[3] + A[3], midstate->buffer, 12);
PUT_UINT32_BE(midstate->state[4] + A[4], midstate->buffer, 16);
PUT_UINT32_BE(midstate->state[5] + A[5], midstate->buffer, 20);
PUT_UINT32_BE(midstate->state[6] + A[6], midstate->buffer, 24);
PUT_UINT32_BE(midstate->state[7] + A[7], midstate->buffer, 28);
/* Calculate the second hash (double SHA-256) */
A[0] = 0x6A09E667;
A[1] = 0xBB67AE85;
A[2] = 0x3C6EF372;
A[3] = 0xA54FF53A;
A[4] = 0x510E527F;
A[5] = 0x9B05688C;
A[6] = 0x1F83D9AB;
A[7] = 0x5BE0CD19;
midstate->buffer[32] = 0x80;
W[0] = GET_UINT32_BE(midstate->buffer, 0);
W[1] = GET_UINT32_BE(midstate->buffer, 4);
W[2] = GET_UINT32_BE(midstate->buffer, 8);
W[3] = GET_UINT32_BE(midstate->buffer, 12);
W[4] = GET_UINT32_BE(midstate->buffer, 16);
W[5] = GET_UINT32_BE(midstate->buffer, 20);
W[6] = GET_UINT32_BE(midstate->buffer, 24);
W[7] = GET_UINT32_BE(midstate->buffer, 28);
W[8] = GET_UINT32_BE(midstate->buffer, 32);
W[9] = GET_UINT32_BE(midstate->buffer, 36);
W[10] = GET_UINT32_BE(midstate->buffer, 40);
W[11] = GET_UINT32_BE(midstate->buffer, 44);
W[12] = GET_UINT32_BE(midstate->buffer, 48);
W[13] = GET_UINT32_BE(midstate->buffer, 52);
W[14] = 0;
W[15] = 256;
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[0], K[0]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[1], K[1]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[2], K[2]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[3], K[3]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[4], K[4]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[5], K[5]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[6], K[6]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[7], K[7]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[8], K[8]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[9], K[9]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[10], K[10]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[11], K[11]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[12], K[12]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[13], K[13]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[14], K[14]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[15], K[15]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(16), K[16]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(17), K[17]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(18), K[18]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(19), K[19]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(20), K[20]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(21), K[21]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(22), K[22]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(23), K[23]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(24), K[24]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(25), K[25]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(26), K[26]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(27), K[27]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(28), K[28]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(29), K[29]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(30), K[30]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(31), K[31]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(32), K[32]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(33), K[33]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(34), K[34]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(35), K[35]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(36), K[36]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(37), K[37]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(38), K[38]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(39), K[39]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(40), K[40]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(41), K[41]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(42), K[42]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(43), K[43]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(44), K[44]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(45), K[45]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(46), K[46]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(47), K[47]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(48), K[48]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(49), K[49]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(50), K[50]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(51), K[51]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(52), K[52]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(53), K[53]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(54), K[54]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(55), K[55]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(56), K[56]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(57), K[57]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(58), K[58]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(59), K[59]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(60), K[60]);
//CHECK_BYTES(0x5BE0CD19, A[7], 0);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(61), K[61]);
//CHECK_BYTES(0x1F83D9AB, A[6], 4);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(62), K[62]);
//CHECK_BYTES(0x9B05688C, A[5], 8);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(63), K[63]);
/*CHECK_BYTES(0x510E527F, A[4], 12);
CHECK_BYTES(0xA54FF53A, A[3], 16);
CHECK_BYTES(0x3C6EF372, A[2], 20);
CHECK_BYTES(0xBB67AE85, A[1], 24);
CHECK_BYTES(0x6A09E667, A[0], 28);*/
PUT_UINT32_BE(midstate->state[0] + A[0], midstate->buffer, 0);
PUT_UINT32_BE(midstate->state[1] + A[1], midstate->buffer, 4);
PUT_UINT32_BE(midstate->state[2] + A[2], midstate->buffer, 8);
PUT_UINT32_BE(midstate->state[3] + A[3], midstate->buffer, 12);
PUT_UINT32_BE(midstate->state[4] + A[4], midstate->buffer, 16);
PUT_UINT32_BE(midstate->state[5] + A[5], midstate->buffer, 20);
PUT_UINT32_BE(midstate->state[6] + A[6], midstate->buffer, 24);
PUT_UINT32_BE(midstate->state[7] + A[7], midstate->buffer, 28);
return true;
}
static void minertask(void* pctx)
{
assert(pctx);
task_ctx* tctx ;
headerandtarget header;
bool* newwork = &tctx->newwork;
while (1) {
if (*newwork) {
*newwork = false;
break;
}
vTaskDelay(1 / portTICK_PERIOD_MS);
}
header = tctx->ht;
uint32_t* hashespersec = &tctx->hashespersec;
while (true) {
_sha256_context midstate_cached = { 0 };
calc_midstate((uint8_t*)&header.bh, &midstate_cached);
*((uint32_t*)&midstate_cached.buffer[12]) = tctx->nonce_start;
_sha256_context ctx = midstate_cached;
while (true) {
//const bool within = verify_nonce(&ctx, header.target);
const bool within = false;
if (__builtin_expect(within, false)) {
*tctx->nonce_solution = *((uint32_t*)&midstate_cached.buffer[12]);
*tctx->solution_found = true;
/* wait until we have a new header to work on */
while (1) {
if (__builtin_expect(*newwork, false)) {
*newwork = false;
header = tctx->ht;
break;
}
vTaskDelay(1 / portTICK_PERIOD_MS);
}
break;
}
if (__builtin_expect(*newwork, false)) {
*newwork = false;
header = tctx->ht;
break;
}
*hashespersec = (*((uint32_t*)&midstate_cached.buffer[12]) += 1) - tctx->nonce_start;
ctx = midstate_cached;
}
}
}
bool check_solutions(void* ctx)
{
assert(ctx);
miner_ctx* mctx;
/* missing memory barrier but appers to work */
/* FIXME: find upper bound for solution len ?*/
if (!mctx->solution_found) {
return false;
}
uint8_t solution[600];
memcpy(solution, &mctx->bh, 80);
solution[80] = 0x01; /* number of transactions, solo mining :( */
memcpy(solution + 81, mctx->rawtx, mctx->txlen);
mctx->cb(mctx->cbctx, solution, 81 + mctx->txlen);
mctx->solution_found = false;
return true;
}
void check_speed(void* ctx, uint32_t* speed)
{
/* missing memory barrier but appers to work */
assert(ctx);
miner_ctx* mctx;
*speed = ((mctx->ctx1.hashespersec + mctx->ctx2.hashespersec) / ((esp_timer_get_time() - mctx->start) / 1000000.0));
}

22
src/ShaTests/jadeSHA256.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef jadeSHA256_H_
#define jadeSHA256_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
typedef struct _sha256_context {
uint8_t buffer[64];
uint32_t state[8];
} _sha256_context;
/* Calculate midstate */
IRAM_ATTR void calc_midstate(uint8_t* buf_ptr, _sha256_context* midstate);
IRAM_ATTR bool make_double_sha(_sha256_context* midstate);
/* We need a way to tell the miner to us that there is a solution */
typedef void (*solution_cb)(void* ctx, const uint8_t*, uint32_t);
#endif /* jadeSHA256_H_ */

View File

@ -5579,8 +5579,8 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD622, 0xD622, 0xD622, // 0x8770 (34672)
0xD622, 0xD622, 0xD622, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xCE03, 0xC5C3, 0xBD83, // 0x8780 (34688)
0xB542, 0xA4E2, 0x9C82, 0x8C22, 0x83E2, 0xA4EB, 0xCE38, 0x2945, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8790 (34704)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x87A0 (34720)
0x0000, 0x10A2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x2945, 0x0861, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x87B0 (34736)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x10A2, 0x0000, 0x0000, // 0x87A0 (34720)
0x0000, 0x0000, 0x0000, 0x0020, 0x2945, 0x0861, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x87B0 (34736)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x87C0 (34752)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x87D0 (34768)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x87E0 (34784)
@ -5599,8 +5599,8 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0xDE42, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD622, 0xD622, 0xD622, 0xD622, // 0x88B0 (34992)
0xD622, 0xD622, 0xD622, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xCE03, 0xC5E3, // 0x88C0 (35008)
0xBD83, 0xB542, 0xA4E2, 0x9C82, 0x8C22, 0x8C02, 0x9CA9, 0xCE17, 0x2945, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x88D0 (35024)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x88E0 (35040)
0x4208, 0x734D, 0x3165, 0x0841, 0x2945, 0x2104, 0x10A2, 0x3165, 0x734D, 0x62EB, 0x0861, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x88F0 (35056)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4208, 0x734D, 0x3165, 0x0841, // 0x88E0 (35040)
0x2945, 0x2104, 0x10A2, 0x3165, 0x734D, 0x62EB, 0x0861, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x88F0 (35056)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8900 (35072)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8910 (35088)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8920 (35104)
@ -5619,11 +5619,11 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0xDE42, 0xDE42, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD622, 0xD622, // 0x89F0 (35312)
0xD622, 0xD622, 0xD622, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xCE03, // 0x8A00 (35328)
0xC5E3, 0xC5A3, 0xB542, 0xACE2, 0x9C82, 0x9442, 0x8C02, 0x9466, 0xCE17, 0x2945, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8A10 (35344)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x39A6, // 0x8A20 (35360)
0x734D, 0x734D, 0x4A49, 0x734D, 0x734D, 0x734D, 0x734D, 0x62EB, 0x734D, 0x734D, 0x62EB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8A30 (35376)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x39A6, 0x734D, 0x734D, 0x4A49, 0x734D, // 0x8A20 (35360)
0x734D, 0x734D, 0x734D, 0x62EB, 0x734D, 0x734D, 0x62EB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8A30 (35376)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8A40 (35392)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8A50 (35408)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18E3, 0x0861, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8A60 (35424)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18E3, 0x0861, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8A60 (35424)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8A70 (35440)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8A80 (35456)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8A90 (35472)
@ -5639,11 +5639,11 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD622, 0xD622, 0xD622, // 0x8B30 (35632)
0xD642, 0xD623, 0xD622, 0xD622, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, // 0x8B40 (35648)
0xCE03, 0xCDE3, 0xC5A3, 0xB563, 0xAD02, 0x9CA2, 0x9442, 0x8C02, 0x9466, 0xCE17, 0x2945, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8B50 (35664)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5ACB, // 0x8B60 (35680)
0x6B2C, 0x6B2C, 0x734D, 0x734D, 0x6B2C, 0x6B2C, 0x62EB, 0x734D, 0x734D, 0x734D, 0x62EB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8B70 (35696)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5ACB, 0x6B2C, 0x6B2C, 0x734D, 0x734D, // 0x8B60 (35680)
0x6B2C, 0x6B2C, 0x62EB, 0x734D, 0x734D, 0x734D, 0x62EB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8B70 (35696)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8B80 (35712)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8B90 (35728)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18C3, 0xDEDB, 0xA514, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8BA0 (35744)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18E3, 0xDEDB, 0x8C51, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8BA0 (35744)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8BB0 (35760)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8BC0 (35776)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8BD0 (35792)
@ -5659,11 +5659,11 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD622, 0xD622, 0xD642, // 0x8C70 (35952)
0xD642, 0xD622, 0xD622, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, // 0x8C80 (35968)
0xD623, 0xCE03, 0xCDE3, 0xC5A3, 0xB563, 0xAD02, 0x9CA2, 0x9442, 0x8C02, 0x9466, 0xCE17, 0x2945, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8C90 (35984)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0861, // 0x8CA0 (36000)
0x3165, 0x734D, 0x62EB, 0x0861, 0x5ACB, 0x734D, 0x0861, 0x5AAA, 0x734D, 0x528A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8CB0 (36016)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0861, 0x3165, 0x734D, 0x62EB, 0x0861, // 0x8CA0 (36000)
0x5ACB, 0x734D, 0x0861, 0x5AAA, 0x734D, 0x528A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8CB0 (36016)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8CC0 (36032)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8CD0 (36048)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18E3, 0xDEDB, 0xA514, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8CE0 (36064)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18C3, 0xDEDB, 0x8C51, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8CE0 (36064)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8CF0 (36080)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8D00 (36096)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8D10 (36112)
@ -5679,17 +5679,17 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0xDE42, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD622, 0xD622, 0xD622, // 0x8DB0 (36272)
0xD622, 0xD643, 0xD622, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, // 0x8DC0 (36288)
0xD623, 0xD623, 0xCE03, 0xCDE3, 0xC5C3, 0xBD63, 0xAD02, 0x9CA2, 0x9442, 0x8C02, 0x9466, 0xCE17, 0x2945, 0x0000, 0x0000, 0x0000, // 0x8DD0 (36304)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8DE0 (36320)
0x528A, 0x734D, 0x2945, 0x0000, 0x62EB, 0x734D, 0x0861, 0x0841, 0x734D, 0x6B2C, 0x0841, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8DF0 (36336)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x528A, 0x734D, 0x2945, 0x0000, // 0x8DE0 (36320)
0x62EB, 0x734D, 0x0861, 0x0020, 0x734D, 0x6B2C, 0x0840, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8DF0 (36336)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8E00 (36352)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8E10 (36368)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18E3, 0xDEDB, 0xA514, 0x528A, 0x8C51, 0x7BCF, 0x18E3, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8E20 (36384)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18E3, 0x8C51, 0x8C51, 0x31A6, 0xDEDB, 0x8C50, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8E20 (36384)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8E30 (36400)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8E40 (36416)
0x0000, 0x0861, 0x6B6D, 0x2945, 0x6B6D, 0x8C51, 0x7BCF, 0x0861, 0x528A, 0x8C51, 0x7BCF, 0x18E3, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8E50 (36432)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8E50 (36432)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8E60 (36448)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8E70 (36464)
0x528A, 0x8C51, 0x8C51, 0x6B6D, 0x18E3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8E80 (36480)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8E80 (36480)
0xEEA0, 0xEEA0, 0xEEA0, 0xEE80, 0xEE80, 0xEEA0, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, // 0x8E90 (36496)
0xEE80, 0xEE80, 0xE680, 0xEE80, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, // 0x8EA0 (36512)
0xE680, 0xE680, 0xE681, 0xE680, 0xE680, 0xE681, 0xE681, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, // 0x8EB0 (36528)
@ -5699,17 +5699,17 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0xDE42, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD622, 0xD642, 0xD642, 0xD642, // 0x8EF0 (36592)
0xD622, 0xD622, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, // 0x8F00 (36608)
0xD623, 0xD623, 0xD623, 0xCE03, 0xCDE3, 0xC5A3, 0xBD63, 0xAD03, 0x9CA2, 0x9442, 0x8C02, 0x9466, 0xCE17, 0x2945, 0x0000, 0x0000, // 0x8F10 (36624)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8F20 (36640)
0x62EB, 0x734D, 0x10A2, 0x0000, 0x62EB, 0x734D, 0x39A6, 0x0000, 0x62EB, 0x734D, 0x0861, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8F30 (36656)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x62EB, 0x734D, 0x10A2, 0x0000, // 0x8F20 (36640)
0x62EB, 0x734D, 0x39A6, 0x0000, 0x62EB, 0x734D, 0x0861, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8F30 (36656)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8F40 (36672)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8F50 (36688)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18E3, 0xDEDB, 0xCE59, 0xCE59, 0xBDF7, 0xDEDB, 0xA514, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8F60 (36704)
0x0000, 0x0000, 0x0000, 0x0000, 0x0861, 0xBDF7, 0xDEDB, 0xB596, 0xBDF7, 0xDEDB, 0x8C51, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8F60 (36704)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8F70 (36720)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8F80 (36736)
0x0000, 0x18E3, 0xDEDB, 0xCE59, 0xCE59, 0xBDF7, 0xDEDB, 0xCE59, 0xCE59, 0xBDF7, 0xDEDB, 0xA514, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8F90 (36752)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8F90 (36752)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8FA0 (36768)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4228, // 0x8FB0 (36784)
0xDEDB, 0xB596, 0x94B2, 0xBDF7, 0x18E3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8FC0 (36800)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8FB0 (36784)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x8FC0 (36800)
0xEEA0, 0xEEA0, 0xEEA0, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, // 0x8FD0 (36816)
0xEE80, 0xEE80, 0xEE80, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, // 0x8FE0 (36832)
0xE680, 0xE680, 0xE680, 0xE680, 0xE681, 0xE681, 0xE681, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE681, 0xE661, 0xE661, 0xE661, // 0x8FF0 (36848)
@ -5719,17 +5719,17 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0xDE42, 0xDE42, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD622, // 0x9030 (36912)
0xD622, 0xD643, 0xD622, 0xD622, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, // 0x9040 (36928)
0xD623, 0xD623, 0xD623, 0xD623, 0xCE03, 0xCDE3, 0xC5C3, 0xB563, 0xAD03, 0x9CA2, 0x9442, 0x8C02, 0x9466, 0xCE17, 0x2945, 0x0000, // 0x9050 (36944)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9060 (36960)
0x528A, 0x734D, 0x18C3, 0x0000, 0x3165, 0x734D, 0x734D, 0x0861, 0x6B2C, 0x734D, 0x0841, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9070 (36976)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x528A, 0x734D, 0x18C3, 0x0000, // 0x9060 (36960)
0x3165, 0x734D, 0x734D, 0x0861, 0x6B2C, 0x734D, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9070 (36976)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9080 (36992)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9090 (37008)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18E3, 0xDEDB, 0xBDF7, 0x0861, 0x0000, 0xCE59, 0xDEDB, 0x0000, 0x0000, 0x0000, 0x0000, // 0x90A0 (37024)
0x0000, 0x0000, 0x0000, 0x0000, 0x4228, 0xDEDB, 0x8C51, 0x0000, 0x31A6, 0xDEDB, 0x8C51, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x90A0 (37024)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x90B0 (37040)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x90C0 (37056)
0x0000, 0x18E3, 0xDEDB, 0xBDF7, 0x1082, 0x0861, 0xDEDB, 0xCE59, 0x18C3, 0x0861, 0xCE59, 0xBDF7, 0x0000, 0x0000, 0x0000, 0x0000, // 0x90D0 (37072)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x90D0 (37072)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x90E0 (37088)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x630C, // 0x90F0 (37104)
0xDEDB, 0x7BCF, 0x18E3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9100 (37120)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x90F0 (37104)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9100 (37120)
0xEEA0, 0xEEA0, 0xEEA0, 0xEEA0, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, // 0x9110 (37136)
0xEE80, 0xEE80, 0xEE80, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, // 0x9120 (37152)
0xE680, 0xE680, 0xE681, 0xE681, 0xE680, 0xE681, 0xE681, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, // 0x9130 (37168)
@ -5739,17 +5739,17 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0xDE42, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD622, 0xD622, // 0x9170 (37232)
0xD622, 0xD622, 0xD643, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, // 0x9180 (37248)
0xD623, 0xD623, 0xD623, 0xD623, 0xCE23, 0xCE03, 0xCDE3, 0xC5A3, 0xB563, 0xAD02, 0x9CA2, 0x9442, 0x8402, 0x9466, 0xCE17, 0x2945, // 0x9190 (37264)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x91A0 (37280)
0x39A6, 0x734D, 0x5ACA, 0x0840, 0x0000, 0x2104, 0x39A6, 0x39A6, 0x734D, 0x528A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x91B0 (37296)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x39A6, 0x734D, 0x5ACA, 0x0841, // 0x91A0 (37280)
0x0000, 0x2104, 0x39A6, 0x39A6, 0x734D, 0x528A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x91B0 (37296)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x91C0 (37312)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x91D0 (37328)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18E3, 0xDEDB, 0xA514, 0x0000, 0x0000, 0xA514, 0xDEDB, 0x0000, 0x0000, 0x0000, 0x0000, // 0x91E0 (37344)
0x0000, 0x0000, 0x0000, 0x0000, 0x6B6D, 0xDEDB, 0x528A, 0x0000, 0x0000, 0xDEDB, 0x8430, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x91E0 (37344)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x91F0 (37360)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9200 (37376)
0x0000, 0x18E3, 0xDEDB, 0xA514, 0x0000, 0x0000, 0xDEDB, 0xA514, 0x0000, 0x0000, 0xBDF7, 0xBDF7, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9210 (37392)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9210 (37392)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9220 (37408)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0861, // 0x9230 (37424)
0xBDF7, 0xDEDB, 0xDEDB, 0x7BCF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9240 (37440)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9230 (37424)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9240 (37440)
0xEEA0, 0xEEA0, 0xEEA0, 0xEEA0, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, // 0x9250 (37456)
0xEE80, 0xEE80, 0xEE80, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, // 0x9260 (37472)
0xE680, 0xE680, 0xE681, 0xE681, 0xE681, 0xE681, 0xE681, 0xE681, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, // 0x9270 (37488)
@ -5759,17 +5759,17 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0xDE42, 0xDE42, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD622, // 0x92B0 (37552)
0xD622, 0xD622, 0xD643, 0xD622, 0xD623, 0xD622, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, // 0x92C0 (37568)
0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xCE03, 0xCDE3, 0xC5C3, 0xB563, 0xAD03, 0x9CA2, 0x9442, 0x8402, 0x9466, 0xCE17, // 0x92D0 (37584)
0x2945, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x92E0 (37600)
0x10A2, 0x734D, 0x734D, 0x62EB, 0x3165, 0x2945, 0x528A, 0x734D, 0x734D, 0x4208, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x92F0 (37616)
0x2945, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x10A2, 0x734D, 0x734D, 0x62EB, // 0x92E0 (37600)
0x3165, 0x2945, 0x528A, 0x734D, 0x734D, 0x4208, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x92F0 (37616)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9300 (37632)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9310 (37648)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18E3, 0xDEDB, 0xA514, 0x0000, 0x0000, 0xA514, 0xDEDB, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9320 (37664)
0x0000, 0x0000, 0x0000, 0x0000, 0x630B, 0xDEDB, 0x630C, 0x0000, 0x0861, 0xDEDB, 0x8430, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9320 (37664)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9330 (37680)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9340 (37696)
0x0000, 0x18E3, 0xDEDB, 0xA514, 0x0000, 0x0000, 0xDEDB, 0xA514, 0x0000, 0x0000, 0xBDF7, 0xBDF7, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9350 (37712)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9350 (37712)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9360 (37728)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9370 (37744)
0x0000, 0x4228, 0xBDF7, 0xDEDB, 0x630C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9380 (37760)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9380 (37760)
0xEEA0, 0xEEA0, 0xEEA0, 0xEEA0, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, // 0x9390 (37776)
0xEE80, 0xEE80, 0xEE80, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, // 0x93A0 (37792)
0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE681, 0xE681, 0xE661, 0xE681, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, // 0x93B0 (37808)
@ -5779,17 +5779,17 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0xDE42, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD622, 0xD622, // 0x93F0 (37872)
0xD622, 0xD642, 0xD622, 0xD622, 0xD622, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, // 0x9400 (37888)
0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xCE03, 0xCDE3, 0xC5A3, 0xB563, 0xAD03, 0x9CA2, 0x9442, 0x8402, 0x9466, // 0x9410 (37904)
0xCE17, 0x2945, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9420 (37920)
0x528A, 0x734D, 0x734D, 0x734D, 0x734D, 0x734D, 0x734D, 0x6B2C, 0x6B2C, 0x734D, 0x10A2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9430 (37936)
0xCE17, 0x2945, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x528A, 0x734D, 0x734D, 0x734D, // 0x9420 (37920)
0x734D, 0x734D, 0x734D, 0x6B2C, 0x6B2C, 0x734D, 0x10A2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9430 (37936)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9440 (37952)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9450 (37968)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18E3, 0xDEDB, 0xA514, 0x0000, 0x0000, 0xA514, 0xDEDB, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9460 (37984)
0x0000, 0x0000, 0x0000, 0x0000, 0x39C6, 0xDEDB, 0xBDF7, 0x528A, 0x7BCF, 0xDEDB, 0x8C51, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9460 (37984)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9470 (38000)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9480 (38016)
0x0000, 0x18E3, 0xDEDB, 0xA514, 0x0000, 0x0000, 0xDEDB, 0xA514, 0x0000, 0x0000, 0xBDF7, 0xBDF7, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9490 (38032)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9490 (38032)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x94A0 (38048)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x528A, // 0x94B0 (38064)
0x528A, 0x31A6, 0x6B6D, 0xDEDB, 0x5AEB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x94C0 (38080)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x94B0 (38064)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x94C0 (38080)
0xEEA0, 0xEEA0, 0xEEA0, 0xEEA0, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, // 0x94D0 (38096)
0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xE680, 0xEE80, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, // 0x94E0 (38112)
0xE680, 0xE680, 0xE680, 0xE680, 0xE681, 0xE681, 0xE681, 0xE681, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, 0xE661, // 0x94F0 (38128)
@ -5799,17 +5799,17 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0xDE42, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD642, 0xD622, 0xD642, 0xD622, // 0x9530 (38192)
0xD622, 0xD622, 0xD643, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, // 0x9540 (38208)
0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xD623, 0xCE23, 0xCE03, 0xCDE3, 0xC5A3, 0xB563, 0xAD02, 0x9CA2, 0x9442, 0x8402, // 0x9550 (38224)
0x9466, 0xCE17, 0x2945, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9560 (38240)
0x2104, 0x4A49, 0x0841, 0x2945, 0x41E7, 0x4208, 0x3165, 0x0841, 0x10A2, 0x3165, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9570 (38256)
0x9466, 0xCE17, 0x2945, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2104, 0x4A49, 0x0020, 0x2945, // 0x9560 (38240)
0x41E7, 0x4208, 0x3165, 0x0020, 0x10A2, 0x3165, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9570 (38256)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9580 (38272)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9590 (38288)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18E3, 0xDEDB, 0xA514, 0x0000, 0x0000, 0xA514, 0xDEDB, 0x0000, 0x0000, 0x0000, 0x0000, // 0x95A0 (38304)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6B6D, 0xDEDB, 0xDEDB, 0x6B6D, 0xCE59, 0x8C51, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x95A0 (38304)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x95B0 (38320)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x95C0 (38336)
0x0000, 0x18E3, 0xDEDB, 0xA514, 0x0000, 0x0000, 0xDEDB, 0xA514, 0x0000, 0x0000, 0xBDF7, 0xBDF7, 0x0000, 0x0000, 0x0000, 0x0000, // 0x95D0 (38352)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x95D0 (38352)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x95E0 (38368)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x528A, // 0x95F0 (38384)
0xDEDB, 0xDEDB, 0xDEDB, 0xA514, 0x18E3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9600 (38400)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x95F0 (38384)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9600 (38400)
0xEEA0, 0xEEA0, 0xEEA0, 0xEEA0, 0xEE80, 0xEEA0, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, // 0x9610 (38416)
0xEE80, 0xEE80, 0xEE80, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, // 0x9620 (38432)
0xE680, 0xE680, 0xE680, 0xE681, 0xE681, 0xE681, 0xE681, 0xE661, 0xE661, 0xE681, 0xE661, 0xE661, 0xE681, 0xE661, 0xE661, 0xE661, // 0x9630 (38448)
@ -5823,13 +5823,13 @@ const unsigned short MinerScreen[0xD480] PROGMEM ={
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x96B0 (38576)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x96C0 (38592)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x96D0 (38608)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x96E0 (38624)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0861, 0x0861, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x96E0 (38624)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x96F0 (38640)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9700 (38656)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9710 (38672)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9720 (38688)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9730 (38704)
0x0000, 0x18C3, 0x0861, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9740 (38720)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x9740 (38720)
0xEEA0, 0xEEA0, 0xEEA0, 0xEEA0, 0xEEA0, 0xEEA0, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, // 0x9750 (38736)
0xEE80, 0xEE80, 0xEE80, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, 0xE680, // 0x9760 (38752)
0xE680, 0xE680, 0xE680, 0xE680, 0xE681, 0xE681, 0xE681, 0xE661, 0xE681, 0xE661, 0xE661, 0xE661, 0xE681, 0xE661, 0xE661, 0xE661, // 0x9770 (38768)

View File

@ -1,12 +1,10 @@
#include <Arduino.h>
#include <ArduinoJson.h>
#include <WiFi.h>
#include <algorithm>
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
#include <wolfssl/wolfcrypt/sha256.h>
#include "media/Free_Fonts.h"
#include "media/images.h"
#include "mbedtls/md.h"
#include "mbedtls/sha256.h"
#include "OpenFontRender.h"
#include "stratum.h"
#include "mining.h"
@ -182,12 +180,13 @@ void runStratumWorker(void *name) {
case MINING_NOTIFY: if(parse_mining_notify(line, mJob)){
//Increse templates readed
templates++;
//Stop miner current job
//Stop miner current jobs
mMiner.inRun = false;
//Prepare data for new job
//Prepare data for new jobs
mMiner=calculateMiningData(mWorker,mJob);
mMiner.poolDifficulty = currentPoolDifficulty;
mMiner.newJob = true;
mMiner.newJob2 = true;
//Give new job to miner
}
@ -211,31 +210,54 @@ void runStratumWorker(void *name) {
//This works only with one thread, TODO -> Class or miner_data for each thread
#include "shaTests/jadeSHA256.h"
#include "shaTests/customSHA256.h"
#include "mbedtls/sha256.h"
void runMiner(void * name){
unsigned long nonce;
unsigned long max_nonce;
while(1){
//Wait new job
while(1){
if(mMiner.newJob==true) break;
if(mMiner.newJob==true || mMiner.newJob2==true) break;
vTaskDelay(100 / portTICK_PERIOD_MS); //Small delay
}
vTaskDelay(10 / portTICK_PERIOD_MS); //Small delay to join both mining threads
mMiner.newJob = false; //Clear newJob flag
if(mMiner.newJob) {
mMiner.newJob = false; //Clear newJob flag
nonce = 0;
max_nonce = MAX_NONCE;
}
else if(mMiner.newJob2){
mMiner.newJob2 = false; //Clear newJob flag
nonce = TARGET_NONCE - MAX_NONCE;
max_nonce = TARGET_NONCE;
}
mMiner.inRun = true; //Set inRun flag
//Prepare Premining data
mbedtls_sha256_context midstate[32];
Sha256 midstate[32];
unsigned char hash[32];
mbedtls_sha256_context ctx;
Sha256 sha256;
//Calcular midstate
mbedtls_sha256_init(midstate);
mbedtls_sha256_starts_ret(midstate, 0);
mbedtls_sha256_update_ret(midstate, mMiner.bytearray_blockheader, 64);
//Calcular midstate WOLF
wc_InitSha256(midstate);
wc_Sha256Update(midstate, mMiner.bytearray_blockheader, 64);
/*Serial.println("Blockheader:");
for (size_t i = 0; i < 80; i++)
Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
Serial.println("Midstate:");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", midstate[i]);
Serial.println("");
*/
// search a valid nonce
unsigned long nonce = TARGET_NONCE - MAX_NONCE;
uint32_t startT = micros();
unsigned char *header64 = mMiner.bytearray_blockheader + 64;
Serial.println(">>> STARTING TO HASH NONCES");
@ -244,20 +266,24 @@ void runMiner(void * name){
//Con midstate
// Primer SHA-256
mbedtls_sha256_clone(&ctx, midstate); //Clonamos el contexto anterior para continuar el SHA desde allí
mbedtls_sha256_update_ret(&ctx, header64, 16);
mbedtls_sha256_finish_ret(&ctx, hash);
wc_Sha256Copy(midstate, &sha256);
wc_Sha256Update(&sha256, header64, 16);
wc_Sha256Final(&sha256, hash);
// Segundo SHA-256
mbedtls_sha256_starts_ret(&ctx, 0);
mbedtls_sha256_update_ret(&ctx, hash, 32);
mbedtls_sha256_finish_ret(&ctx, hash);
wc_Sha256Update(&sha256, hash, 32);
wc_Sha256Final(&sha256, hash);
/*for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", hash[i]);
Serial.println(""); */
Serial.println("");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", midstate_jade.buffer[i]);
Serial.println(""); */
hashes++;
if (nonce++> TARGET_NONCE) break; //exit
if (nonce++> max_nonce) break; //exit
if(!mMiner.inRun) { Serial.println ("MINER WORK ABORTED >> waiting new job"); break;}
// check if 16bit share
@ -300,8 +326,8 @@ void runMiner(void * name){
}
} // exit if found a valid result or nonce > MAX_NONCE
mbedtls_sha256_free(&ctx);
mbedtls_sha256_free(midstate);
wc_Sha256Free(&sha256);
wc_Sha256Free(midstate);
mMiner.inRun = false;
Serial.print(">>> Finished job waiting new data from pool");

View File

@ -12,6 +12,7 @@
#include "utils.h"
#include "monitor.h"
extern char poolString[80];
extern unsigned long templates;
extern unsigned long hashes;
extern unsigned long Mhashes;
@ -79,7 +80,9 @@ void updateGlobalData(void){
}
http.end();
//Make second API call to get remaining Blocks
//OLD code gets remaining blocks to next difficulty ajustment
/*//Make second API call to get remaining Blocks
http.begin(getDifficulty);
httpCode = http.GET();
@ -97,7 +100,7 @@ void updateGlobalData(void){
mGlobalUpdate = millis();
}
http.end();
http.end();*/
//Make third API call to get fees
http.begin(getFees);
@ -247,18 +250,17 @@ void show_MinerScreen(unsigned long mElapsed){
render.setFontSize(36);
render.drawString(String(shares).c_str(), 186, 76, 0xDEDB);
//Hores
unsigned long secElapsed=millis()/1000;
int hr = secElapsed/3600; //Number of seconds in an hour
int mins = (secElapsed-(hr*3600))/60; //Remove the number of hours and calculate the minutes.
int sec = secElapsed-(hr*3600)-(mins*60);
render.setFontSize(36);
render.rdrawString(String(hr).c_str(), 208, 99, 0xDEDB);
//Minutss
render.setFontSize(36);
render.rdrawString(String(mins).c_str(), 253, 99, 0xDEDB);
//Segons
render.setFontSize(36);
render.rdrawString(String(sec).c_str(), 298, 99, 0xDEDB);
char timeMining[15];
unsigned long secElapsed = millis() / 1000;
int days = secElapsed / 86400;
int hours = (secElapsed - (days * 86400)) / 3600; //Number of seconds in an hour
int mins = (secElapsed - (days * 86400) - (hours * 3600)) / 60; //Remove the number of hours and calculate the minutes.
int secs = secElapsed - (days * 86400) - (hours * 3600) - (mins * 60);
sprintf(timeMining, "%01d %02d:%02d:%02d", days, hours, mins, secs);
render.setFontSize(27);
render.rdrawString(String(timeMining).c_str(), 315, 104, 0xDEDB);
//Valid Blocks
render.setFontSize(48);
render.drawString(String(valids).c_str(), 285, 56, 0xDEDB);
@ -275,6 +277,12 @@ void show_MinerScreen(unsigned long mElapsed){
render.setFontSize(20);
render.rdrawString(getTime().c_str(), 286, 1, TFT_BLACK);
// pool url
/*background.setTextSize(1);
background.setTextDatum(MC_DATUM);
background.setTextColor(0xDEDB);
background.drawString(String(poolString), 59, 85, FONT2);*/
//Push prepared background to screen
background.pushSprite(0,0);
}
@ -377,10 +385,14 @@ void show_GlobalHashScreen(unsigned long mElapsed){
//Print BlockHeight
render.setFontSize(55);
render.rdrawString(getBlockHeight().c_str(), 140, 104, 0xDEDB);
gData.currentBlock = getBlockHeight();
render.rdrawString(gData.currentBlock.c_str(), 140, 104, 0xDEDB);
//Draw percentage rectangle
//width percent bar 140 - 2
unsigned long cBlock = gData.currentBlock.toInt();
gData.remainingBlocks = (((cBlock / HALVING_BLOCKS)+1) * HALVING_BLOCKS) - cBlock;
gData.progressPercent = (HALVING_BLOCKS-gData.remainingBlocks)*100/HALVING_BLOCKS;
int x2 = 2 + (138*gData.progressPercent/100);
background.fillRect(2, 149, x2, 168, 0xDEDB);

View File

@ -25,6 +25,8 @@
#define getFees "https://mempool.space/api/v1/fees/recommended"
#define UPDATE_Global_min 2
#define NEXT_HALVING_EVENT 840000
#define HALVING_BLOCKS 210000
typedef struct{
uint8_t screen;
@ -33,7 +35,7 @@ typedef struct{
typedef struct{
String globalHash; //hexahashes
String lastBlock;
String currentBlock;
String difficulty;
String blocksHalving;
float progressPercent;

View File

@ -204,11 +204,10 @@ bool tx_mining_submit(WiFiClient& client, mining_subscribe mWorker, mining_job m
sprintf(payload, "{\"id\": %u, \"method\": \"mining.submit\", \"params\": [\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"]}\n",
id,
mWorker.wName,//"bc1qvv469gmw4zz6qa4u4dsezvrlmqcqszwyfzhgwj", //mWorker.name,
mJob.job_id,
mWorker.extranonce2,
mJob.ntime,
String(nonce, HEX),
id
mJob.job_id.c_str(),
mWorker.extranonce2.c_str(),
mJob.ntime.c_str(),
String(nonce, HEX).c_str()
);
Serial.print(" Sending : "); Serial.print(payload);
client.print(payload);

5
test/TestHashPerformance/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

View File

@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

View File

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

View File

@ -0,0 +1,36 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
globallib_dir = lib
default_envs = TestSHA
[env:TestSHA]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
monitor_filters =
esp32_exception_decoder
time
log2file
board_build.arduino.memory_type = qio_opi
monitor_speed = 115200
upload_speed = 115200
# 2 x 4.5MB app, 6.875MB SPIFFS
board_build.partitions = huge_app.csv
build_flags =
-D BOARD_HAS_PSRAM
-D ARDUINO_USB_MODE=1
-D ARDUINO_USB_CDC_ON_BOOT=1
;-D DEBUG_MINING=1
lib_deps =
https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4

View File

@ -0,0 +1,222 @@
#include "customSHA256.h"
#define TOTAL_LEN_LEN 8
/*
* Comments from pseudo-code at https://en.wikipedia.org/wiki/SHA-2 are reproduced here.
* When useful for clarification, portions of the pseudo-code are reproduced here too.
*/
/*
* @brief Rotate a 32-bit value by a number of bits to the right.
* @param value The value to be rotated.
* @param count The number of bits to rotate by.
* @return The rotated value.
*/
static inline uint32_t right_rot(uint32_t value, unsigned int count)
{
/*
* Defined behaviour in standard C for all count where 0 < count < 32, which is what we need here.
*/
return value >> count | value << (32 - count);
}
/*
* @brief Update a hash value under calculation with a new chunk of data.
* @param h Pointer to the first hash item, of a total of eight.
* @param p Pointer to the chunk data, which has a standard length.
*
* @note This is the SHA-256 work horse.
*/
static inline void consume_chunk(uint32_t *h, const uint8_t *p)
{
unsigned i, j;
uint32_t ah[8];
/* Initialize working variables to current hash value: */
for (i = 0; i < 8; i++)
ah[i] = h[i];
/*
* The w-array is really w[64], but since we only need 16 of them at a time, we save stack by
* calculating 16 at a time.
*
* This optimization was not there initially and the rest of the comments about w[64] are kept in their
* initial state.
*/
/*
* create a 64-entry message schedule array w[0..63] of 32-bit words (The initial values in w[0..63]
* don't matter, so many implementations zero them here) copy chunk into first 16 words w[0..15] of the
* message schedule array
*/
uint32_t w[16];
/* Compression function main loop: */
for (i = 0; i < 4; i++) {
for (j = 0; j < 16; j++) {
if (i == 0) {
w[j] =
(uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | (uint32_t)p[3];
p += 4;
} else {
/* Extend the first 16 words into the remaining 48 words w[16..63] of the
* message schedule array: */
const uint32_t s0 = right_rot(w[(j + 1) & 0xf], 7) ^ right_rot(w[(j + 1) & 0xf], 18) ^
(w[(j + 1) & 0xf] >> 3);
const uint32_t s1 = right_rot(w[(j + 14) & 0xf], 17) ^
right_rot(w[(j + 14) & 0xf], 19) ^ (w[(j + 14) & 0xf] >> 10);
w[j] = w[j] + s0 + w[(j + 9) & 0xf] + s1;
}
const uint32_t s1 = right_rot(ah[4], 6) ^ right_rot(ah[4], 11) ^ right_rot(ah[4], 25);
const uint32_t ch = (ah[4] & ah[5]) ^ (~ah[4] & ah[6]);
/*
* Initialize array of round constants:
* (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
*/
static const uint32_t k[] = {
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};
const uint32_t temp1 = ah[7] + s1 + ch + k[i << 4 | j] + w[j];
const uint32_t s0 = right_rot(ah[0], 2) ^ right_rot(ah[0], 13) ^ right_rot(ah[0], 22);
const uint32_t maj = (ah[0] & ah[1]) ^ (ah[0] & ah[2]) ^ (ah[1] & ah[2]);
const uint32_t temp2 = s0 + maj;
ah[7] = ah[6];
ah[6] = ah[5];
ah[5] = ah[4];
ah[4] = ah[3] + temp1;
ah[3] = ah[2];
ah[2] = ah[1];
ah[1] = ah[0];
ah[0] = temp1 + temp2;
}
}
/* Add the compressed chunk to the current hash value: */
for (i = 0; i < 8; i++)
h[i] += ah[i];
}
/*
* Public functions. See header file for documentation.
*/
void sha_256_init(struct Sha_256 *sha_256, uint8_t hash[SIZE_OF_SHA_256_HASH])
{
sha_256->hash = hash;
sha_256->chunk_pos = sha_256->chunk;
sha_256->space_left = SIZE_OF_SHA_256_CHUNK;
sha_256->total_len = 0;
/*
* Initialize hash values (first 32 bits of the fractional parts of the square roots of the first 8 primes
* 2..19):
*/
sha_256->h[0] = 0x6a09e667;
sha_256->h[1] = 0xbb67ae85;
sha_256->h[2] = 0x3c6ef372;
sha_256->h[3] = 0xa54ff53a;
sha_256->h[4] = 0x510e527f;
sha_256->h[5] = 0x9b05688c;
sha_256->h[6] = 0x1f83d9ab;
sha_256->h[7] = 0x5be0cd19;
}
void sha_256_write(struct Sha_256 *sha_256, const uint8_t *data, size_t len)
{
sha_256->total_len += len;
const uint8_t *p = data;
while (len > 0) {
/*
* If the input chunks have sizes that are multiples of the calculation chunk size, no copies are
* necessary. We operate directly on the input data instead.
*/
if (sha_256->space_left == SIZE_OF_SHA_256_CHUNK && len >= SIZE_OF_SHA_256_CHUNK) {
consume_chunk(sha_256->h, p);
len -= SIZE_OF_SHA_256_CHUNK;
p += SIZE_OF_SHA_256_CHUNK;
continue;
}
/* General case, no particular optimization. */
const size_t consumed_len = len < sha_256->space_left ? len : sha_256->space_left;
memcpy(sha_256->chunk_pos, p, consumed_len);
sha_256->space_left -= consumed_len;
len -= consumed_len;
p += consumed_len;
if (sha_256->space_left == 0) {
consume_chunk(sha_256->h, sha_256->chunk);
sha_256->chunk_pos = sha_256->chunk;
sha_256->space_left = SIZE_OF_SHA_256_CHUNK;
} else {
sha_256->chunk_pos += consumed_len;
}
}
}
uint8_t *sha_256_close(struct Sha_256 *sha_256)
{
uint8_t *pos = sha_256->chunk_pos;
size_t space_left = sha_256->space_left;
uint32_t *const h = sha_256->h;
/*
* The current chunk cannot be full. Otherwise, it would already have been consumed. I.e. there is space left for
* at least one byte. The next step in the calculation is to add a single one-bit to the data.
*/
*pos++ = 0x80;
--space_left;
/*
* Now, the last step is to add the total data length at the end of the last chunk, and zero padding before
* that. But we do not necessarily have enough space left. If not, we pad the current chunk with zeroes, and add
* an extra chunk at the end.
*/
if (space_left < TOTAL_LEN_LEN) {
memset(pos, 0x00, space_left);
consume_chunk(h, sha_256->chunk);
pos = sha_256->chunk;
space_left = SIZE_OF_SHA_256_CHUNK;
}
const size_t left = space_left - TOTAL_LEN_LEN;
memset(pos, 0x00, left);
pos += left;
size_t len = sha_256->total_len;
pos[7] = (uint8_t)(len << 3);
len >>= 5;
int i;
for (i = 6; i >= 0; --i) {
pos[i] = (uint8_t)len;
len >>= 8;
}
consume_chunk(h, sha_256->chunk);
/* Produce the final hash value (big-endian): */
int j;
uint8_t *const hash = sha_256->hash;
for (i = 0, j = 0; i < 8; i++) {
hash[j++] = (uint8_t)(h[i] >> 24);
hash[j++] = (uint8_t)(h[i] >> 16);
hash[j++] = (uint8_t)(h[i] >> 8);
hash[j++] = (uint8_t)h[i];
}
return sha_256->hash;
}
void calc_sha_256(uint8_t hash[SIZE_OF_SHA_256_HASH], const uint8_t *input, size_t len)
{
struct Sha_256 sha_256;
sha_256_init(&sha_256, hash);
sha_256_write(&sha_256, input, len);
(void)sha_256_close(&sha_256);
}

View File

@ -0,0 +1,103 @@
#ifndef SHA_256_H
#define SHA_256_H
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* @brief Size of the SHA-256 sum. This times eight is 256 bits.
*/
#define SIZE_OF_SHA_256_HASH 32
/*
* @brief Size of the chunks used for the calculations.
*
* @note This should mostly be ignored by the user, although when using the streaming API, it has an impact for
* performance. Add chunks whose size is a multiple of this, and you will avoid a lot of superfluous copying in RAM!
*/
#define SIZE_OF_SHA_256_CHUNK 64
/*
* @brief The opaque SHA-256 type, that should be instantiated when using the streaming API.
*
* @note Although the details are exposed here, in order to make instantiation easy, you should refrain from directly
* accessing the fields, as they may change in the future.
*/
struct Sha_256 {
uint8_t *hash;
uint8_t chunk[SIZE_OF_SHA_256_CHUNK];
uint8_t *chunk_pos;
size_t space_left;
size_t total_len;
uint32_t h[8];
};
/*
* @brief The simple SHA-256 calculation function.
* @param hash Hash array, where the result is delivered.
* @param input Pointer to the data the hash shall be calculated on.
* @param len Length of the input data, in byte.
*
* @note If all of the data you are calculating the hash value on is available in a contiguous buffer in memory, this is
* the function you should use.
*
* @note If either of the passed pointers is NULL, the results are unpredictable.
*/
void calc_sha_256(uint8_t hash[SIZE_OF_SHA_256_HASH], const uint8_t *input, size_t len);
/*
* @brief Initialize a SHA-256 streaming calculation.
* @param sha_256 A pointer to a SHA-256 structure.
* @param hash Hash array, where the result will be delivered.
*
* @note If all of the data you are calculating the hash value on is not available in a contiguous buffer in memory, this is
* where you should start. Instantiate a SHA-256 structure, for instance by simply declaring it locally, make your hash
* buffer available, and invoke this function. Once a SHA-256 hash has been calculated (see further below) a SHA-256
* structure can be initialized again for the next calculation.
*
* @note If either of the passed pointers is NULL, the results are unpredictable.
*/
void sha_256_init(struct Sha_256 *sha_256, uint8_t hash[SIZE_OF_SHA_256_HASH]);
/*
* @brief Stream more input data for an on-going SHA-256 calculation.
* @param sha_256 A pointer to a previously initialized SHA-256 structure.
* @param data Pointer to the data to be added to the calculation.
* @param len Length of the data to add, in byte.
*
* @note This function may be invoked an arbitrary number of times between initialization and closing, but the maximum
* data length is limited by the SHA-256 algorithm: the total number of bits (i.e. the total number of bytes times
* eight) must be representable by a 64-bit unsigned integer. While that is not a practical limitation, the results are
* unpredictable if that limit is exceeded.
*
* @note This function may be invoked on empty data (zero length), although that obviously will not add any data.
*
* @note If either of the passed pointers is NULL, the results are unpredictable.
*/
void sha_256_write(struct Sha_256 *sha_256, const uint8_t *data, size_t len);
/*
* @brief Conclude a SHA-256 streaming calculation, making the hash value available.
* @param sha_256 A pointer to a previously initialized SHA-256 structure.
* @return Pointer to the hash array, where the result is delivered.
*
* @note After this function has been invoked, the result is available in the hash buffer that initially was provided. A
* pointer to the hash value is returned for convenience, but you should feel free to ignore it: it is simply a pointer
* to the first byte of your initially provided hash array.
*
* @note If the passed pointer is NULL, the results are unpredictable.
*
* @note Invoking this function for a calculation with no data (the writing function has never been invoked, or it only
* has been invoked with empty data) is legal. It will calculate the SHA-256 value of the empty string.
*/
uint8_t *sha_256_close(struct Sha_256 *sha_256);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,573 @@
#define NDEBUG
#include <stdio.h>
#include <string.h>
#include <Arduino.h>
//#include <wally_address.h>
//#include <wally_transaction.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <esp_log.h>
#include <esp_timer.h>
#include "jadeSHA256.h"
#include <math.h>
#include <string.h>
#define HASH_SIZE 32
#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n, data, offset) \
{ \
u.num = n; \
p = (data) + (offset); \
*p = u.b[3]; \
*(p + 1) = u.b[2]; \
*(p + 2) = u.b[1]; \
*(p + 3) = u.b[0]; \
}
#endif
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(b, i) \
(((uint32_t)(b)[(i)] << 24) | ((uint32_t)(b)[(i) + 1] << 16) | ((uint32_t)(b)[(i) + 2] << 8) \
| ((uint32_t)(b)[(i) + 3]))
#endif
//DRAM_ATTR static const uint32_t K[] = {
static const uint32_t K[] = {
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,
};
#define SHR(x, n) ((x & 0xFFFFFFFF) >> n)
#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
#define F0(x, y, z) ((x & y) | (z & (x | y)))
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define R(t) (W[t] = S1(W[t - 2]) + W[t - 7] + S0(W[t - 15]) + W[t - 16])
#define P(a, b, c, d, e, f, g, h, x, K) \
{ \
temp1 = h + S3(e) + F1(e, f, g) + K + x; \
temp2 = S2(a) + F0(a, b, c); \
d += temp1; \
h = temp1 + temp2; \
}
#define CHECK_BYTES(u1, u2, offset) \
{ \
temp1 = u1 + u2; \
for (int i = 0; i < 4; ++i) { \
temp3 = (uint8_t)((temp1 >> (i * 8)) & 0xff); \
temp4 = *(target + offset + i); \
if (__builtin_expect(temp4 < temp3, true)) { \
return false; \
} \
if (__builtin_expect(temp4 > temp3, false)) { \
return true; \
} \
} \
}
#define MAINET_TESTNET_INTERVAL 210000
#define REGTEST_INTERVAL 150
const char* TAG = "MINER";
typedef struct {
uint32_t version;
uint8_t prev_block[32];
uint8_t merkle_root[32];
uint32_t timestamp;
uint32_t bits;
uint32_t nonce;
} block_header;
typedef struct headerandtarget {
block_header bh;
uint8_t target[32];
} headerandtarget;
typedef struct task_ctx {
headerandtarget ht;
uint32_t hashespersec;
uint32_t nonce_start;
uint32_t* nonce_solution;
uint8_t task_n;
bool* solution_found;
bool newwork;
} task_ctx;
typedef struct miner_ctx {
uint8_t rawtx[300];
block_header bh;
int64_t start;
TaskHandle_t xHandle1;
TaskHandle_t xHandle2;
solution_cb cb;
void* cbctx;
task_ctx ctx1;
task_ctx ctx2;
size_t txlen;
bool solution_found;
} miner_ctx;
IRAM_ATTR void calc_midstate(uint8_t* buf_ptr, _sha256_context* midstate)
{
uint32_t A[8] = { 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };
uint32_t temp1, temp2, W[64];
W[0] = GET_UINT32_BE(buf_ptr, 0);
W[1] = GET_UINT32_BE(buf_ptr, 4);
W[2] = GET_UINT32_BE(buf_ptr, 8);
W[3] = GET_UINT32_BE(buf_ptr, 12);
W[4] = GET_UINT32_BE(buf_ptr, 16);
W[5] = GET_UINT32_BE(buf_ptr, 20);
W[6] = GET_UINT32_BE(buf_ptr, 24);
W[7] = GET_UINT32_BE(buf_ptr, 28);
W[8] = GET_UINT32_BE(buf_ptr, 32);
W[9] = GET_UINT32_BE(buf_ptr, 36);
W[10] = GET_UINT32_BE(buf_ptr, 40);
W[11] = GET_UINT32_BE(buf_ptr, 44);
W[12] = GET_UINT32_BE(buf_ptr, 48);
W[13] = GET_UINT32_BE(buf_ptr, 52);
W[14] = GET_UINT32_BE(buf_ptr, 56);
W[15] = GET_UINT32_BE(buf_ptr, 60);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[0], K[0]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[1], K[1]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[2], K[2]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[3], K[3]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[4], K[4]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[5], K[5]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[6], K[6]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[7], K[7]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[8], K[8]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[9], K[9]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[10], K[10]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[11], K[11]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[12], K[12]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[13], K[13]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[14], K[14]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[15], K[15]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(16), K[16]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(17), K[17]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(18), K[18]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(19), K[19]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(20), K[20]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(21), K[21]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(22), K[22]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(23), K[23]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(24), K[24]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(25), K[25]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(26), K[26]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(27), K[27]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(28), K[28]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(29), K[29]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(30), K[30]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(31), K[31]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(32), K[32]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(33), K[33]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(34), K[34]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(35), K[35]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(36), K[36]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(37), K[37]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(38), K[38]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(39), K[39]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(40), K[40]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(41), K[41]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(42), K[42]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(43), K[43]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(44), K[44]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(45), K[45]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(46), K[46]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(47), K[47]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(48), K[48]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(49), K[49]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(50), K[50]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(51), K[51]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(52), K[52]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(53), K[53]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(54), K[54]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(55), K[55]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(56), K[56]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(57), K[57]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(58), K[58]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(59), K[59]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(60), K[60]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(61), K[61]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(62), K[62]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(63), K[63]);
midstate->state[0] = A[0];// 0x6A09E667 + A[0];
midstate->state[1] = A[1];// 0xBB67AE85 + A[1];
midstate->state[2] = A[2];// 0x3C6EF372 + A[2];
midstate->state[3] = A[3];// 0xA54FF53A + A[3];
midstate->state[4] = A[4];// 0x510E527F + A[4];
midstate->state[5] = A[5];// 0x9B05688C + A[5];
midstate->state[6] = A[6];// 0x1F83D9AB + A[6];
midstate->state[7] = A[7];// 0x5BE0CD19 + A[7];
midstate->buffer[16] = 0x80;
memcpy(midstate->buffer, buf_ptr + 64, 12);
}
IRAM_ATTR bool make_double_sha(_sha256_context* midstate)
{
uint32_t temp1, temp2;
uint8_t temp3, temp4;
uint32_t W[64] = { GET_UINT32_BE(midstate->buffer, 0), GET_UINT32_BE(midstate->buffer, 4),
GET_UINT32_BE(midstate->buffer, 8), GET_UINT32_BE(midstate->buffer, 12), 2147483648, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint32_t A[8] = { midstate->state[0], midstate->state[1], midstate->state[2], midstate->state[3],
midstate->state[4], midstate->state[5], midstate->state[6], midstate->state[7] };
//2147483648
union {
uint32_t num;
uint8_t b[4];
} u;
uint8_t* p = NULL;
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[0], K[0]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[1], K[1]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[2], K[2]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[3], K[3]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[4], K[4]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[5], K[5]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[6], K[6]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[7], K[7]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[8], K[8]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[9], K[9]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[10], K[10]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[11], K[11]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[12], K[12]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[13], K[13]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[14], K[14]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[15], K[15]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(16), K[16]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(17), K[17]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(18), K[18]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(19), K[19]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(20), K[20]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(21), K[21]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(22), K[22]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(23), K[23]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(24), K[24]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(25), K[25]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(26), K[26]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(27), K[27]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(28), K[28]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(29), K[29]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(30), K[30]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(31), K[31]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(32), K[32]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(33), K[33]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(34), K[34]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(35), K[35]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(36), K[36]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(37), K[37]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(38), K[38]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(39), K[39]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(40), K[40]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(41), K[41]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(42), K[42]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(43), K[43]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(44), K[44]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(45), K[45]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(46), K[46]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(47), K[47]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(48), K[48]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(49), K[49]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(50), K[50]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(51), K[51]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(52), K[52]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(53), K[53]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(54), K[54]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(55), K[55]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(56), K[56]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(57), K[57]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(58), K[58]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(59), K[59]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(60), K[60]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(61), K[61]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(62), K[62]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(63), K[63]);
PUT_UINT32_BE(midstate->state[0] + A[0], midstate->buffer, 0);
PUT_UINT32_BE(midstate->state[1] + A[1], midstate->buffer, 4);
PUT_UINT32_BE(midstate->state[2] + A[2], midstate->buffer, 8);
PUT_UINT32_BE(midstate->state[3] + A[3], midstate->buffer, 12);
PUT_UINT32_BE(midstate->state[4] + A[4], midstate->buffer, 16);
PUT_UINT32_BE(midstate->state[5] + A[5], midstate->buffer, 20);
PUT_UINT32_BE(midstate->state[6] + A[6], midstate->buffer, 24);
PUT_UINT32_BE(midstate->state[7] + A[7], midstate->buffer, 28);
/* Calculate the second hash (double SHA-256) */
A[0] = 0x6A09E667;
A[1] = 0xBB67AE85;
A[2] = 0x3C6EF372;
A[3] = 0xA54FF53A;
A[4] = 0x510E527F;
A[5] = 0x9B05688C;
A[6] = 0x1F83D9AB;
A[7] = 0x5BE0CD19;
midstate->buffer[32] = 0x80;
W[0] = GET_UINT32_BE(midstate->buffer, 0);
W[1] = GET_UINT32_BE(midstate->buffer, 4);
W[2] = GET_UINT32_BE(midstate->buffer, 8);
W[3] = GET_UINT32_BE(midstate->buffer, 12);
W[4] = GET_UINT32_BE(midstate->buffer, 16);
W[5] = GET_UINT32_BE(midstate->buffer, 20);
W[6] = GET_UINT32_BE(midstate->buffer, 24);
W[7] = GET_UINT32_BE(midstate->buffer, 28);
W[8] = GET_UINT32_BE(midstate->buffer, 32);
W[9] = GET_UINT32_BE(midstate->buffer, 36);
W[10] = GET_UINT32_BE(midstate->buffer, 40);
W[11] = GET_UINT32_BE(midstate->buffer, 44);
W[12] = GET_UINT32_BE(midstate->buffer, 48);
W[13] = GET_UINT32_BE(midstate->buffer, 52);
W[14] = 0;
W[15] = 256;
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[0], K[0]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[1], K[1]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[2], K[2]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[3], K[3]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[4], K[4]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[5], K[5]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[6], K[6]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[7], K[7]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[8], K[8]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[9], K[9]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[10], K[10]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[11], K[11]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[12], K[12]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[13], K[13]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[14], K[14]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[15], K[15]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(16), K[16]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(17), K[17]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(18), K[18]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(19), K[19]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(20), K[20]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(21), K[21]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(22), K[22]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(23), K[23]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(24), K[24]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(25), K[25]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(26), K[26]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(27), K[27]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(28), K[28]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(29), K[29]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(30), K[30]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(31), K[31]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(32), K[32]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(33), K[33]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(34), K[34]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(35), K[35]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(36), K[36]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(37), K[37]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(38), K[38]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(39), K[39]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(40), K[40]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(41), K[41]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(42), K[42]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(43), K[43]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(44), K[44]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(45), K[45]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(46), K[46]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(47), K[47]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(48), K[48]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(49), K[49]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(50), K[50]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(51), K[51]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(52), K[52]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(53), K[53]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(54), K[54]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(55), K[55]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(56), K[56]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(57), K[57]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(58), K[58]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(59), K[59]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(60), K[60]);
//CHECK_BYTES(0x5BE0CD19, A[7], 0);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(61), K[61]);
//CHECK_BYTES(0x1F83D9AB, A[6], 4);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(62), K[62]);
//CHECK_BYTES(0x9B05688C, A[5], 8);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(63), K[63]);
/*CHECK_BYTES(0x510E527F, A[4], 12);
CHECK_BYTES(0xA54FF53A, A[3], 16);
CHECK_BYTES(0x3C6EF372, A[2], 20);
CHECK_BYTES(0xBB67AE85, A[1], 24);
CHECK_BYTES(0x6A09E667, A[0], 28);*/
PUT_UINT32_BE(midstate->state[0] + A[0], midstate->buffer, 0);
PUT_UINT32_BE(midstate->state[1] + A[1], midstate->buffer, 4);
PUT_UINT32_BE(midstate->state[2] + A[2], midstate->buffer, 8);
PUT_UINT32_BE(midstate->state[3] + A[3], midstate->buffer, 12);
PUT_UINT32_BE(midstate->state[4] + A[4], midstate->buffer, 16);
PUT_UINT32_BE(midstate->state[5] + A[5], midstate->buffer, 20);
PUT_UINT32_BE(midstate->state[6] + A[6], midstate->buffer, 24);
PUT_UINT32_BE(midstate->state[7] + A[7], midstate->buffer, 28);
return true;
}
static void minertask(void* pctx)
{
assert(pctx);
task_ctx* tctx ;
headerandtarget header;
bool* newwork = &tctx->newwork;
while (1) {
if (*newwork) {
*newwork = false;
break;
}
vTaskDelay(1 / portTICK_PERIOD_MS);
}
header = tctx->ht;
uint32_t* hashespersec = &tctx->hashespersec;
while (true) {
_sha256_context midstate_cached = { 0 };
calc_midstate((uint8_t*)&header.bh, &midstate_cached);
*((uint32_t*)&midstate_cached.buffer[12]) = tctx->nonce_start;
_sha256_context ctx = midstate_cached;
while (true) {
//const bool within = verify_nonce(&ctx, header.target);
const bool within = false;
if (__builtin_expect(within, false)) {
*tctx->nonce_solution = *((uint32_t*)&midstate_cached.buffer[12]);
*tctx->solution_found = true;
/* wait until we have a new header to work on */
while (1) {
if (__builtin_expect(*newwork, false)) {
*newwork = false;
header = tctx->ht;
break;
}
vTaskDelay(1 / portTICK_PERIOD_MS);
}
break;
}
if (__builtin_expect(*newwork, false)) {
*newwork = false;
header = tctx->ht;
break;
}
*hashespersec = (*((uint32_t*)&midstate_cached.buffer[12]) += 1) - tctx->nonce_start;
ctx = midstate_cached;
}
}
}
bool check_solutions(void* ctx)
{
assert(ctx);
miner_ctx* mctx;
/* missing memory barrier but appers to work */
/* FIXME: find upper bound for solution len ?*/
if (!mctx->solution_found) {
return false;
}
uint8_t solution[600];
memcpy(solution, &mctx->bh, 80);
solution[80] = 0x01; /* number of transactions, solo mining :( */
memcpy(solution + 81, mctx->rawtx, mctx->txlen);
mctx->cb(mctx->cbctx, solution, 81 + mctx->txlen);
mctx->solution_found = false;
return true;
}
void check_speed(void* ctx, uint32_t* speed)
{
/* missing memory barrier but appers to work */
assert(ctx);
miner_ctx* mctx;
*speed = ((mctx->ctx1.hashespersec + mctx->ctx2.hashespersec) / ((esp_timer_get_time() - mctx->start) / 1000000.0));
}

View File

@ -0,0 +1,22 @@
#ifndef jadeSHA256_H_
#define jadeSHA256_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
typedef struct _sha256_context {
uint8_t buffer[64];
uint32_t state[8];
} _sha256_context;
/* Calculate midstate */
IRAM_ATTR void calc_midstate(uint8_t* buf_ptr, _sha256_context* midstate);
IRAM_ATTR bool make_double_sha(_sha256_context* midstate);
/* We need a way to tell the miner to us that there is a solution */
typedef void (*solution_cb)(void* ctx, const uint8_t*, uint32_t);
#endif /* jadeSHA256_H_ */

View File

@ -0,0 +1,129 @@
#include <Arduino.h>
#include <esp_task_wdt.h>
#include "jadeSHA256.h"
#include "customSHA256.h"
#include "mbedtls/md.h"
#include "mbedtls/sha256.h"
#include <wolfssl/wolfcrypt/sha256.h>
/********* INIT *****/
void setup()
{
Serial.begin(115200);
Serial.setTimeout(0);
delay(100);
// Idle task that would reset WDT never runs, because core 0 gets fully utilized
//disableCore0WDT();
}
void loop() {
//Prepare Premining data
delay(3000);
uint8_t blockheader[80] = {0};
for(int i=0; i<80; i++){
if(i<10) blockheader[i]=0;
else blockheader[i]=0xFF;
}
/* blockheader: 0000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1rstSHA: 2c6b82fa0260c2a3aca4e22444f3133a07990e5d0bb4c0faebef321027af214e
2ndSHA: 8063482c768e9a922566a895cbc5248ef29f8c0d5a65cc40c64fb74a64ec0a26
SHA256 from online resources:
blockheader: 00000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
1rstSHA: b36b04e42ed7ffc47f300d8b4f96fef9c987bacf0df40793ec8b194afad3cfbe
2ndSHA: 7201f38ecedb9b03df0101b407d5c232e62aa76c885d47055fa0f7bd1aa168ec
*/
Serial.println("");Serial.println("");
Serial.println("BlockHeader on test: ");
for (int i = 0; i < 80; i++)
Serial.printf("%02x", blockheader[i]);
Serial.println("SHA256 from online resources: ");
Serial.println("b36b04e42ed7ffc47f300d8b4f96fef9c987bacf0df40793ec8b194afad3cfbe");
Serial.println("Double SHA256 from online resources:");
Serial.println("7201f38ecedb9b03df0101b407d5c232e62aa76c885d47055fa0f7bd1aa168ec");
Serial.println("----------------------------------------------------------------");
//Test custom SHA
uint8_t hash[32];
uint8_t dhash[32];
uint32_t startT = micros();
calc_sha_256(hash, blockheader, 80);
calc_sha_256(dhash, hash, 32);
uint32_t expired = micros() - startT;
Serial.println("Custom double SHA [" + String(expired) + "us]:");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", dhash[i]);
Serial.println("");
//Test WOLF
Sha256 midstate[32];
Sha256 sha256;
uint8_t hash2[32];
wc_InitSha256(midstate);
wc_Sha256Update(midstate, blockheader, 64);
// Mining starts here
//Primer sha
startT = micros();
wc_Sha256Copy(midstate, &sha256);
wc_Sha256Update(&sha256, blockheader+64, 16);
wc_Sha256Final(&sha256, hash2);
// Segundo SHA-256
wc_Sha256Update(&sha256, hash2, 32);
wc_Sha256Final(&sha256, hash2);
expired = micros() - startT;
Serial.println("Wolf using midstate & double SHA[" + String(expired) + "us]:");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", hash2[i]);
Serial.println("");
//Test mbed
mbedtls_sha256_context midstate3;
unsigned char hash3[32];
mbedtls_sha256_context ctx;
//Calcular midstate
mbedtls_sha256_init(&midstate3);
mbedtls_sha256_starts_ret(&midstate3, 0);
mbedtls_sha256_update_ret(&midstate3, blockheader, 64);
// Mining starts here
// Primer SHA-256
startT = micros();
mbedtls_sha256_clone(&ctx, &midstate3); //Clonamos el contexto anterior para continuar el SHA desde allí
mbedtls_sha256_update_ret(&ctx, blockheader+64, 16);
mbedtls_sha256_finish_ret(&ctx, hash3);
// Segundo SHA-256
mbedtls_sha256_starts_ret(&ctx, 0);
mbedtls_sha256_update_ret(&ctx, hash3, 32);
mbedtls_sha256_finish_ret(&ctx, hash3);
expired = micros() - startT;
Serial.println("Mbed double SHA[" + String(expired) + "us]:");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", hash3[i]);
Serial.println("");
//Test Jade SHA
_sha256_context midstate_cached = { 0 };
calc_midstate(blockheader, &midstate_cached);
*((uint32_t*)&midstate_cached.buffer[12]) = 0xFFFFFFFF;//nonce;
// Mining starts here
startT = micros();
make_double_sha(&midstate_cached);
expired = micros() - startT;
Serial.println("Jade double SHA ["+ String(expired) + "us]:");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", midstate_cached.buffer[i]);
Serial.println("");
}

View File

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html