UNPKG

mima-kit

Version:

mima-kit is a cryptographic suite implemented in TypeScript. The goal is to provide an easy-to-use cryptographic library. mima-kit 是一个使用 TypeScript 实现的密码学套件。目标是提供一个简单易用的密码学库。

96 lines (95 loc) 2.87 kB
import { createHash } from '../core/hash'; import { U8, rotateL32 } from '../core/utils'; // * Constants function K(t) { if (t < 20) return 0x5A827999; if (t < 40) return 0x6ED9EBA1; if (t < 60) return 0x8F1BBCDC; return 0xCA62C1D6; } // * Function const Ch = (x, y, z) => (x & y) ^ ((~x) & z); const Parity = (x, y, z) => x ^ y ^ z; const Maj = (x, y, z) => (x & y) ^ (x & z) ^ (y & z); function ft(x, y, z, t) { if (t < 20) return Ch(x, y, z); if (t < 40) return Parity(x, y, z); if (t < 60) return Maj(x, y, z); return Parity(x, y, z); } // * Algorithm function digest(message) { // * 初始化 const state = new U8(20); const state_view = state.view(4); state_view.set(0, 0x67452301n); state_view.set(1, 0xefcdab89n); state_view.set(2, 0x98badcfen); state_view.set(3, 0x10325476n); state_view.set(4, 0xc3d2e1f0n); const m_byte = message.length; const m_bit = BigInt(m_byte) << 3n; const block_size = 64; // ceil((M_BYTE + 9) / 64) const block_total = (m_byte + 9 + 63) >> 6; // * 填充 const p = new U8(block_total * block_size); p.set(message); // appending the bit '1' to the message p[m_byte] = 0x80; // appending length const p_view = new DataView(p.buffer); p_view.setBigUint64(p.length - 8, m_bit); // * 分块处理 for (let offset = 0; offset < p.length; offset += block_size) { /** B(n) = p[offset:offset + block_size] */ // 准备状态字 const H0 = Number(state_view.get(0)); const H1 = Number(state_view.get(1)); const H2 = Number(state_view.get(2)); const H3 = Number(state_view.get(3)); const H4 = Number(state_view.get(4)); let a = H0; let b = H1; let c = H2; let d = H3; let e = H4; // 合并执行 扩展 & 压缩 const W = new Uint32Array(80); for (let i = 0; i < 80; i++) { // 扩展 if (i < 16) // W[i] = B(n)[i] W[i] = p_view.getUint32(offset + (i << 2)); else W[i] = rotateL32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); // 压缩 const T = rotateL32(a, 5) + ft(b, c, d, i) + K(i) + e + W[i]; e = d; d = c; c = rotateL32(b, 30); b = a; a = T; } // 更新状态字 state_view.set(0, BigInt(H0 + a)); state_view.set(1, BigInt(H1 + b)); state_view.set(2, BigInt(H2 + c)); state_view.set(3, BigInt(H3 + d)); state_view.set(4, BigInt(H4 + e)); } // * 返回状态 return state; } export const sha1 = createHash(digest, { ALGORITHM: 'SHA-1', BLOCK_SIZE: 64, DIGEST_SIZE: 20, OID: '1.3.14.3.2.26', });