UNPKG

sm-crypto

Version:
212 lines (190 loc) 4.69 kB
/** * 循环左移 */ function rotl(x, n) { const result = [] const a = ~~(n / 8) // 偏移 a 字节 const b = n % 8 // 偏移 b 位 for (let i = 0, len = x.length; i < len; i++) { // current << b + (current + 1) >>> (8 - b) result[i] = ((x[(i + a) % len] << b) & 0xff) + ((x[(i + a + 1) % len] >>> (8 - b)) & 0xff) } return result } /** * 二进制异或运算 */ function xor(x, y) { const result = [] for (let i = x.length - 1; i >= 0; i--) result[i] = (x[i] ^ y[i]) & 0xff return result } /** * 二进制与运算 */ function and(x, y) { const result = [] for (let i = x.length - 1; i >= 0; i--) result[i] = (x[i] & y[i]) & 0xff return result } /** * 二进制或运算 */ function or(x, y) { const result = [] for (let i = x.length - 1; i >= 0; i--) result[i] = (x[i] | y[i]) & 0xff return result } /** * 二进制与运算 */ function add(x, y) { const result = [] let temp = 0 for (let i = x.length - 1; i >= 0; i--) { const sum = x[i] + y[i] + temp if (sum > 0xff) { temp = 1 result[i] = sum & 0xff } else { temp = 0 result[i] = sum & 0xff } } return result } /** * 二进制非运算 */ function not(x) { const result = [] for (let i = x.length - 1; i >= 0; i--) result[i] = (~x[i]) & 0xff return result } /** * 压缩函数中的置换函数 P1(X) = X xor (X <<< 9) xor (X <<< 17) */ function P0(X) { return xor(xor(X, rotl(X, 9)), rotl(X, 17)) } /** * 消息扩展中的置换函数 P1(X) = X xor (X <<< 15) xor (X <<< 23) */ function P1(X) { return xor(xor(X, rotl(X, 15)), rotl(X, 23)) } /** * 布尔函数 FF */ function FF(X, Y, Z, j) { return j >= 0 && j <= 15 ? xor(xor(X, Y), Z) : or(or(and(X, Y), and(X, Z)), and(Y, Z)) } /** * 布尔函数 GG */ function GG(X, Y, Z, j) { return j >= 0 && j <= 15 ? xor(xor(X, Y), Z) : or(and(X, Y), and(not(X), Z)) } /** * 压缩函数 */ function CF(V, Bi) { // 消息扩展 const W = [] const M = [] // W' // 将消息分组B划分为 16 个字 W0, W1,……,W15 for (let i = 0; i < 16; i++) { const start = i * 4 W.push(Bi.slice(start, start + 4)) } // W16 ~ W67:W[j] <- P1(W[j−16] xor W[j−9] xor (W[j−3] <<< 15)) xor (W[j−13] <<< 7) xor W[j−6] for (let j = 16; j < 68; j++) { W.push(xor( xor( P1( xor( xor(W[j - 16], W[j - 9]), rotl(W[j - 3], 15) ) ), rotl(W[j - 13], 7) ), W[j - 6] )) } // W′0 ~ W′63:W′[j] = W[j] xor W[j+4] for (let j = 0; j < 64; j++) { M.push(xor(W[j], W[j + 4])) } // 压缩 const T1 = [0x79, 0xcc, 0x45, 0x19] const T2 = [0x7a, 0x87, 0x9d, 0x8a] // 字寄存器 let A = V.slice(0, 4) let B = V.slice(4, 8) let C = V.slice(8, 12) let D = V.slice(12, 16) let E = V.slice(16, 20) let F = V.slice(20, 24) let G = V.slice(24, 28) let H = V.slice(28, 32) // 中间变量 let SS1 let SS2 let TT1 let TT2 for (let j = 0; j < 64; j++) { const T = j >= 0 && j <= 15 ? T1 : T2 SS1 = rotl(add( add(rotl(A, 12), E), rotl(T, j) ), 7) SS2 = xor(SS1, rotl(A, 12)) TT1 = add(add(add(FF(A, B, C, j), D), SS2), M[j]) TT2 = add(add(add(GG(E, F, G, j), H), SS1), W[j]) D = C C = rotl(B, 9) B = A A = TT1 H = G G = rotl(F, 19) F = E E = P0(TT2) } return xor([].concat(A, B, C, D, E, F, G, H), V) } module.exports = function (array) { // 填充 let len = array.length * 8 // k 是满足 len + 1 + k = 448mod512 的最小的非负整数 let k = len % 512 // 如果 448 <= (512 % len) < 512,需要多补充 (len % 448) 比特'0'以满足总比特长度为512的倍数 k = k >= 448 ? 512 - (k % 448) - 1 : 448 - k - 1 // 填充 const kArr = new Array((k - 7) / 8) for (let i = 0, len = kArr.length; i < len; i++) kArr[i] = 0 const lenArr = [] len = len.toString(2) for (let i = 7; i >= 0; i--) { if (len.length > 8) { const start = len.length - 8 lenArr[i] = parseInt(len.substr(start), 2) len = len.substr(0, start) } else if (len.length > 0) { lenArr[i] = parseInt(len, 2) len = '' } else { lenArr[i] = 0 } } const m = [].concat(array, [0x80], kArr, lenArr) // 迭代压缩 const n = m.length / 64 let V = [0x73, 0x80, 0x16, 0x6f, 0x49, 0x14, 0xb2, 0xb9, 0x17, 0x24, 0x42, 0xd7, 0xda, 0x8a, 0x06, 0x00, 0xa9, 0x6f, 0x30, 0xbc, 0x16, 0x31, 0x38, 0xaa, 0xe3, 0x8d, 0xee, 0x4d, 0xb0, 0xfb, 0x0e, 0x4e] for (let i = 0; i < n; i++) { const start = 64 * i const B = m.slice(start, start + 64) V = CF(V, B) } return V }