// See file LICENSE for more information. library impl.digest.sm3; import 'dart:typed_data'; import 'package:pointycastle/api.dart'; import 'package:pointycastle/src/impl/md4_family_digest.dart'; import 'package:pointycastle/src/registry/registry.dart'; import 'package:pointycastle/src/ufixnum.dart'; /// Implementation of Chinese SM3 Hash Function (GM/T 0004-2012) as /// described at [Reference 1][REF1] and at [Reference 2][REF2]. /// /// 这是一个依据 [参考文献1][REF1] 和 [参考文献2][REF2] 的 SM3 哈希函数的实现. /// /// [REF1]: http://www.sca.gov.cn/sca/xwdt/2010-12/17/content_1002389.shtml /// [REF2]: https://tools.ietf.org/html/draft-shen-sm3-hash class SM3Digest extends MD4FamilyDigest implements Digest { static final FactoryConfig factoryConfig = StaticFactoryConfig(Digest, 'SM3', () => SM3Digest()); static const _DIGEST_LENGTH = 32; final List _W; SM3Digest() : _W = List.filled(68, 0, growable: false), super(Endian.big, 8, 16); @override final algorithmName = 'SM3'; @override final digestSize = _DIGEST_LENGTH; @override void resetState() { state[0] = 0x7380166f; state[1] = 0x4914b2b9; state[2] = 0x172442d7; state[3] = 0xda8a0600; state[4] = 0xa96f30bc; state[5] = 0x163138aa; state[6] = 0xe38dee4d; state[7] = 0xb0fb0e4e; } @override void processBlock() { int i; // [REF1] 5.3.2 消息扩展 // [REF2] 3.3.2 Message Extension _W.setAll(0, buffer); for (i = 16; i < 68; ++i) { _W[i] = _P1(_W[i - 16] ^ _W[i - 9] ^ rotl32(_W[i - 3], 15)) ^ rotl32(_W[i - 13], 7) ^ _W[i - 6]; } // [REF1] 5.3.3 压缩函数 // [REF2] 3.3.3 Compression Function var A = state[0]; var B = state[1]; var C = state[2]; var D = state[3]; var E = state[4]; var F = state[5]; var G = state[6]; var H = state[7]; int SS1, SS2, TT1, TT2, Tj; for (i = 0; i < 16; ++i) { Tj = 0x79cc4519; SS1 = rotl32(clip32(rotl32(A, 12) + E + rotl32(Tj, i)), 7); SS2 = SS1 ^ rotl32(A, 12); TT1 = clip32(_FF1(A, B, C) + D + SS2 + (_W[i] ^ _W[i + 4])); TT2 = clip32(_GG1(E, F, G) + H + SS1 + _W[i]); D = C; C = rotl32(B, 9); B = A; A = TT1; H = G; G = rotl32(F, 19); F = E; E = _P0(TT2); } for (i = 16; i < 64; ++i) { Tj = 0x7a879d8a; SS1 = rotl32(clip32(rotl32(A, 12) + E + rotl32(Tj, i)), 7); SS2 = SS1 ^ rotl32(A, 12); TT1 = clip32(_FF2(A, B, C) + D + SS2 + (_W[i] ^ _W[i + 4])); TT2 = clip32(_GG2(E, F, G) + H + SS1 + _W[i]); D = C; C = rotl32(B, 9); B = A; A = TT1; H = G; G = rotl32(F, 19); F = E; E = _P0(TT2); } state[0] ^= A; state[1] ^= B; state[2] ^= C; state[3] ^= D; state[4] ^= E; state[5] ^= F; state[6] ^= G; state[7] ^= H; } /// FF1 Function static int _FF1(int X, int Y, int Z) => X ^ Y ^ Z; /// FF2 Function static int _FF2(int X, int Y, int Z) => (X & Y) | (X & Z) | (Y & Z); /// GG1 Function static final _GG1 = _FF1; /// GG2 Function static int _GG2(int X, int Y, int Z) => (X & Y) | ((~X) & Z); /// P0 Function static int _P0(int X) => X ^ rotl32(X, 9) ^ rotl32(X, 17); /// P1 Function static int _P1(int X) => X ^ rotl32(X, 15) ^ rotl32(X, 23); @override int get byteLength => 64; }