56Khs SHA version

This commit is contained in:
BitMaker 2023-08-20 00:45:09 +02:00
parent 06f7b3a3df
commit 10d01ff2c7
22 changed files with 167 additions and 1925 deletions

View File

@ -10,7 +10,7 @@
[platformio]
globallib_dir = lib
default_envs = NerminerV2
default_envs = NerminerV2, ESP32-devKitv1
[env:NerminerV2]
platform = espressif32

View File

@ -79,6 +79,7 @@ void setup()
//Standard ESP32-devKit
button1.setPressTicks(5000);
button1.attachLongPressStart(reset_configurations);
pinMode(LED_PIN, OUTPUT);
#endif
@ -165,5 +166,9 @@ void loop() {
wifiManagerProcess(); // avoid delays() in loop when non-blocking and other long running code
#ifdef DEVKITV1
doLedStuff(LED_PIN);
#endif
vTaskDelay(50 / portTICK_PERIOD_MS);
}

View File

@ -13,6 +13,32 @@
#define HASH_SIZE 32
//------------- JADE
#define SHR(x, n) ((x & 0xFFFFFFFF) >> n)
#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - 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 RJ(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; \
}
//--------------
IRAM_ATTR static inline uint32_t rotlFixed(uint32_t x, uint32_t y)
{
return (x << y) | (x >> (sizeof(y) * 8 - y));
@ -56,7 +82,12 @@ IRAM_ATTR static inline uint32_t rotrFixed(uint32_t x, uint32_t y)
)
#define RND1(j) \
t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+j] + SCHED1(j); \
t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[j] + SCHED1(j); \
t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
d(j) += t0; \
h(j) = t0 + t1
#define RND(j) \
t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[j] + SCHED(j); \
t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
d(j) += t0; \
h(j) = t0 + t1
@ -224,6 +255,97 @@ int nerd_midstate(nerd_sha256* sha256, uint8_t* data, uint32_t len)
return 0;
}
IRAM_ATTR int nerd_double_sha2(nerd_sha256* midstate, uint8_t* dataIn, uint8_t* doubleHash)
{
uint32_t S[8], t0, t1;
uint32_t W[16];
int i;
uint8_t* data;
//*********** Init 1rst SHA ***********
uint8_t data1rstSHA[64] = { dataIn[3],dataIn[2],dataIn[1],dataIn[0],dataIn[7],dataIn[6],dataIn[5],dataIn[4],
dataIn[11],dataIn[10],dataIn[9],dataIn[8],dataIn[15],dataIn[14],dataIn[13],dataIn[12],
0,0,0,0x80,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,0x80,0x02,0,0};
data = data1rstSHA;
// Copy digest to working vars
S[0] = midstate->digest[0];
S[1] = midstate->digest[1];
S[2] = midstate->digest[2];
S[3] = midstate->digest[3];
S[4] = midstate->digest[4];
S[5] = midstate->digest[5];
S[6] = midstate->digest[6];
S[7] = midstate->digest[7];
RND1( 0); RND1( 1); RND1( 2); RND1( 3);
RND1( 4); RND1( 5); RND1( 6); RND1( 7);
RND1( 8); RND1( 9); RND1(10); RND1(11);
RND1(12); RND1(13); RND1(14); RND1(15);
// 64 operations, partially loop unrolled
for (i = 16; i < 64; i += 16) {
RNDN( 0); RNDN( 1); RNDN( 2); RNDN( 3);
RNDN( 4); RNDN( 5); RNDN( 6); RNDN( 7);
RNDN( 8); RNDN( 9); RNDN(10); RNDN(11);
RNDN(12); RNDN(13); RNDN(14); RNDN(15);
}
// Add the working vars back into digest
S[0] += midstate->digest[0];
S[1] += midstate->digest[1];
S[2] += midstate->digest[2];
S[3] += midstate->digest[3];
S[4] += midstate->digest[4];
S[5] += midstate->digest[5];
S[6] += midstate->digest[6];
S[7] += midstate->digest[7];
//*********** end SHA_finish ***********
// ----- 2nd SHA ------------
uint32_t data2nSha[64] = {S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],
0x80000000,0,0,0,0,0,0,256};
data = (uint8_t*)data2nSha;
S[0] = 0x6A09E667L;
S[1] = 0xBB67AE85L;
S[2] = 0x3C6EF372L;
S[3] = 0xA54FF53AL;
S[4] = 0x510E527FL;
S[5] = 0x9B05688CL;
S[6] = 0x1F83D9ABL;
S[7] = 0x5BE0CD19L;
RND1( 0); RND1( 1); RND1( 2); RND1( 3);
RND1( 4); RND1( 5); RND1( 6); RND1( 7);
RND1( 8); RND1( 9); RND1(10); RND1(11);
RND1(12); RND1(13); RND1(14); RND1(15);
// 64 operations, partially loop unrolled
for (i = 16; i < 64; i += 16) {
RNDN( 0); RNDN( 1); RNDN( 2); RNDN( 3);
RNDN( 4); RNDN( 5); RNDN( 6); RNDN( 7);
RNDN( 8); RNDN( 9); RNDN(10); RNDN(11);
RNDN(12); RNDN(13); RNDN(14); RNDN(15);
}
// Add the working vars back into digest
S[0] += 0x6A09E667L;
S[1] += 0xBB67AE85L;
S[2] += 0x3C6EF372L;
S[3] += 0xA54FF53AL;
S[4] += 0x510E527FL;
S[5] += 0x9B05688CL;
S[6] += 0x1F83D9ABL;
S[7] += 0x5BE0CD19L;
ByteReverseWords((uint32_t*)doubleHash, S, NERD_DIGEST_SIZE);
return 0;
}
IRAM_ATTR int nerd_double_sha(nerd_sha256* midstate, uint8_t* data, uint8_t* doubleHash)
{
IRAM_DATA_ATTR nerd_sha256 sha256;

View File

@ -21,6 +21,8 @@ struct nerd_sha256 {
/* Calculate midstate */
IRAM_ATTR int nerd_midstate(nerd_sha256* sha256, uint8_t* data, uint32_t len);
IRAM_ATTR int nerd_double_sha(nerd_sha256* midstate, uint8_t* data, uint8_t* doubleHash);
//IRAM_ATTR int nerd_double_sha(nerd_sha256* midstate, uint8_t* data, uint8_t* doubleHash);
IRAM_ATTR int nerd_double_sha2(nerd_sha256* midstate, uint8_t* dataIn, uint8_t* doubleHash);
#endif /* nerdSHA256_H_ */

View File

@ -3,8 +3,8 @@
#include <WiFi.h>
#include <esp_task_wdt.h>
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
//#include <wolfssl/wolfcrypt/sha256.h>
#include "ShaTests/nerdSHA256.h"
//#include "ShaTests/nerdSHA256plus.h"
#include "media/Free_Fonts.h"
#include "media/images.h"
#include "OpenFontRender.h"
@ -226,9 +226,7 @@ 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 * task_id) {
unsigned int miner_id = (uint32_t)task_id;
@ -251,26 +249,16 @@ void runMiner(void * task_id) {
mMiner.inRun = true; //Set inRun flag
//Prepare Premining data
//Sha256 midstate[32];
nerd_sha256 nerdMidstate;
//nerdSHA256_context nerdMidstate; //NerdShaplus
uint8_t hash[32];
//Sha256 sha256;
//Calcular midstate WOLF
//wc_InitSha256(midstate);
//wc_Sha256Update(midstate, mMiner.bytearray_blockheader, 64);
//Calcular midstate
nerd_midstate(&nerdMidstate, mMiner.bytearray_blockheader, 64);
//nerd_mids(&nerdMidstate, mMiner.bytearray_blockheader); //NerdShaplus
/*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;
// split up odd/even nonces between miner tasks
@ -278,11 +266,15 @@ void runMiner(void * task_id) {
uint32_t startT = micros();
unsigned char *header64;
// each miner thread needs to track its own blockheader template
uint8_t temp;
memcpy(mMiner.bytearray_blockheader2, &mMiner.bytearray_blockheader, 80);
if (miner_id == 0)
header64 = mMiner.bytearray_blockheader + 64;
else
header64 = mMiner.bytearray_blockheader2 + 64;
bool is16BitShare=true;
Serial.println(">>> STARTING TO HASH NONCES");
while(true) {
if (miner_id == 0)
@ -290,23 +282,17 @@ void runMiner(void * task_id) {
else
memcpy(mMiner.bytearray_blockheader2 + 76, &nonce, 4);
//Con midstate
// Primer SHA-256
/*wc_Sha256Copy(midstate, &sha256);
wc_Sha256Update(&sha256, header64, 16);
wc_Sha256Final(&sha256, hash);
// Segundo SHA-256
wc_Sha256Update(&sha256, hash, 32);
wc_Sha256Final(&sha256, hash);*/
nerd_double_sha(&nerdMidstate, header64, hash);
nerd_double_sha2(&nerdMidstate, header64, hash);
//is16BitShare=nerd_sha256d(&nerdMidstate, header64, hash); //Boosted 80Khs sha
/*for (size_t i = 0; i < 32; i++)
/*Serial.print("hash1: ");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", hash[i]);
Serial.println("");
Serial.print("hash2: ");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", midstate_jade.buffer[i]);
Serial.printf("%02x", hash2[i]);
Serial.println(""); */
hashes++;
@ -315,6 +301,7 @@ void runMiner(void * task_id) {
// check if 16bit share
if(hash[31] !=0 || hash[30] !=0) {
//if(!is16BitShare){
// increment nonce
nonce += 2;
continue;

View File

@ -421,3 +421,13 @@ void show_GlobalHashScreen(unsigned long mElapsed){
//Push prepared background to screen
background.pushSprite(0,0);
}
void doLedStuff(int ledPin){
//State 1: Waiting config - on portal mode
//State 2: Config ok - but not hashing
//State 3: Hashing
//State 1:
//State 2:
}

View File

@ -50,5 +50,6 @@ void show_ClockScreen(unsigned long mElapsed);
void show_GlobalHashScreen(unsigned long mElapsed);
void show_NoScreen(unsigned long mElapsed);
void changeScreen(void);
void doLedStuff(int ledPin);
#endif //MONITOR_API_H

View File

@ -25,4 +25,5 @@ bool checkValid(unsigned char* hash, unsigned char* target);
void suffix_string(double val, char *buf, size_t bufsiz, int sigdigits);
#endif // UTILS_API_H

View File

@ -9,6 +9,7 @@
#define PIN_BUTTON_1 0
#define PIN_BUTTON_2 19 //Not used
#define PIN_ENABLE5V 21 //Not used
#define LED_PIN 2
#endif
void init_WifiManager();

View File

@ -1,11 +0,0 @@
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

View File

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

View File

@ -1,39 +0,0 @@
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

@ -1,46 +0,0 @@
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

@ -1,36 +0,0 @@
; 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

@ -1,222 +0,0 @@
#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

@ -1,103 +0,0 @@
#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

@ -1,704 +0,0 @@
#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
#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 ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - 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];
uint8_t i;
/*for (i = 0; i < 16; i++) {
W[i] = GET_UINT32_BE(buf_ptr, 4 * i);
}*/
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);
for (i = 0; i < 16; i += 8) {
P(A[0], A[1], A[2], A[3], A[4],
A[5], A[6], A[7], W[i+0], K[i+0]);
P(A[7], A[0], A[1], A[2], A[3],
A[4], A[5], A[6], W[i+1], K[i+1]);
P(A[6], A[7], A[0], A[1], A[2],
A[3], A[4], A[5], W[i+2], K[i+2]);
P(A[5], A[6], A[7], A[0], A[1],
A[2], A[3], A[4], W[i+3], K[i+3]);
P(A[4], A[5], A[6], A[7], A[0],
A[1], A[2], A[3], W[i+4], K[i+4]);
P(A[3], A[4], A[5], A[6], A[7],
A[0], A[1], A[2], W[i+5], K[i+5]);
P(A[2], A[3], A[4], A[5], A[6],
A[7], A[0], A[1], W[i+6], K[i+6]);
P(A[1], A[2], A[3], A[4], A[5],
A[6], A[7], A[0], W[i+7], K[i+7]);
}
for (i = 16; i < 64; i += 8) {
P(A[0], A[1], A[2], A[3], A[4],
A[5], A[6], A[7], R(i+0), K[i+0]);
P(A[7], A[0], A[1], A[2], A[3],
A[4], A[5], A[6], R(i+1), K[i+1]);
P(A[6], A[7], A[0], A[1], A[2],
A[3], A[4], A[5], R(i+2), K[i+2]);
P(A[5], A[6], A[7], A[0], A[1],
A[2], A[3], A[4], R(i+3), K[i+3]);
P(A[4], A[5], A[6], A[7], A[0],
A[1], A[2], A[3], R(i+4), K[i+4]);
P(A[3], A[4], A[5], A[6], A[7],
A[0], A[1], A[2], R(i+5), K[i+5]);
P(A[2], A[3], A[4], A[5], A[6],
A[7], A[0], A[1], R(i+6), K[i+6]);
P(A[1], A[2], A[3], A[4], A[5],
A[6], A[7], A[0], R(i+7), K[i+7]);
}
for (i = 0; i < 8; i++) {
midstate->state[i] += A[i];
}
/*
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), 0x80000000, 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] };
//0x80000000
union {
uint32_t num;
uint8_t b[4];
} u;
uint8_t* p = NULL;
uint8_t i;
for (i = 0; i < 16; i += 8) {
P(A[0], A[1], A[2], A[3], A[4],
A[5], A[6], A[7], W[i+0], K[i+0]);
P(A[7], A[0], A[1], A[2], A[3],
A[4], A[5], A[6], W[i+1], K[i+1]);
P(A[6], A[7], A[0], A[1], A[2],
A[3], A[4], A[5], W[i+2], K[i+2]);
P(A[5], A[6], A[7], A[0], A[1],
A[2], A[3], A[4], W[i+3], K[i+3]);
P(A[4], A[5], A[6], A[7], A[0],
A[1], A[2], A[3], W[i+4], K[i+4]);
P(A[3], A[4], A[5], A[6], A[7],
A[0], A[1], A[2], W[i+5], K[i+5]);
P(A[2], A[3], A[4], A[5], A[6],
A[7], A[0], A[1], W[i+6], K[i+6]);
P(A[1], A[2], A[3], A[4], A[5],
A[6], A[7], A[0], W[i+7], K[i+7]);
}
for (i = 16; i < 64; i += 8) {
P(A[0], A[1], A[2], A[3], A[4],
A[5], A[6], A[7], R(i+0), K[i+0]);
P(A[7], A[0], A[1], A[2], A[3],
A[4], A[5], A[6], R(i+1), K[i+1]);
P(A[6], A[7], A[0], A[1], A[2],
A[3], A[4], A[5], R(i+2), K[i+2]);
P(A[5], A[6], A[7], A[0], A[1],
A[2], A[3], A[4], R(i+3), K[i+3]);
P(A[4], A[5], A[6], A[7], A[0],
A[1], A[2], A[3], R(i+4), K[i+4]);
P(A[3], A[4], A[5], A[6], A[7],
A[0], A[1], A[2], R(i+5), K[i+5]);
P(A[2], A[3], A[4], A[5], A[6],
A[7], A[0], A[1], R(i+6), K[i+6]);
P(A[1], A[2], A[3], A[4], A[5],
A[6], A[7], A[0], R(i+7), K[i+7]);
}
/*
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;
for (i = 0; i < 16; i += 8) {
P(A[0], A[1], A[2], A[3], A[4],
A[5], A[6], A[7], W[i+0], K[i+0]);
P(A[7], A[0], A[1], A[2], A[3],
A[4], A[5], A[6], W[i+1], K[i+1]);
P(A[6], A[7], A[0], A[1], A[2],
A[3], A[4], A[5], W[i+2], K[i+2]);
P(A[5], A[6], A[7], A[0], A[1],
A[2], A[3], A[4], W[i+3], K[i+3]);
P(A[4], A[5], A[6], A[7], A[0],
A[1], A[2], A[3], W[i+4], K[i+4]);
P(A[3], A[4], A[5], A[6], A[7],
A[0], A[1], A[2], W[i+5], K[i+5]);
P(A[2], A[3], A[4], A[5], A[6],
A[7], A[0], A[1], W[i+6], K[i+6]);
P(A[1], A[2], A[3], A[4], A[5],
A[6], A[7], A[0], W[i+7], K[i+7]);
}
for (i = 16; i < 64; i += 8) {
P(A[0], A[1], A[2], A[3], A[4],
A[5], A[6], A[7], R(i+0), K[i+0]);
P(A[7], A[0], A[1], A[2], A[3],
A[4], A[5], A[6], R(i+1), K[i+1]);
P(A[6], A[7], A[0], A[1], A[2],
A[3], A[4], A[5], R(i+2), K[i+2]);
P(A[5], A[6], A[7], A[0], A[1],
A[2], A[3], A[4], R(i+3), K[i+3]);
P(A[4], A[5], A[6], A[7], A[0],
A[1], A[2], A[3], R(i+4), K[i+4]);
P(A[3], A[4], A[5], A[6], A[7],
A[0], A[1], A[2], R(i+5), K[i+5]);
P(A[2], A[3], A[4], A[5], A[6],
A[7], A[0], A[1], R(i+6), K[i+6]);
P(A[1], A[2], A[3], A[4], A[5],
A[6], A[7], A[0], R(i+7), K[i+7]);
}
/*
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

@ -1,22 +0,0 @@
#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

@ -1,463 +0,0 @@
#define NDEBUG
#include <stdio.h>
#include <string.h>
#include <Arduino.h>
//#include <wolfssl/wolfcrypt/sha256.h>
#include <esp_log.h>
#include <esp_timer.h>
#include "nerdSHA256.h"
#include <math.h>
#include <string.h>
#define HASH_SIZE 32
//------------- JADE
#define SHR(x, n) ((x & 0xFFFFFFFF) >> n)
#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - 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 RJ(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; \
}
//--------------
IRAM_ATTR static inline uint32_t rotlFixed(uint32_t x, uint32_t y)
{
return (x << y) | (x >> (sizeof(y) * 8 - y));
}
IRAM_ATTR static inline uint32_t rotrFixed(uint32_t x, uint32_t y)
{
return (x >> y) | (x << (sizeof(y) * 8 - y));
}
/* SHA256 math based on specification */
#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define Maj(x,y,z) ((((x) | (y)) & (z)) | ((x) & (y)))
#define R(x, n) (((x) & 0xFFFFFFFFU) >> (n))
#define S(x, n) rotrFixed(x, n)
#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
#define a(i) S[(0-(i)) & 7]
#define b(i) S[(1-(i)) & 7]
#define c(i) S[(2-(i)) & 7]
#define d(i) S[(3-(i)) & 7]
#define e(i) S[(4-(i)) & 7]
#define f(i) S[(5-(i)) & 7]
#define g(i) S[(6-(i)) & 7]
#define h(i) S[(7-(i)) & 7]
#define XTRANSFORM(S, D) Transform_Sha256((S),(D))
#define XMEMCPY(d,s,l) memcpy((d),(s),(l))
#define XMEMSET(b,c,l) memset((b),(c),(l))
/* SHA256 version that keeps all data in registers */
#define SCHED1(j) (W[j] = *((uint32_t*)&data[j*sizeof(uint32_t)]))
#define SCHED(j) ( \
W[ j & 15] += \
Gamma1(W[(j-2) & 15])+ \
W[(j-7) & 15] + \
Gamma0(W[(j-15) & 15]) \
)
#define RND1(j) \
t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[j] + SCHED1(j); \
t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
d(j) += t0; \
h(j) = t0 + t1
#define RND(j) \
t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[j] + SCHED(j); \
t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
d(j) += t0; \
h(j) = t0 + t1
DRAM_ATTR static const uint32_t K[64] = {
0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL,
0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L,
0x243185BEL, 0x550C7DC3L, 0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L,
0xC19BF174L, 0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL,
0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL, 0x983E5152L,
0xA831C66DL, 0xB00327C8L, 0xBF597FC7L, 0xC6E00BF3L, 0xD5A79147L,
0x06CA6351L, 0x14292967L, 0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL,
0x53380D13L, 0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L,
0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L, 0xD192E819L,
0xD6990624L, 0xF40E3585L, 0x106AA070L, 0x19A4C116L, 0x1E376C08L,
0x2748774CL, 0x34B0BCB5L, 0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL,
0x682E6FF3L, 0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L,
0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L
};
IRAM_ATTR bool doSHA(nerd_sha256* midstate)
{
uint32_t temp1, temp2;
uint8_t temp3, temp4;
uint32_t W[64] = { midstate->buffer[0], midstate->buffer[1], midstate->buffer[2],
midstate->buffer[3], midstate->buffer[4], midstate->buffer[5], 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};
uint32_t A[8] = { midstate->digest[0], midstate->digest[1], midstate->digest[2], midstate->digest[3],
midstate->digest[4], midstate->digest[5], midstate->digest[6], midstate->digest[7] };
//0x80000000
union {
uint32_t num;
uint8_t b[4];
} u;
uint8_t* p = NULL;
uint8_t i;
for (i = 0; i < 16; i += 8) {
P(A[0], A[1], A[2], A[3], A[4],
A[5], A[6], A[7], W[i+0], K[i+0]);
P(A[7], A[0], A[1], A[2], A[3],
A[4], A[5], A[6], W[i+1], K[i+1]);
P(A[6], A[7], A[0], A[1], A[2],
A[3], A[4], A[5], W[i+2], K[i+2]);
P(A[5], A[6], A[7], A[0], A[1],
A[2], A[3], A[4], W[i+3], K[i+3]);
P(A[4], A[5], A[6], A[7], A[0],
A[1], A[2], A[3], W[i+4], K[i+4]);
P(A[3], A[4], A[5], A[6], A[7],
A[0], A[1], A[2], W[i+5], K[i+5]);
P(A[2], A[3], A[4], A[5], A[6],
A[7], A[0], A[1], W[i+6], K[i+6]);
P(A[1], A[2], A[3], A[4], A[5],
A[6], A[7], A[0], W[i+7], K[i+7]);
}
for (i = 16; i < 64; i += 8) {
P(A[0], A[1], A[2], A[3], A[4],
A[5], A[6], A[7], RJ(i+0), K[i+0]);
P(A[7], A[0], A[1], A[2], A[3],
A[4], A[5], A[6], RJ(i+1), K[i+1]);
P(A[6], A[7], A[0], A[1], A[2],
A[3], A[4], A[5], RJ(i+2), K[i+2]);
P(A[5], A[6], A[7], A[0], A[1],
A[2], A[3], A[4], RJ(i+3), K[i+3]);
P(A[4], A[5], A[6], A[7], A[0],
A[1], A[2], A[3], RJ(i+4), K[i+4]);
P(A[3], A[4], A[5], A[6], A[7],
A[0], A[1], A[2], RJ(i+5), K[i+5]);
P(A[2], A[3], A[4], A[5], A[6],
A[7], A[0], A[1], RJ(i+6), K[i+6]);
P(A[1], A[2], A[3], A[4], A[5],
A[6], A[7], A[0], RJ(i+7), K[i+7]);
}
/*
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], RJ(16), K[16]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], RJ(17), K[17]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], RJ(18), K[18]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], RJ(19), K[19]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], RJ(20), K[20]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], RJ(21), K[21]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], RJ(22), K[22]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], RJ(23), K[23]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], RJ(24), K[24]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], RJ(25), K[25]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], RJ(26), K[26]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], RJ(27), K[27]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], RJ(28), K[28]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], RJ(29), K[29]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], RJ(30), K[30]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], RJ(31), K[31]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], RJ(32), K[32]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], RJ(33), K[33]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], RJ(34), K[34]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], RJ(35), K[35]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], RJ(36), K[36]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], RJ(37), K[37]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], RJ(38), K[38]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], RJ(39), K[39]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], RJ(40), K[40]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], RJ(41), K[41]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], RJ(42), K[42]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], RJ(43), K[43]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], RJ(44), K[44]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], RJ(45), K[45]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], RJ(46), K[46]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], RJ(47), K[47]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], RJ(48), K[48]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], RJ(49), K[49]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], RJ(50), K[50]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], RJ(51), K[51]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], RJ(52), K[52]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], RJ(53), K[53]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], RJ(54), K[54]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], RJ(55), K[55]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], RJ(56), K[56]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], RJ(57), K[57]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], RJ(58), K[58]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], RJ(59), K[59]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], RJ(60), K[60]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], RJ(61), K[61]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], RJ(62), K[62]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], RJ(63), K[63]);
*/
midstate->digest[0] += A[0];
midstate->digest[1] += A[1];
midstate->digest[2] += A[2];
midstate->digest[3] += A[3];
midstate->digest[4] += A[4];
midstate->digest[5] += A[5];
midstate->digest[6] += A[6];
midstate->digest[7] += A[7];
return true;
}
IRAM_ATTR inline static int Transform_Sha256(nerd_sha256* sha256, const uint8_t* data)
{
IRAM_DATA_ATTR uint32_t S[8], t0, t1;
int i;
IRAM_DATA_ATTR uint32_t W[NERD_BLOCK_SIZE/sizeof(uint32_t)];
/* Copy digest to working vars */
S[0] = sha256->digest[0];
S[1] = sha256->digest[1];
S[2] = sha256->digest[2];
S[3] = sha256->digest[3];
S[4] = sha256->digest[4];
S[5] = sha256->digest[5];
S[6] = sha256->digest[6];
S[7] = sha256->digest[7];
RND1( 0); RND1( 1); RND1( 2); RND1( 3);
RND1( 4); RND1( 5); RND1( 6); RND1( 7);
RND1( 8); RND1( 9); RND1(10); RND1(11);
RND1(12); RND1(13); RND1(14); RND1(15);
/* 64 operations, partially loop unrolled */
/*for (i = 16; i < 64; i += 16) {
RNDN( 0); RNDN( 1); RNDN( 2); RNDN( 3);
RNDN( 4); RNDN( 5); RNDN( 6); RNDN( 7);
RNDN( 8); RNDN( 9); RNDN(10); RNDN(11);
RNDN(12); RNDN(13); RNDN(14); RNDN(15);
}*/
RND(16); RND(17); RND(18); RND(19);
RND(20); RND(21); RND(22); RND(23);
RND(24); RND(25); RND(26); RND(27);
RND(28); RND(29); RND(30); RND(31);
RND(32); RND(33); RND(34); RND(35);
RND(36); RND(37); RND(38); RND(39);
RND(40); RND(41); RND(42); RND(43);
RND(44); RND(45); RND(46); RND(47);
RND(48); RND(49); RND(50); RND(51);
RND(52); RND(53); RND(54); RND(55);
RND(56); RND(57); RND(58); RND(59);
RND(60); RND(61); RND(62); RND(63);
/* Add the working vars back into digest */
sha256->digest[0] += S[0];
sha256->digest[1] += S[1];
sha256->digest[2] += S[2];
sha256->digest[3] += S[3];
sha256->digest[4] += S[4];
sha256->digest[5] += S[5];
sha256->digest[6] += S[6];
sha256->digest[7] += S[7];
return 0;
}
IRAM_ATTR static uint32_t ByteReverseWord32(uint32_t value){
value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
return rotlFixed(value, 16U);
}
IRAM_ATTR static void ByteReverseWords(uint32_t* out, const uint32_t* in, uint32_t byteCount)
{
uint32_t count, i;
count = byteCount/(uint32_t)sizeof(uint32_t);
for (i = 0; i < count; i++) out[i] = ByteReverseWord32(in[i]);
}
static int nerd_update(nerd_sha256* sha256, uint8_t* data, uint32_t len)
{
int ret = 0;
uint32_t blocksLen;
uint8_t* local;
//ShaUpdate
uint32_t tmp = sha256->loLen;
if ((sha256->loLen += len) < tmp) {
sha256->hiLen++; /* carry low to high */
}
local = (uint8_t*)sha256->buffer;
/* process any remainder from previous operation */
if (sha256->buffLen > 0) {
blocksLen = min(len, NERD_BLOCK_SIZE - sha256->buffLen);
XMEMCPY(&local[sha256->buffLen], data, blocksLen);
sha256->buffLen += blocksLen;
data += blocksLen;
len -= blocksLen;
if (sha256->buffLen == NERD_BLOCK_SIZE) {
ByteReverseWords(sha256->buffer, sha256->buffer, NERD_BLOCK_SIZE);
ret = XTRANSFORM(sha256, (const uint8_t*)local);
if (ret == 0)
sha256->buffLen = 0;
else
len = 0; /* error */
}
}
/* process blocks */
while (len >= NERD_BLOCK_SIZE) {
uint32_t* local32 = sha256->buffer;
XMEMCPY(local32, data, NERD_BLOCK_SIZE);
data += NERD_BLOCK_SIZE;
len -= NERD_BLOCK_SIZE;
ByteReverseWords(local32, local32, NERD_BLOCK_SIZE);
ret = XTRANSFORM(sha256, (const uint8_t*)local32);
if (ret != 0)
break;
}
/* save remainder */
if (ret == 0 && len > 0) {
XMEMCPY(local, data, len);
sha256->buffLen = len;
}
return ret;
}
int nerd_midstate(nerd_sha256* sha256, uint8_t* data, uint32_t len)
{
int ret = 0;
uint32_t blocksLen;
uint8_t* local;
//Init SHA context
XMEMSET(sha256->digest, 0, sizeof(sha256->digest));
sha256->digest[0] = 0x6A09E667L;
sha256->digest[1] = 0xBB67AE85L;
sha256->digest[2] = 0x3C6EF372L;
sha256->digest[3] = 0xA54FF53AL;
sha256->digest[4] = 0x510E527FL;
sha256->digest[5] = 0x9B05688CL;
sha256->digest[6] = 0x1F83D9ABL;
sha256->digest[7] = 0x5BE0CD19L;
sha256->buffLen = 0;
sha256->loLen = 0;
sha256->hiLen = 0;
//endINIT Sha contexxt
nerd_update(sha256,data,len);
return 0;
}
IRAM_ATTR int nerd_double_sha(nerd_sha256* midstate, uint8_t* data, uint8_t* doubleHash)
{
IRAM_DATA_ATTR nerd_sha256 sha256;
//nerd_sha256 sha256_2;
int ret = 0;
uint32_t blocksLen;
uint8_t* local;
//Copy current context
sha256 = *midstate;
// ----- 1rst SHA ------------
//*********** ShaUpdate ***********
local = (uint8_t*)sha256.buffer;
XMEMCPY(local, data, 16); //Pending bytes to make the sha256
//*********** end update ***********
//*********** Init SHA_finish ***********
local[16] = 0x80; // add 1
//ADD final zeros
XMEMSET(&local[17], 0, 39); //NERD_PAD_SIZE - sha256.buffLen);
// put lengths in bits
sha256.hiLen = 0;
sha256.loLen = 640;
ByteReverseWords(sha256.buffer, sha256.buffer, NERD_BLOCK_SIZE);
// ! length ordering dependent on digest endian type !
XMEMCPY(&local[NERD_PAD_SIZE], &sha256.hiLen, sizeof(uint32_t));
XMEMCPY(&local[NERD_PAD_SIZE + sizeof(uint32_t)], &sha256.loLen, sizeof(uint32_t));
XTRANSFORM(&sha256, (const uint8_t*)local);
//doSHA(&sha256);
//*********** end SHA_finish ***********
// ----- 2nd SHA ------------
//Init SHA context again
IRAM_DATA_ATTR nerd_sha256 secondSha256 = {
// Init with initial sha data
.digest = {0x6A09E667L, 0xBB67AE85L, 0x3C6EF372L, 0xA54FF53AL, 0x510E527FL, 0x9B05688CL, 0x1F83D9ABL, 0x5BE0CD19L},
// Init with past SHA done
.buffer = {sha256.digest[0],sha256.digest[1],sha256.digest[2],sha256.digest[3],sha256.digest[4],sha256.digest[5],sha256.digest[6],sha256.digest[7],
0x80000000,0,0,0,0,0,0,0}, // Init with past hash and 0x80
.buffLen = 32, // Bytes to hash
.loLen = 256, // Init to 256 bits
.hiLen = 0, // Inicializar a cero
.heap = NULL // Inicializar a NULL
};
local = (uint8_t*)secondSha256.buffer;
// ! length ordering dependent on digest endian type !
XMEMCPY(&local[NERD_PAD_SIZE + sizeof(uint32_t)], &secondSha256.loLen, sizeof(uint32_t));
XTRANSFORM(&secondSha256, (const uint8_t*)local);
ByteReverseWords((uint32_t*)doubleHash, secondSha256.digest, NERD_DIGEST_SIZE);
return 0;
}

View File

@ -1,26 +0,0 @@
#ifndef nerdSHA256_H_
#define nerdSHA256_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define NERD_DIGEST_SIZE 32
#define NERD_BLOCK_SIZE 64
#define NERD_PAD_SIZE 56
struct nerd_sha256 {
uint32_t digest[NERD_DIGEST_SIZE / sizeof(uint32_t)];
uint32_t buffer[NERD_BLOCK_SIZE / sizeof(uint32_t)];
uint32_t buffLen; /* in bytes */
uint32_t loLen; /* length in bytes */
uint32_t hiLen; /* length in bytes */
void* heap;
};
/* Calculate midstate */
IRAM_ATTR int nerd_midstate(nerd_sha256* sha256, uint8_t* data, uint32_t len);
IRAM_ATTR int nerd_double_sha(nerd_sha256* midstate, uint8_t* data, uint8_t* doubleHash);
#endif /* nerdSHA256_H_ */

View File

@ -1,199 +0,0 @@
#include <Arduino.h>
#include <esp_task_wdt.h>
#include "jadeSHA256.h"
#include "customSHA256.h"
#include "nerdSHA256.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;
Sha256 sha256;
uint8_t hash2[32];
wc_InitSha256(&midstate);
wc_Sha256Update(&midstate, blockheader, 64);
Serial.print("Wolf midstate: ");
for (size_t i = 0; i < 8; i++)
Serial.printf("%02x", midstate.digest[i]);
Serial.println("");
// 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);
Serial.println("Mbed midstate:");
for (size_t i = 0; i < 8; i++)
Serial.printf("%02x", midstate3.state[i]);
Serial.println("");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", midstate3.buffer[i]);
Serial.println("");
// 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 };
memcpy(midstate_cached.buffer, blockheader, 64);
calc_midstate(blockheader, &midstate_cached);
Serial.println("Jade midstate:");
for (size_t i = 0; i < 8; i++)
Serial.printf("%02x", midstate_cached.state[i]);
Serial.println("");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", midstate_cached.buffer[i]);
Serial.println("");
*((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("");
//Test nerdSHA
nerd_sha256 nerdMidstate;
uint8_t nerdHash[32];
nerd_midstate(&nerdMidstate, blockheader, 64);
Serial.print("Nerd midstate: ");
for (size_t i = 0; i < 8; i++)
Serial.printf("%02x", nerdMidstate.digest[i]);
Serial.println("");
//Mining starts here
startT = micros();
nerd_double_sha(&nerdMidstate, blockheader+64,nerdHash);
expired = micros() - startT;
Serial.println("Nerd double SHA[" + String(expired) + "us]:");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", nerdHash[i]);
Serial.println("");
//-------------- Check result with other nonce -------------- -------------------- <<<<
//Repeat tests with other value
// WOLF TEST NEXT NONCE
blockheader[79]=1;
//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 next nonce[" + String(expired) + "us]:");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", hash2[i]);
Serial.println("");
//NERD TEST NEXT NONCE
//Mining starts here
startT = micros();
nerd_double_sha(&nerdMidstate, blockheader+64,nerdHash);
expired = micros() - startT;
Serial.println("Nerd next nonce[" + String(expired) + "us]:");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", nerdHash[i]);
Serial.println("");
}

View File

@ -1,11 +0,0 @@
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