Author

Topic: How to hash the midstate? (Read 1839 times)

newbie
Activity: 1
Merit: 0
June 05, 2015, 06:42:41 PM
#5
It appears that King changed the data string into a byte array somewhere else in his program before feeding it to the Sha256.write command, but I never figured out how to make that conversion.  Using the Sha256.print command to take the String directly does not seem to work.  Any suggestions?  The part of my code pertaining to midstate calc is below.  Alternately, pointing me to a code example that correctly makes a byte array out of the getwork data string without using a bunch of libraries that don't work in Arduino IDE would help a lot. 

As with King, just doing this for fun and learning, no dillusions that an Arduino is effective mining hardware.

Thanks.

Code:
#include "sha256.h"

void setup() {
    Serial.begin(57600);
}

void loop() {
    String data = "00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca064f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d89b574a864db8345b1b00b5ac00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000";  
    data = RemovePadding(data);
    data = EndianFlip32BitChunks(data);  //flips from little endian to big endian

    Sha256.init();
    Sha256.print(data.substring(0,80)); //hash first half to make midstate
    uint8_t* midstatearray = Sha256.result();
    Serial.println(F("Calc midstate is:"));
    printHash(midstatearray);
    Serial.println(F("Expected:"));
    Serial.println(F("e772fc6964e7b06d8f855a6166353e48b2562de4ad037abc889294cea8ed1070"));
}

void printHash(uint8_t* hash) {
  int i;
  for (i=0; i<32; ++i) {
    Serial.print("0123456789abcdef"[hash[i]>>4]);
    Serial.print("0123456789abcdef"[hash[i]&0xf]);
  }
  Serial.println();
}

static String EndianFlip32BitChunks(String input)
        {
            //32 bits = 4*4 bytes = 4*4*2 chars
            String result = "";
            for (int i = 0; i < input.length(); i += 8)
                for (int j = 0; j < 8; j += 2)
                {
                    //append byte (2 chars)
                    result += input[i - j + 6];
                    result += input[i - j + 7];
                }
            return result;        
        }
        
 static String RemovePadding(String input)
        {
            //payload length: final 64 bits in big-endian - 0x0000000000000280 = 640 bits = 80 bytes = 160 chars
            return input.substring(0, 160);
        }
newbie
Activity: 16
Merit: 0
March 23, 2013, 07:05:39 AM
#4

I am writing a hardware bitcoin wallet via Arduino. I took a detour and hooked it up to a mining pool. It was still crazy slow but considerably faster then the Uno. It did about 1600 hashes a second. I think mostly it was just fun to see a 5v Arduino hash.

A video of it hashing.
https://www.youtube.com/watch?v=UvSVxC7dy9c
hero member
Activity: 826
Merit: 500
October 09, 2012, 08:21:14 PM
#3

thanks for posting back. good manners:)
newbie
Activity: 16
Merit: 0
October 09, 2012, 05:00:12 PM
#2
I figured it out, I was confused about how midstate works. For anybody who cares, the hash rate of an Arduino UNO is about 36 hashes a second.
newbie
Activity: 16
Merit: 0
October 02, 2012, 03:58:00 PM
#1

This is my first post, so please go easy on me.
First off, I've done my due diligence. I've searched this forum and studied the documentation on both Bitcoin and SHA256. However, with SHA256, I'm still a little confused.
I wanted to learn both Bitcoin and Arduino so I've started to build a miner. Now before anybody says that's a stupid idea, I know it is. I'm just doing this for fun and learning. And for the most part, it has been fun until I've hit a roadblock.
I am able to get the midstate by doing a 256 hash on the first half of Data that I get from a "getwork" call. It matches perfectly the "midstate" that came with the "getwork" call. Because of that I'm fairly confident that I'm getting the endian in the right order and that my 256 library is functional. The 256 library that I'm using is :https://code.google.com/p/cryptosuite/source/browse/Sha/sha256.h?r=ba70bfce07af76ff141c53833b8c1d15e3d7d368
to get midstate I do this:

Code:
 
Sha256.init();
for(int i = 0;i < 64;++i)
{
       Sha256.write(midstateByte[i]);
}

and it works like a champ, no problems. My problem that I desperately need help with is how to do the second and final hash. I know the nonce is in the second half of the data block. You increment the nonce and then do a hash on the second block.  Which I can following the same procedure as I did with the first half to get the midstate. How do I combine midstate and the first hash together? in this post at : https://bitcointalksearch.org/topic/do-i-understand-header-hashing-13113 a user says

Quote
This will also  output 8 32bit numbers. Each number from the second "chunk" is added to the first, to its corresponding number from the first chunk. This addition is done over modulo 2^32 for each number, so there's no overflow or carry.

I don't understand what he is saying here. Somehow I'm supposed to add a 32 byte array (midstate) to the result of the first hash on the second half of Data, another 32 byte array, and get a 64 byte array to put through SHA256 for the final hash.

If anybody could explain how to do that I would be extremely appreciative. Also, I know you can just hash the entire data without breaking it up, but unfortunately I'm hitting Arduino stack limits. I also know that most robust SHA256 libraries have an option to do this, but mine does not and I can't use another.

Please include a address for tips, because I'm desperate! Thanks again!
Jump to: