Author

Topic: Question about Wt in the SHA-256 algorithm (Read 293 times)

legendary
Activity: 3472
Merit: 4801
March 16, 2018, 01:48:11 PM
#9
I am not too sure where N comes from in BTC, is it from a previous block (blockchain block)?
What is a block in this equation? is it a 32bit chunk of the padded message?

SHA256 is an algorithm that can be applied to any arbitrary binary data.  It isn't exclusive to Bitcoin.

The Wikipedia and NIST links that you provided are generic descriptions about the SHA256 algorithm. There is nothing about Bitcoin at all in either of those links.  Therefore, references to "blocks" in either of those are references to some defined block of data, and not to a "Bitcoin Block".

Specifically, if you actually started reading the NIST document from the top, (instead of jumping straight to the calculation on page 27), then you would have found that:

M is the message to be hashed.  In other words, it is the data that is being hashed.

You would also have found that some pre-processing is required to pad the message separate it into blocks (see page 21).
Quote
5. PREPROCESSING
Preprocessing consists of three steps: padding the message, M (Sec.  5.1), parsing the message into message blocks (Sec. 5.2), and setting the initial hash value, H(0) (Sec. 5.3).

Then you would have discovered that the message M needs to be padded to a multiple of 512 bits before it can be hashed:
Quote
5.1 Padding the message
The  purpose  of  this  padding  is  to  ensure  that  the  padded  message  is  a  multiple  of  512  or  1024  
bits, depending on the algorithm.

5.1.1 SHA-1, SHA-224 and SHA-256
Suppose that the length of the message, M, is l bits. Append the bit “1” to the end of the message, followed by k zero bits, where k is the smallest, non-negative solution to the equation (l + 1 + k)mod512 = 448. Then append the 64-bit block that is equal to the number l expressed using a binary representation.

And finally, you would find that the message M needs to be parsed into blocks of data that are each exactly 512 bits long:
Quote
5.2 Parsing the message
The message and its padding must be parsed into N m-bit blocks.

5.2.1 SHA-1, SHA-224 and SHA-256
For SHA-1, SHA-224 and SHA-256, the message and its padding are parsed into N 512-bit blocks, M(1), M(2),...,M(N). Since the 512 bits of the input block may be expressed as sixteen 32-bit words, the first 32 bits of message block i are denoted M0(i), the next 32 bits are M1(i), and so on up to M15(i).  

So:

Data that is less than 449 bits will be padded out to 512 bits and will be parsed into a single 512 bit block.  In that case N is 1 (there is only 1 block of data to hash).

Data that is more than 448 bits and less than 961 bits will be padded out to 1024 bits and will be parsed into two 512 bit blocks. In that case N is 2 (there are 2 blocks of data to hash).

Data that is more than 960 bits and less than 1473 bits will be padded out to 1536 bits and will be parsed into three 512 bit blocks. In that case N is 3 (there are 3 blocks of data to hash).

This process can be continued for any arbitrary length of data.

Note that the Bitcoin Block header is 80 bytes (640 bits), and therefore must be padded to 1024 bits and parsed into two 512 bit blocks.
 
jr. member
Activity: 44
Merit: 12
You left out a line of pseudo-code:

It should be:

For i = 1 to N
Wt = {
    Mti  (when 0 ≤ t ≤ 15)
    ROTL1 (Wt−3 ⊕ Wt−8 ⊕ Wt−14 ⊕ Wt−16) (when 16 ≤ t ≤ 79)
}


N is the number of blocks in the padded message, so the first line says to loop through all the blocks in the message (this explains where the i in the Mti comes from).

Wt is the tth word of the message schedule, so when processing word #1, that would be W1, when processing word #2, it would be W2, and so on.

For each word of the message schedule, you perform one of two processes...

