2021SC@SDUSC
目录
1、sha256算法
在hash.h文件中宏定义,并且在hash_impl.h中写出了函数的具体实现代码。 首先是定义了一个sha256的结构体,包括两个无符号类型数据unit32_t,和一个size_t类型。 问题1:size_t也是32位无符号数据类型,为什么不直接写成“unsigned int”呢? 答:为了程序的可扩展性, 假如将来我们需要的数据大小变成了64bit时,我们只需要将typedef long long size_t就可以了, 不然我们可要修改好多好多的地方了.
问题2:什么是big endian(大端)? 答:对于整型、长整型等数据类型,都存在字节排列的高低位顺序问题。 Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节) 而 Little endian 则相反,它认为第一个字节是最低位字节(按照从低地址到高地址的顺序存放据的低位字节到高位字节)。
接下来就是定义初始化sha256的步骤,sha256算法的8个哈希值就是自然数中的前8个质数(2,3,5,7,11,13,17,19)的平方根的小数部分取前32bit。 例如:2的开平方根的小数部分就是0.414213562373095048…换算为16进制,就是 0x6a09e667 这部分是sha256算法中用到的64个常量,是自然数中前64个质数的立方根的小数部分去前32bit而来。处理512-bit(16 个字)报文分组序列。该算法使用了六种基本逻辑函数,由64 步迭代运算组成。每步都以256-bit 缓存值ABCDEFGH 为输入,然后更新缓存内容。 每步使用一个32-bit 常数值Kt 和一个32-bit Wt。 六种运算:与、补、异或、或、循环右移n个bit、右移n个bit
这部分是信息预处理的代码,sha256算法中的预处理需要在消息后面补充需要的信息,使得整个信息满足指定的结构,分为两步,附加填充比特和附加长度。 首先把信息切成大小相等的块(64)
这部分就是把那些不完整的块补全,空的部分用0填充 这部分代码,就是上一篇博客讲到的,需要做两次sha256,为了提高安全性。
2、hmac加密算法
hmac加密算法是一种基于数据摘要算法和共享密钥的消息认证协议.它可以有效地防止数据在传输过程中被篡改,维护了数据的完整性、可靠性和安全性。 有一个key和一个需要加密的value,通过私钥进行初始化;输入的数据如果小于64位,执行mencpy进行填充,如果满足要求,则执行sha256的操作。另外,还需要对inner和outer两个变量进行初始化: secp256k1_sha256_initialize(&hash->inner); secp256k1_sha256_initialize(&hash->outer);
这个函数用来获取最后的数组,并转化位16进制,最后32位输出。
3、RFC6979(确定性签名算法)
我们使用确定性算法来代替随机数,算法返回一个合适的k值。使用确定性算法生成的随机数以非常高的概率保证其唯一。这是基于sha256抗碰撞性质提供的保证。从测试的角度说,这么做也是有好处的,同样的z和私钥具有唯一的签名结果。这使得调试和单元测试也变得容易完成。此外使用确定的k使得每次构造的交易都是相同的,因为签名没有变化。
首先介绍一下RFC6979生产k(私钥)的流程 首先我们定义:
HMAC_K(V)
1) 使用密钥(key)K对数据V进行HMAC算法。 给定输入消息m,应用以下过程: 通过哈希函数H处理m,产生: h1 = H(m)
2) V = 0x01 0x01 0x01 … 0x01 V的长度等于8 * ceil(hlen / 8)。例如,如果H是SHA-256,则V被设置为值为1的32个八位字节的序列。
3) K = 0x00 0x00 0x00 … 0x00 K的长度(以比特)等于8 * ceil(hlen / 8)。
4) K = HMAC_K(V || 0x00 || int2octets(x)|| bits2octets(h1)) ‘||’表示连接。x是私钥。
5) V = HMAC_K(V)
6) K = HMAC_K(V || 0x01 || int2octets(x)|| bits2octets(h1))
7) V = HMAC_K(V) 执行以下流程,直到找到适当的值k: 1、将T设置为空序列。 T的长度(以比特为单位)表示为tlen, 因此tlen = 0。 2、当V = HMAC_K(V);T = T || V 计算k = bits2int(T) 如果k的值在[1,q-1]范围内,那么k的生成就完了。否则,计算: K = HMAC_K(V || 0x00) V = HMAC_K(V) 并循环(尝试生成一个新的T,等等)
分析代码: 这就是产生私钥的过程,先进行初始化,再分段,分段后用0填充空白,重复两次,注意,第二次的时候不需要0填充了,因为经过第一次,这个串已经是标准化的了。
输出设置为32位 参考https://blog.csdn.net/pony_maggie/article/details/77622149的确定性签名算法介绍
|