注:简介和原理摘自维基百科SHA-256,有些难以理解的内容我把它细化了,例如Rightrotate操作。
部分内容转自:https://blog.csdn.net/u013137970/article/details/69891985/
强烈建议:使用Google浏览器打开,360浏览器感觉有问题。
SHA-2,名称来自于安全散列算法2(英语:Secure Hash Algorithm 2)的缩写,一种密码散列函数算法标准,由美国国家安全局研发,由美国国家标准与技术研究院(NIST)在2001年发布。属于SHA算法之一,是SHA-1的后继者。其下又可再分为六个不同的算法标准,包括了:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。
【步骤1】取前8个素数的平方根的小数部分的前32位,前8个素数分别为:2,3,5,7,11,13,17,19,从而得到8个32位的数分别记为:
h0 = 0x6a09e667;h1 = 0xbb67ae85;h2 = 0x3c6ef372;h3 = 0xa54ff53a;
h4 = 0x510e527f;h5 = 0x9b05688c;h6 = 0x1f83d9ab;h7 = 0x5be0cd19;
【步骤2】取前64个素数的立方根的小数部分的前32位,前64个素数分别为:2,3,5,7,11,13,17,19,
23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311.从而得到64个32位的数分别记为:
k[64] = {
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}
【步骤3】预处理原始数据
a)在原始数据的比特位数最后附加比特"1";
b)再附加n个比特"0",n满足n>=0且处理后的数据位数个数满足对512取模,余数=448位;
c)附加数据长度(原始数据位数),以位表示,作为64位大端方式(高位在前)附加在整个数据的后面。
例如:原始数据为890比特位:(10101010...11001100)
a)(10101010...11001100) 1
b)(10101010...11001100) 1 (0000...0000) 其中附加比特“0”的位数 = 448 - ((890+1)mod512))= 70
c)(10101010...11001100) 1 (0000...0000) (0000...1101111010)其中1101111010 = 890(十进制)
注:为啥(b)步骤的余数是448位,是因为要空出64位的位置放置原始数据的长度,448+64=512
【步骤4】将步骤三处理后的数据分解为N个512位的块(经过步骤三处理后,数据位数肯定是512的整数倍)
对于每一个512位数的块,分解为16个32位的W[16]寄存器中,以大端格式。
【步骤5】将这16个32位的数据扩展到64个32位的寄存器W[64]中。执行下列算法:
for(16 <= i <= 63)
{
S0 = (W[i-15] rightrotate 7) xor (W[i-15] rightrotate 18) xor (W[i-15] rightshift 3);
S1 = (W[i-2] rightrotate 17) xor (W[i-2] rightrotate 19) xor (W[i-2] rightshift 10);
W[i] = W[i-16] + S0 + W[i-7] + S1;
}
【步骤6】初始HASH变量下面的块
A = h0
B = h1
C = h2
D = h3
E = h4
F = h5
G = h6
H = h7
【步骤7】主要计算,进行64次迭代:
for(0 <= i <= 63)
{
S0 = (A rightrotate 2) xor (A rightrotate 13) xor (A rightrotate 22)
maj = (A & B) xor (A & C) xor (B & C)
t2 = S0 + maj
S1 = (E rightrotate 6) xor (E rightrotate 11) xor (E rightrotate 25)
Ch = (E & F) xor ((~E) & G)
t1 = H + S1 + Ch + k[i] + w[i]
H = G
G = F
F = E
E = D + t1
D = C
C = B
B = A
A = t1 + t2
}
【步骤8】第一个块的哈希结果
H0 = H0 + A
H1 = H1 + B
H2 = H2 + C
H3 = H3 + D
H4 = H4 + E
H5 = H5 + F
H6 = H6 + G
H7 = H7 + H
【步骤9】然后把第一个块的哈希结果作为下一个块的初始HASH变量继续计算下一个快的HASH值,重复【步骤4】,【步骤5】,【步骤6】,【步骤7】,【步骤8】直到最后一个块计算完成,得到最终256位的HASH结果。
【步骤10】产生最终结果:(大端格式,即高位在前)
Digest = Hash = {H0,H1,H2,H3,H4,H5,H6,H7};
素数,又称质数,是指一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。
右旋操作,即把一个数先向右位移n位,然后把移除的n位按照大端格式放置在该数的高位。举例如下:
1010000011110000 Rightrotate 5 //该句话的意思是把 1010000011110000 进行右旋5位
/*
具体过程是:
a)1010000011110000 向右位移5位得到0000010100000111
b)把1010000011110000数的低5位10000放置到0000010100000111的高五位
c)得到1000010100000111
*/
右移操作,即把一个数直接向右位移n位。举例如下:
1010 0000 1111 0000 Rightshift 5 //该句话的意思是把1010000011110000 向右位移5位
/*
直接得到:00000 10100000111
*/
异或操作,即两个数按位异或,如果同为1或同为0则异或后为0,否则为1。
4.1 区块头结构信息(80字节)
字节 | 字段 | 说明 |
---|---|---|
4 | 版本 | 区块版本号,表示本区块遵守的验证规则 |
32 | 父区块头哈希值 | 前一区块的哈希值,使用SHA256(SHA256(父区块头))计算 |
32 | Merkle根 | 该区块中交易的Merkle树根的哈希值,同样采用SHA256(SHA256())计算 |
4 | 时间戳 | 该区块产生的近似时间,精确到秒的UNIX时间戳,必须严格大于前11个区块时间的中值,同时全节点也会拒绝那些超出自己2个小时时间戳的区块 |
4 | 难度目标 | 该区块工作量证明算法的难度目标,已经使用特定算法编码 |
4 | Nonce | 为了找到满足难度目标所设定的随机数,为了解决32位随机数在算力飞升的情况下不够用的问题,规定时间戳和coinbase交易信息均可更改,以此扩展nonce的位数 |
4.2 SHA-256计算
工作量的证明就是寻找随机数,把上述区块头部80个字节信息,进行SHA-256运算,运算结果(256bits)再进行一次SHA-256运算等待最终结果(256bits)。该结果与目标值进行比较,如果小于则开始同步广播信息,与其它节点达成共识,或者把数据交给矿池,矿池与其它节点同步信息,你获得矿池奖励给你的一定的比特币。
【附录】
SHA-224和SHA-256基本上是相同的,除了:
h0到h7的初始值不同,以及
SHA-224输出时截掉h7的函数值。
SHA-512和SHA-256的结构相同,但:
SHA-512所有的数字都是64位,
SHA-512运行80次加密循环而非64次,
SHA-512初始值和常量拉长成64位,以及
二者比特的偏移量和循环位移量不同。
SHA-384和SHA-512基本上是相同的,除了:
h0到h7的初始值不同,以及
SHA-384输出时截掉h6和h7的函数值。