文章首发链接:rbtblog.com/posts/SHA256算法的C语言实现
文章目录
作者: Robert1037
代码仓库:
github.com/Robert1037/Crypto-in-C/tree/master/sha-256
gitee.com/robert1037/Crypto-in-C/tree/master/sha-256
程序发行:
github.com/Robert1037/Crypto-in-C/releases/tag/sha-256_v2.1_little-endian
gitee.com/robert1037/Crypto-in-C/releases/tag/sha-256_v2.1_little-endian
简介
什么是SHA算法?这是 安全散列标准 (SHS) 的官方定义/解释:
This Standard specifies secure hash algorithms, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224 and SHA-512/256. All of the algorithms are iterative, one-way hash functions that can process a message to produce a condensed representation called a message digest. These algorithms enable the determination of a message’s integrity: any change to the message will, with a very high probability, result in a different message digest. This property is useful in the generation and verification of digital signatures and message authentication codes, and in the generation of random numbers or bits.
Each algorithm can be described in two stages: preprocessing and hash computation. Preprocessing involves padding a message, parsing the padded message into m-bit blocks, and setting initialization values to be used in the hash computation. The hash computation generates a message schedule from the padded message and uses that schedule, along with functions, constants, and word operations to iteratively generate a series of hash values. The final hash value generated by the hash computation is used to determine the message digest.
大致翻译:
本标准指定了一些安全散列算法:SHA-1、SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224 和 SHA-512/256。所有这些算法都是迭代、单向的散列函数,可以处理消息生成一个消息摘要。这些算法能够确定消息的完整性:对消息的任何修改都将极大概率地导致最后生成一个不同的消息摘要。该特性可用于数字签名和消息认证码的生成和验证,以及随机数或随机比特序列的生成。
每个算法都可以被描述为两个步骤:预处理和散列值计算。预处理包括填充消息、把填充后的消息解析为多个m比特的块、以及设置被用于散列值计算的初始值。散列值的计算是联合利用填充好的消息、函数、常数和字处理操作来迭代地生成一系列的散列值。最终的散列值就是所求的消息摘要。
算法
阅读 安全散列标准 (SHS) 的以下章节:
2
3
4.1.2
4.2.2
5.1.1
5.2.1
5.3.3
6.2
或者阅读 RFC 6234: 美国安全散列算法
代码实现及其特性
sha256fast.c 和 sha256min.c 是 sha256full.c 的分支,即 sha256full.c
是最初版本,但是 sha256full.c
和 sha256fast.c
在代码上都经过了一些优化,所以可能会较难读懂,因此建议先看 sha256min.c
。
这是三版代码的功能特性对照:
功能/特性 | sha256full.c | sha256fast.c | sha256min.c |
---|---|---|---|
计时器 | 有 (3个时间) | 有 (1个时间) | 无 |
提示信息 | 有 (详细) | 有 (简略) | 无 |
可多次输入 | 是 | 否 | 否 |
计算字符串的散列值 | 是 | 是 (包括空字符串) | 否 |
计算文件的散列值 | 是 | 是 | 是 |
代码中循环体展开 | 是 (1次) | 是 (18次) | 否 |
详细言之,即 sha256full.c
和 sha256fast.c
都可在屏幕显示程序运行所需的时间,其中前者可显示读取文件并进行预处理的时间、计算散列值的时间、总共花费的时间,后者只显示一个总共花费的时间。
sha256full.c
的程序在等待用户输入时会有详细的提示信息,指导用户如何正确输入,并提示被求散列值的文件大小的范围,另外如果程序读取文件失败或内存分配出错,都会显示报错信息。 sha256fast.c
的程序则只会显示一条等待输入的提示信息和文件不存在时的提示信息。sha256min.c
的程序使用方式为命令行,整个运行过程不显示任何提示信息。
sha256full.c
的程序支持一次运行多次输入并计算,直到用户不输入消息直接按下 回车键
才结束进程,适合需要计算多个文件的散列值的场景。 sha256fast.c
和 sha256min.c
的程序一次运行均只能输入一次消息。
sha256full.c
和 sha256fast.c
的程序都首先默认用户输入的消息是本地文件名,优先对指定路径存在的文件计算散列值。若文件不存在,则提示文件不存在并转而计算用户所输入字符串的散列值。 sha256min.c
的程序使用命令行运行,以程序参数的方式接收文件名的输入,若文件存在且计算成功则输出一行最终结果,其它任何情况均不输出任何结果。
总而言之, sha256full.c
的程序提示信息最完善、功能相对最强大、计算速度较快(中等)。 sha256fast.c
的代码优化级别相对最高(展开循环18次),计算速度相对最快。 sha256min.c
的程序体积相对最小,计算速度相对最慢,但对于1GB以内的文件其计算速度与最快版程序差别很小(可能大概1至2秒或1秒以内),不影响使用体验。因此本人推荐可将 sha256fast
程序添加进用户路径或系统路径作为日常使用,其运行速度可与操作系统自带的sha256散列计算命令行工具不相上下,使用体验上则由于计时功能的存在而似乎更胜一筹。
以下展示 sha256min.c
的代码:
/**
* MIT License
* Copyright (c) 2023 Robert1037
* sha256min.c v2.1 little-endian
* Last modified: 2023-01-21
**/
#include <stdio.h>
#include <stdlib.h>
#define M_LEN 64 //each M block is 512 bits == 64 bytes
#define Rn(X, n) ((X << (32 - n)) | (X >> n))
#define Sn(X, n) (X >> n)
#define Ch(X, Y, Z) ((X & Y) ^ (~X & Z))
#define Maj(X, Y, Z) ((X & Y) ^ (X & Z) ^ (Y & Z))
#define Sigma_E0(X) (Rn(X, 2) ^ Rn(X, 13) ^ Rn(X, 22)) //Σ0(X) = R2(X) ⊕ R13(X) ⊕ R22(X)
#define Sigma_E1(X) (Rn(X, 6) ^ Rn(X, 11) ^ Rn(X, 25)) //Σ1(X) = R6(X) ⊕ R11(X) ⊕ R25(X)
#define Sigma_o0(X) (Rn(X, 7) ^ Rn(X, 18) ^ Sn(X, 3)) //σ0(X) = R7(X) ⊕ R18(X) ⊕ S3(X)
#define Sigma_o1(X) (Rn(X, 17) ^ Rn(X, 19) ^ Sn(X, 10)) //σ1(X) = R17(X) ⊕ R19(X) ⊕ S10(X)
int main(int argc, char **argv)
{
FILE *fp = fopen(argv[1], "rb");
if (!fp)
return 0;
unsigned int 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
};
register unsigned int *Kp, *W, *M, a, b, c, d, e, f, g, h, T1,
H0 = 0x6a09e667, H1 = 0xbb67ae85, H2 = 0x3c6ef372, H3 = 0xa54ff53a,
H4 = 0x510e527f, H5 = 0x9b05688c, H6 = 0x1f83d9ab, H7 = 0x5be0cd19;
register char *chp, *ch, tmp;
fseek(fp, 0, SEEK_END);
a = ftell(fp);
b = a & 63; // a % 64;
b = a + ((b < 56) ? (M_LEN - b) : (M_LEN | (M_LEN - b)));
if (!(ch = (char*)calloc(b + 256, 1))) // 256 == 64 * sizeof(int), it's for W.
return 0;
rewind(fp);
if (fread(ch, 1, a, fp) != a)
return 0;
fclose(fp);
ch[a] = 0x80;
chp = ch + b - 12;
do {
tmp = chp[0]; chp[0] = chp[3]; chp[3] = tmp;
tmp = chp[1]; chp[1] = chp[2]; chp[2] = tmp;
chp -= 4;
} while (ch <= chp);
M = (unsigned int*)ch;
b >>= 2;
W = M + b;
W[-2] = a >> 29;
W[-1] = a << 3;
do { // 1 -> N blocks of M
a = H0; b = H1; c = H2; d = H3;
e = H4; f = H5; g = H6; h = H7;
Kp = W + 16;
do { // j : 0 -> 15
*W = *M;
W++; M++;
} while (Kp != W);
Kp += 48;
do { // j : 16 -> 63
*W = Sigma_o1(W[-2]) + W[-7] + Sigma_o0(W[-15]) + W[-16];
W++;
} while (Kp != W);
Kp = K; W -= 64;
do {
T1 = h + Sigma_E1(e) + Ch(e, f, g) + *W + *Kp; //T1 ← h + Σ1(e) + Ch(e, f, g) + Wj + Kj
h = g; g = f; f = e; e = d + T1;
d = c; c = b; b = a; a = T1 + Sigma_E0(b) + Maj(b, c, d); //T2 ← Σ0(a) + Maj(a, b, c)
W++; Kp++;
} while (Kp <= &K[63]);
H0 += a; H1 += b; H2 += c; H3 += d;
H4 += e; H5 += f; H6 += g; H7 += h;
W -= 64;
} while (M != W);
printf("%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x\n", H0, H1, H2, H3, H4, H5, H6, H7);
return 0;
}
下载
Windows系统
64位
win10_x64
sha256full_win10_x64.exe github sourceforge
sha256fast_win10_x64.exe github sourceforge
sha256min_win10_x64.exe github sourceforge
操作系统
- Windows 10
- Windows 11
CPU
- Intel x64 (x86_64, amd64)
- AMD x64 (x86_64, amd64)
编译工具信息
Microsoft Windows 10
x64-based PC
GNU Make 4.2.1
Built for x86_64-w64-mingw32
gcc version 12.2.0 (x86_64-posix-seh-rev2, Built by MinGW-W64 project)
Using built-in specs.
COLLECT_GCC=D:\mingw64\bin\gcc.exe
COLLECT_LTO_WRAPPER=D:/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/12.2.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-12.2.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw-builds/ucrt64-seh-posix/x86_64-1220-posix-seh-ucrt-rt_v10-rev2/mingw64 --enable-hot
-shared --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --enable-libstdcxx-filesystem-ts=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw-builds/ucrt64-seh-posix/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw-builds/ucrt64-seh-posix/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw-builds/ucrt64-seh-posix/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw-builds/ucrt64-seh-posix/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev2, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw-builds/ucrt64-seh-posix/x86_64-1220-posix-seh-ucrt-rt_v10-rev2/mingw64/opt/include -I/c/mingw-builds/ucrt64-seh-posix/prerequisites/x86_64-zlib-static/include -I/c/mingw-builds/ucrt64-seh-posix/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw-builds/ucrt64-seh-posix/x86_64-1220-posix-seh-ucrt-rt_v10-rev2/mingw64/opt/include -I/c/mingw-builds/ucrt64-seh-posix/prerequisites/x86_64-zlib-static/include -I/c/mingw-builds/ucrt64-seh-posix/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw-builds/ucrt64-seh-posix/x86_64-1220-posix-seh-ucrt-rt_v10-rev2/mingw64/opt/include -I/c/mingw-builds/ucrt64-seh-posix/prerequisites/x86_64-zlib-static/include -I/c/mingw-builds/ucrt64-seh-posix/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw-builds/ucrt64-seh-posix/x86_64-1220-posix-seh-ucrt-rt_v10-rev2/mingw64/opt/lib -L/c/mingw-builds/ucrt64-seh-posix/prerequisites/x86_64-zlib-static/lib -L/c/mingw-builds/ucrt64-seh-posix/prerequisites/x86_64-w64-mingw32-static/lib ' LD_FOR_TARGET=/c/mingw-builds/ucrt64-seh-posix/x86_64-1220-posix-seh-ucrt-rt_v10-rev2/mingw64/bin/ld.exe --with-boot-ldflags=' -Wl,--disable-dynamicbase -static-libstdc++ -static-libgcc'
Thread model: posix
Supported LTO compression algorithms: zlib
Linux系统
64位
deb11_x64
sha256full_deb11_x64 github sourceforge
sha256fast_deb11_x64 github sourceforge
sha256min_deb11_x64 github sourceforge
操作系统
- Debian 11 (bullseye) amd64
- Debian 12 (bookworm) amd64
- Ubuntu 20.04 (focal) amd64
- Ubuntu 22.04 (jammy) amd64
CPU
- Intel x64 (x86_64, amd64)
- AMD x64 (x86_64, amd64)
编译工具信息
Debian GNU/Linux 11 (bullseye)
Linux version 5.10.0-18-cloud-amd64
GNU Make 4.3
Built for x86_64-pc-linux-gnu
gcc version 10.2.1 20210110 (Debian 10.2.1-6)
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 10.2.1-6' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-Km9U7s/gcc-10-10.2.1/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-10-Km9U7s/gcc-10-10.2.1/debian/tmp-gcn/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex
Thread model: posix
Supported LTO compression algorithms: zlib zstd
rasp4b_64
sha256full_rasp4b_64 github sourceforge
sha256min_rasp4b_64 github sourceforge
操作系统
- Raspbian 11 (即 Debian 11) aarch64
- Ubuntu 20.04 (focal) aarch64
- Ubuntu 22.04 (jammy) aarch64
硬件平台
- 树莓派4B
编译工具信息
Debian GNU/Linux 11 (bullseye)
Linux version 5.15.61-v8+
GNU Make 4.3
Built for aarch64-unknown-linux-gnu
gcc version 10.2.1 20210110 (Debian 10.2.1-6)
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/aarch64-linux-gnu/10/lto-wrapper
Target: aarch64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 10.2.1-6' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=aarch64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-checking=release --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex
Thread model: posix
Supported LTO compression algorithms: zlib zstd
32位
rasp4b_32
sha256full_rasp4b_32 github sourceforge
sha256min_rasp4b_32 github sourceforge
操作系统
- Raspbian 11 armhf
- Ubuntu 20.04 (focal) armhf
- Ubuntu 22.04 (jammy) armhf
硬件平台
- 树莓派4B
编译工具信息
Raspbian GNU/Linux 11 (bullseye)
Linux version 5.15.61-v7l+
GNU Make 4.3
Built for arm-unknown-linux-gnueabihf
gcc version 10.2.1 20210110 (Raspbian 10.2.1-6+rpi1)
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/10/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Raspbian 10.2.1-6+rpi1' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=arm-linux-gnueabihf- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --disable-libquadmath-support --enable-plugin --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard --disable-werror --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
Supported LTO compression algorithms: zlib zstd
克隆代码和编译
点击链接下载打包好的源码:
source_of_sha-256_v2.1_little-endian.zip github sourceforge
source_of_sha-256_v2.1_little-endian.tar.gz github sourceforge
或者用git克隆整个仓库:
git clone https://github.com/Robert1037/Crypto-in-C.git
Windows系统
首先需要下载编译工具包 mingw: github.com/niXman/mingw-builds-binaries/releases4
编译其中一个:(例如sha256full)
> mingw32-make full
编译全部三个:(默认)
> mingw32-make
Linux系统
需要具备编译工具:gcc、 make
编译其中一个:(例如sha256full)
$ make full
编译全部三个:(默认)
$ make
使用方法
Windows系统
sha256full
-
cmd
或powershell
- 双击运行
.exe
> .\sha256full
*************** sha-256 ***************
Please input a file name.
If the file dose not exist,
the inputted string will be computed.
(string length < 960, file size < 2 GB)
(ENTER without input to quit)
:
sha256fast
-
cmd
或powershell
- 双击运行
.exe
> .\sha256fast
filename or string :
sha256min
-
cmd
或powershell
- 双击运行
.exe
> .\sha256min <文件名>
Linux系统
sha256full
$ ./sha256full
*************** sha-256 ***************
Please input a file name.
If the file dose not exist,
the inputted string will be computed.
(string length < 960, file size < 2 GB)
(ENTER without input to quit)
:
sha256fast
$ ./sha256fast
filename or string :
sha256min
$ ./sha256min <文件名>
程序测试结果截图
Windows10 x64
验证工具:
和
> certutil -hashfile <文件名> sha256
sha256full.exe
hello
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JX1Mlh1f-1674578748695)(null)]
null.txt
NIST.FIPS.180-4.pdf
..\..\test.mp4
..\..\movie.mp4
(无输入直接按回车
键)
sha256fast.exe
(无输入直接按回车
键)
hello
null.txt
NIST.FIPS.180-4.pdf
..\..\movie.mp4
sha256min.exe
(无输入直接按回车
键)
null.txt
NIST.FIPS.180-4.pdf
..\..\movie.mp4
Ubuntu20.04 x64
验证工具:
$ sha256sum <文件名>
sha256full
hello
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XmDDea85-1674578750697)(null)]
NIST.FIPS.180-4.pdf
sha256fast
(无输入直接按回车
键)
hello
NIST.FIPS.180-4.pdf
sha256min
null.txt
NIST.FIPS.180-4.pdf
Verification:
参考资料
[1] Wade Trappe, Lawrence C. Washington. Introduction to Cryptography with Coding Theory (3rd edition) [M]. Hoboken: Pearson Education, 2020: 499-521.
[2] FIPS PUB 180-4. Secure Hash Standard (SHS) [S]. dx.doi.org/10.6028/NIST.FIPS.180-4
[3] Datacruiser. 一文读懂SHA256算法原理及其实现. zhuanlan.zhihu.com/p/94619052
[4] 小Q谈移动安全. 【密码学】一文读懂SHA-2. zhuanlan.zhihu.com/p/404879837
延伸阅读
[1] Henri Gilbert, Helena Handschuh. Security Analysis of SHA-256 and Sisters. link.springer.com/content/pdf/10.1007/978-3-540-24654-1_13.pdf
[2] in3rsha. sha256-animation. github.com/in3rsha/sha256-animation