sha256Hex function
FIPS 180-4 SHA-256 over input, as lowercase hex.
Implementation
String sha256Hex(List<int> input) {
final bytes = Uint8List.fromList(input);
final bitLength = bytes.length * 8;
// Pad to a multiple of 64 bytes: 0x80, zeroes, then the 64-bit big-endian bit
// length.
final paddedLength = ((bytes.length + 9 + 63) ~/ 64) * 64;
final padded = Uint8List(paddedLength)..setRange(0, bytes.length, bytes);
padded[bytes.length] = 0x80;
final view = ByteData.view(padded.buffer);
view.setUint32(paddedLength - 8, bitLength ~/ 0x100000000, Endian.big);
view.setUint32(paddedLength - 4, bitLength & 0xffffffff, Endian.big);
final h = Uint32List.fromList(<int>[
0x6a09e667,
0xbb67ae85,
0x3c6ef372,
0xa54ff53a,
0x510e527f,
0x9b05688c,
0x1f83d9ab,
0x5be0cd19,
]);
final w = Uint32List(64);
for (var offset = 0; offset < paddedLength; offset += 64) {
for (var i = 0; i < 16; i++) {
w[i] = view.getUint32(offset + i * 4, Endian.big);
}
for (var i = 16; i < 64; i++) {
final s0 = _rotr(w[i - 15], 7) ^ _rotr(w[i - 15], 18) ^ (w[i - 15] >> 3);
final s1 = _rotr(w[i - 2], 17) ^ _rotr(w[i - 2], 19) ^ (w[i - 2] >> 10);
w[i] = (w[i - 16] + s0 + w[i - 7] + s1) & 0xffffffff;
}
var a = h[0], b = h[1], c = h[2], d = h[3];
var e = h[4], f = h[5], g = h[6], hh = h[7];
for (var i = 0; i < 64; i++) {
final s1 = _rotr(e, 6) ^ _rotr(e, 11) ^ _rotr(e, 25);
final ch = (e & f) ^ ((~e & 0xffffffff) & g);
final temp1 = (hh + s1 + ch + _k[i] + w[i]) & 0xffffffff;
final s0 = _rotr(a, 2) ^ _rotr(a, 13) ^ _rotr(a, 22);
final maj = (a & b) ^ (a & c) ^ (b & c);
final temp2 = (s0 + maj) & 0xffffffff;
hh = g;
g = f;
f = e;
e = (d + temp1) & 0xffffffff;
d = c;
c = b;
b = a;
a = (temp1 + temp2) & 0xffffffff;
}
h[0] = (h[0] + a) & 0xffffffff;
h[1] = (h[1] + b) & 0xffffffff;
h[2] = (h[2] + c) & 0xffffffff;
h[3] = (h[3] + d) & 0xffffffff;
h[4] = (h[4] + e) & 0xffffffff;
h[5] = (h[5] + f) & 0xffffffff;
h[6] = (h[6] + g) & 0xffffffff;
h[7] = (h[7] + hh) & 0xffffffff;
}
return h.map((word) => word.toRadixString(16).padLeft(8, '0')).join();
}