If you are processing any of the first 16 words in a message block (word #0 through word #15), then you simply set Wt to the value of that word:
Mti is just the tth word of the ith message block

If you are processing any of the remaining words in a message block (word #16 through word #79) then you set Wt to the result of the following function:
ROTL1 (Wt−3 ⊕ Wt−8 ⊕ Wt−14 ⊕ Wt−16)

ROTL1 means to perform a one bit circular left shift.

The thing that is being shifted is the result of:
Wt−3 ⊕ Wt−8 ⊕ Wt−14 ⊕ Wt−16

Remember that you are processing the tth word and that this only happens when you are processing words 16 through 79, so for example:
If t is 17 then you perform:
W17−3 ⊕ W17−8 ⊕ W17−14 ⊕ W17−16
complete those subtractions and you find that you are performing:
W14 ⊕ W9 ⊕ W3 ⊕ W1
Since  is the symbol for the EXCLUSIVE OR (XOR) operation, you need to perform an XOR on those 4 words of the message schedule.

This set of instructions is performed for all 80 words in the message block (word #0 through word #79)



Thank you very much for your answer Danny, I am still digesting it.
I am not too sure where N comes from in BTC, is it from a previous block (blockchain block)?
What is a block in this equation? is it a 32bit chunk of the padded message?

legendary
Activity: 4542
Merit: 3393
Vile Vixen and Miss Bitcointalk 2021-2023
Most C++ compilers have been optimized, so if the code is well written then it should run just about as fast as it would if it was written in assembler.
Even faster, actually, since modern optimising compilers are smarter than nearly all human programmers. Unless you're John Carmack, you should expect hand-optimised code to run even slower than machine-optimised code (not to mention be much harder to debug).
J-N
member
Activity: 100
Merit: 13
Compiled C++ results in machine code binaries.  Most C++ compilers have been optimized, so if the code is well written then it should run just about as fast as it would if it was written in assembler.

Well C# results in almost the same assembly code as using C++ in windows I am told and I even tried speeding things
up using un-safe pointer code but that didn't achieve much of a result so maybe hidden within the COM windows is still using
after they told everyone to move over to Dot.Net they kick out to some custom hand crafted machine code.
You can use inline assembly code in C++ program, for example:
Code:
#include 

int main() {
    /* moves the byte from ch to the memory pointed by ebx */
    __asm__("movb %ch, (%ebx)");

    return 0 ;
}

So SHA256 can be implemented directly in ASM code and the computing will be fast as possible on the CPU.
member
Activity: 210
Merit: 26
High fees = low BTC price
Compiled C++ results in machine code binaries.  Most C++ compilers have been optimized, so if the code is well written then it should run just about as fast as it would if it was written in assembler.

Well C# results in almost the same assembly code as using C++ in windows I am told and I even tried speeding things
up using un-safe pointer code but that didn't achieve much of a result so maybe hidden within the COM windows is still using
after they told everyone to move over to Dot.Net they kick out to some custom hand crafted machine code.

I even played with un-checked (Maloc in C++ i think you call it) but that didn't result in any gains at all so maybe I will
crank up VC just out of interest and give that a go not that I can remember much C++ and most of that came from Borlands C++

I think the other part of your answer is spot on the money 
legendary
Activity: 3472
Merit: 4801
these functions must be built at assembly level and not from compiled C++

Whats your thought on this ?

Compiled C++ results in machine code binaries.  Most C++ compilers have been optimized, so if the code is well written then it should run just about as fast as it would if it was written in assembler.

That being said, SHA256 is common enough that it is now implemented directly on the hardware.  That's what an ASIC is.  It's hardware that is custom designed for a single purpose.  The SHA256 maths can all be implemented with combinations of circuits.  As such, the entire calculation can be completed in the amount of time that it takes for the electricity to flow through the circuit.
member
Activity: 210
Merit: 26
High fees = low BTC price
You left out a line of pseudo-code:

It should be:

For i = 1 to N
Wt = {
    Mti  (when 0 ≤ t ≤ 15)
    ROTL1 (Wt−3 ⊕ Wt−8 ⊕ Wt−14 ⊕ Wt−16) (when 16 ≤ t ≤ 79)
}

I can see you know your stuff here but with all that maths going on you would expect it to be slow but it's not
really and the same is also true with GZip so these functions must be built at assembly level and not from compiled
C++ or C# using *ptr because they run almost as fast as we can iterate a byte array in Dot.NET without performing any "if" statements
or maths.

Whats your thought on this ?

Would send you a merit but i think the merit routine here is broken because I don't have any left to spend it says
legendary
Activity: 3472
Merit: 4801
You left out a line of pseudo-code:

It should be:

For i = 1 to N
Wt = {
    Mti  (when 0 ≤ t ≤ 15)
    ROTL1 (Wt−3 ⊕ Wt−8 ⊕ Wt−14 ⊕ Wt−16) (when 16 ≤ t ≤ 79)
}


N is the number of blocks in the padded message, so the first line says to loop through all the blocks in the message (this explains where the i in the Mti comes from).

Wt is the tth word of the message schedule, so when processing word #1, that would be W1, when processing word #2, it would be W2, and so on.

For each word of the message schedule, you perform one of two processes...

If you are processing any of the first 16 words in a message block (word #0 through word #15), then you simply set Wt to the value of that word:
Mti is just the tth word of the ith message block

If you are processing any of the remaining words in a message block (word #16 through word #79) then you set Wt to the result of the following function:
ROTL1 (Wt−3 ⊕ Wt−8 ⊕ Wt−14 ⊕ Wt−16)

ROTL1 means to perform a one bit circular left shift.

The thing that is being shifted is the result of:
Wt−3 ⊕ Wt−8 ⊕ Wt−14 ⊕ Wt−16

Remember that you are processing the tth word and that this only happens when you are processing words 16 through 79, so for example:
If t is 17 then you perform:
W17−3 ⊕ W17−8 ⊕ W17−14 ⊕ W17−16
complete those subtractions and you find that you are performing:
W14 ⊕ W9 ⊕ W3 ⊕ W1
Since  is the symbol for the EXCLUSIVE OR (XOR) operation, you need to perform an XOR on those 4 words of the message schedule.

This set of instructions is performed for all 80 words in the message block (word #0 through word #79)
jr. member
Activity: 44
Merit: 12
Hi everyone I have recently gotten into trying to understand the math behind Bitcoin and cryptography.
Right now I am concentrating on the SHA-256 process mostly using http://www.righto.com/2014/09/mining-bitcoin-with-pencil-and-paper.html & https://en.wikipedia.org/wiki/SHA-2#Pseudocode & https://csrc.nist.gov/csrc/media/publications/fips/180/4/final/documents/fips180-4-draft-aug2014.pdf as a starting point

I have trouble understanding the following:
Where does the Wt value comes from, how to calculate it and how it relates to the previous block. I cannot understand the origin of this value at all.


Thank you

Edit:

Basically I am trying to understand this:

Wt =

Mt (i) for ≤ t ≤ 15

ROTL1 (Wt−3 ⊕Wt−8 ⊕Wt−14 ⊕Wt−16 ) for 16 ≤ t ≤ 79
Jump to: