前言
K210内置了丰富的加快器,包括神经网络处理惩罚器 (KPU),AES(高级加密加快器),APU 麦克风阵列语音数据加快计算处理惩罚器,现场可编程 IO 阵列 (FPIOA),数字摄像头接口 (DVP),相对于软件可以极大的进步 AES 运算速率,快速傅里叶变更加快器 (FFT),安全散列算法加快器 (SHA256)。
本文先容安全散列算法加快器 (SHA256);
一、什么是SHA256?
说到SHA256就不得不说SHA-2,因为SHA256是SHA-2的子集,SHA-256是当今最常用的SHA2变体之一,因为它具有很高的安全性和性能;
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;
SHA-256在当今的加密实现中被广泛利用,例如:
数据完整性 - 利用SHA-256哈希验证软件更新、取证数据、备份等,以确保有用性和防止篡改。
数字签名 - 可以对消息的哈希进行加密,以创建一个验证发送者身份的签名。SHA-256在这方面被广泛利用。
用户凭据 - 在安全存储之前,暗码和其他敏感凭据会经过雷同SHA-256的算法进行加盐和哈希处理惩罚。
区块链 - 交易通过哈希链接在一起,以维护一个不可变的账本。比特币和其他加密货币利用SHA-256。
随机数天生 - SHA-256具有强大的单向特性,适用于天生随机位。
SHA-256云云普遍利用是因为它提供了速率、安全性和易于实现的适当平衡,满足了各种应用的需求。
SHA-256的一些关键特性:
为差别长度的输入产生唯一的固定大小的256位散列。
相同哈希的两个差别输入碰撞的可能性非常小。
输入的任何变革都会导致完全差别的散列。
不可逆的哈希过程无法恢复原始数据。
计划成纵然对于大量数据也能计算得非常快。
这使得SHA-256在验证系统中的数据完整性和真实性方面非常抱负。
实验原理
将算法按照将常量的初始化、信息预处理惩罚、逻辑运算三部分进行先容
常量初始化
SHA256算法中用到了8个哈希初值以及64个哈希常量
此中,SHA256算法的8个哈希初值如下:
- h0 := 0x6a09e667
- h1 := 0xbb67ae85
- h2 := 0x3c6ef372
- h3 := 0xa54ff53a
- h4 := 0x510e527f
- h5 := 0x9b05688c
- h6 := 0x1f83d9ab
- h7 := 0x5be0cd19
复制代码 这些初值是对天然数中前8个质数(2,3,5,7,11,13,17,19)的平方根的小数部分取前32bit而来
举个例子来说,$ \sqrt{2} $小数部分约为0.414213562373095048,而
于是,质数2的平方根的小数部分取前32bit就对应出了0x6a09e667
在SHA256算法中,用到的64个常量如下:
- 428a2f98 71374491 b5c0fbcf e9b5dba5
- 3956c25b 59f111f1 923f82a4 ab1c5ed5
- d807aa98 12835b01 243185be 550c7dc3
- 72be5d74 80deb1fe 9bdc06a7 c19bf174
- e49b69c1 efbe4786 0fc19dc6 240ca1cc
- 2de92c6f 4a7484aa 5cb0a9dc 76f988da
- 983e5152 a831c66d b00327c8 bf597fc7
- c6e00bf3 d5a79147 06ca6351 14292967
- 27b70a85 2e1b2138 4d2c6dfc 53380d13
- 650a7354 766a0abb 81c2c92e 92722c85
- a2bfe8a1 a81a664b c24b8b70 c76c51a3
- d192e819 d6990624 f40e3585 106aa070
- 19a4c116 1e376c08 2748774c 34b0bcb5
- 391c0cb3 4ed8aa4a 5b9cca4f 682e6ff3
- 748f82ee 78a5636f 84c87814 8cc70208
- 90befffa a4506ceb bef9a3f7 c67178f2
复制代码 和8个哈希初值雷同,这些常量是对天然数中前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…)的立方根的小数部分取前32bit而来。
信息预处理惩罚
SHA256算法中的预处理惩罚就是在想要Hash的消息后面补充需要的信息,使整个消息满足指定的结构。
信息的预处理惩罚分为两个步调:附加填充比特和附加长度
STEP1:附加填充比特
在报文末端进行填充,使报文长度在对512取模以后的余数是448
填充是如许进行的:先补第一个比特为1,然后都补0,直到长度满足对512取模后余数是448。
需要注意的是,信息必须进行填充,也就是说,纵然长度已经满足对512取模后余数是448,补位也必须要进行,这时要填充512个比特。
因此,填充是至少补一位,最多补512位。
例:以信息“abc”为例显示补位的过程。
a,b,c对应的ASCII码分别是97,98,99
于是原始信息的二进制编码为:01100001 01100010 01100011
补位第一步,首先补一个“1” : 0110000101100010 01100011 1
补位第二步,补423个“0”:01100001 01100010 01100011 10000000 00000000 … 00000000
补位完成后的数据如下(为了简介用16进制表示):
- 61626380 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000
- 00000000 00000000
复制代码 为什么是448?
因为在第一步的预处理惩罚后,第二步会再附加上一个64bit的数据,用来表示原始报文的长度信息。而448+64=512,正好拼成了一个完整的结构。
STEP2:附加长度值
附加长度值就是将原始数据(第一步填充前的消息)的长度信息补到已经进行了填充利用的消息后面。
wiki百科中给出的原文是:append length of message (before pre-processing), in bits, as 64-bit big-endian integer
SHA256用一个64位的数据来表示原始消息的长度。
因此,通过SHA256计算的消息长度必须要小于$ 2^64 $,固然绝大多数情况这足够大了。
长度信息的编码方式为64-bit big-endian integer
关于Big endian的寄义,文末给出了补充
回到刚刚的例子,消息“abc”,3个字符,占用24个bit
因此,在进行了补长度的利用以后,整个消息就酿成下面如许了(16进制格式)
- 61626380 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000000
- 00000000 00000000
- 00000000 00000018
复制代码 逻辑运算
SHA256散列函数中涉及的利用全部是逻辑的位运算
包括如下的逻辑函数:
此中:
如今来先容SHA256算法的主体部分,即消息摘要是如何计算的。
首先:将消息分解成512-bit大小的块(break message into 512-bit chunks)
假设数据D可以被分解为n个块,于是整个算法需要做的就是完成n次迭代,n次迭代的结果就是最终的哈希值,即256bit的数字摘要。
一个256-bit的摘要的初始值H0,经过第一个数据块进行运算,得到H1,即完成了第一次迭代,H1经过第二个数据块得到H2,……,依次处理惩罚,最后得到Hn,Hn即为最终的256-bit消息摘要。
将每次迭代进行的映射用$ Map(H_{i-1}) = H_{i} $表示,于是迭代可以更形象的展示为:
图中256-bit的Hi被描述8个小块,这是因为SHA256算法中的最小运算单元称为“字”(Word),一个字是32位。
此外,第一次迭代中,映射的初值设置为前面先容的8个哈希初值,如下图所示:
下面开始先容每一次迭代的内容,即映射$ Map(H_{i-1}) = H_{i} $的详细算法。
STEP1:构造64个字(word)
对于每一块,将块分解为16个32-bit的big-endian的字,记为w[0], …, w[15]
也就是说,前16个字直接由消息的第i个块分解得到
别的的字由如下迭代公式得到:
STEP2:进行64次循环
映射 $ Map(H_{i-1}) = H_{i} $ 包罗了64次加密循环
即进行64次加密循环即可完成一次迭代
每次加密循环可以由下图描述:
图中,ABCDEFGH这8个字(word)在按照一定的规则进行更新,此中
深蓝色方块是事先界说好的非线性逻辑函数,上文已经做过铺垫
红色田字方块代表 mod $ 2^{32} $ addition,即将两个数字加在一起,假如结果大于$ 2^{32} , 你 必 须 除 以 ,你必须除以,你必须除以 2^{32} $并找到余数。
ABCDEFGH一开始的初始值分别为$ H_{i-1}(0),H_{i-1}(1),…,H_{i-1}(7) $
Kt是第t个密钥,对应我们上文提到的64个常量
Wt是本区块产生第t个word。原消息被切成固定长度512-bit的区块,对每一个区块,产生64个word,通过重复运行循环n次对ABCDEFGH这八个字循环加密。
最后一次循环所产生的八个字合起来即是第i个块对应到的散列字符串$ H_{i} $
二、K210的安全散列算法加快器
SHA256 加快器是用来计算 SHA-256 的计算单元:
• 支持 SHA-256 的计算
• 支持输入数据的 DMA 传输
对应的头文件 sha256.h
支持 SHA-256 的计算。
为用户提供以下接口:
• sha256_init:初始化SHA256加快器外设。
• sha256_update:传入一个数据块参与SHA256 Hash计算。
• sha256_final:竣事对数据的SHA256 Hash 计算。
• sha256_hard_calculate:一次性对一连的数据计算它的SHA256 Hash。
三、实验过程
原理很复杂,但是K210内置了算法模块,我们只需要简朴的调用这些接口就可以快速实现,如下实验,事先通过https://hash.online-convert.com/sha256-generator 计算好对应的字符串的哈希值,然后调用内置算法,将两者的结果进行比对,假如一致则测试通过
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <encoding.h>
- #include "sha256.h"
- #include "sleep.h"
- #include "sysctl.h"
- uint8_t hash[SHA256_HASH_LEN];
- uint8_t compare1[] = {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
- 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
- uint8_t compare2[] = {0x58, 0xbe, 0xb6, 0xbb, 0x9b, 0x80, 0xb2, 0x12, 0xc3, 0xdb, 0xc1, 0xc1, 0x02, 0x0c, 0x69, 0x6f,
- 0xbf, 0xa3, 0xaa, 0xd8, 0xe8, 0xa4, 0xef, 0x4d, 0x38, 0x5e, 0x9b, 0x07, 0x32, 0xfc, 0x5d, 0x98};
- uint8_t compare3[] = {0x6e, 0x65, 0xda, 0xd1, 0x7a, 0xa2, 0x3e, 0x72, 0x79, 0x8d, 0x50, 0x33, 0xa1, 0xae, 0xe5, 0x9e,
- 0xe3, 0x35, 0x2d, 0x3c, 0x49, 0x6c, 0x18, 0xfb, 0x71, 0xe3, 0xa5, 0x37, 0x22, 0x11, 0xfc, 0x6c};
- uint8_t compare4[] = {0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67,
- 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e, 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0};
- uint8_t data_buf[1000*1000];
- int main(void)
- {
- uint64_t cycle;
- uint8_t total_check_tag = 0;
-
- uint32_t i;
- printf("\n");
- cycle = read_cycle();
- sha256_hard_calculate((uint8_t *)"abc", 3, hash);
- for (i = 0; i < SHA256_HASH_LEN;)
- {
- if (hash[i] != compare1[i])
- total_check_tag = 1;
- printf("%02x", hash[i++]);
- if (!(i % 4))
- printf(" ");
- }
- printf("\n");
- sha256_hard_calculate((uint8_t *)"abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij", 60, hash);
- for (i = 0; i < SHA256_HASH_LEN;)
- {
- if (hash[i] != compare2[i])
- total_check_tag = 1;
- printf("%02x", hash[i++]);
- if (!(i % 4))
- printf(" ");
- }
- printf("\n");
-
- sha256_hard_calculate((uint8_t *)"abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgha", 65, hash);
- for (i = 0; i < SHA256_HASH_LEN;)
- {
- if (hash[i] != compare3[i])
- total_check_tag = 1;
- printf("%02x", hash[i++]);
- if (!(i % 4))
- printf(" ");
- }
- printf("\n");
-
- memset(data_buf, 'a', sizeof(data_buf));
- sha256_hard_calculate(data_buf, sizeof(data_buf), hash);
- for (i = 0; i < SHA256_HASH_LEN;)
- {
- if (hash[i] != compare4[i])
- total_check_tag = 1;
- printf("%02x", hash[i++]);
- if (!(i % 4))
- printf(" ");
- }
- printf("\n");
- sha256_context_t context;
- sha256_init(&context, sizeof(data_buf));
- sha256_update(&context, data_buf, 1111);
- sha256_update(&context, data_buf + 1111, sizeof(data_buf) - 1111);
- sha256_final(&context, hash);
- for (i = 0; i < SHA256_HASH_LEN;)
- {
- if (hash[i] != compare4[i])
- total_check_tag = 1;
- printf("%02x", hash[i++]);
- if (!(i % 4))
- printf(" ");
- }
- printf("\n");
- cycle = read_cycle() - cycle;
- if (total_check_tag == 1)
- printf("\nSHA256_TEST _TEST_FAIL_\n");
- else
- printf("\nSHA256_TEST _TEST_PASS_\n");
- printf("\nsha256 test time = %ld ms\n", cycle/(sysctl_clock_get_freq(SYSCTL_CLOCK_CPU)/1000));
- while(1);
- return 0;
- }
复制代码 完成代码后进行编译;
- cd build
- cmake .. -DPROJ=sha256 -G "MinGW Makefiles"
- make
复制代码 编译完成后,在build文件夹下会天生sha256.bin文件。
利用type-C数据线连接电脑与K210开发板,打开kflash,选择对应的设备,再将程序固件烧录到K210开发板上。
烧录后重启开发板,实验结果如下:
总结
本章学习了SHA-256算法的原理,并验证了K210内置的安全散列算法加快器模块,这使得安全散列的计算速率更快速;
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |