(function() { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; var W = []; var SM3 = C_algo.SM3 = Hasher.extend({ _doReset: function() { //this._hash = new WordArray.init([0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e]); this._hash = new WordArray.init([1937774191, 1226093241, 388252375, -628488704, -1452330820, 372324522, -477237683, -1325724082]); }, _doProcessBlock: function(M, offset) { var H = this._hash.words; var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; var e = H[4]; for (var i = 0; i < 80; i++) { if (i < 16) { W[i] = M[offset + i] | 0 } else { var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; W[i] = (n << 1) | (n >>> 31) } var t = ((a << 5) | (a >>> 27)) + e + W[i]; if (i < 20) { t += ((b & c) | (~b & d)) + 0x5a827999 } else if (i < 40) { t += (b ^ c ^ d) + 0x6ed9eba1 } else if (i < 60) { t += ((b & c) | (b & d) | (c & d)) - 0x70e44324 } else { t += (b ^ c ^ d) - 0x359d3e2a } e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t } H[0] = (H[0] + a) | 0; H[1] = (H[1] + b) | 0; H[2] = (H[2] + c) | 0; H[3] = (H[3] + d) | 0; H[4] = (H[4] + e) | 0 }, _doFinalize: function() { var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; data.sigBytes = dataWords.length * 4; this._process(); return this._hash }, clone: function() { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone } }); C.SM3 = Hasher._createHelper(SM3); C.HmacSM3 = Hasher._createHmacHelper(SM3) } ()); function SM3Digest() { this.BYTE_LENGTH = 64; this.xBuf = new Array(); this.xBufOff = 0; this.byteCount = 0; this.DIGEST_LENGTH = 32; //this.v0 = [0x7380166f,0x4914b2b9,0x172442d7,0xda8a0600,0xa96f30bc,0x163138aa,0xe38dee4d,0xb0fb0e4e]; // this.v0 = [0x7380166f, 0x4914b2b9, 0x172442d7,0xda8a0600,0xa96f30bc,0x163138aa,0xe38dee4d,0xb0fb0e4e]; // this.v0 = [0x7380166f, 0x4914b2b9, 0x172442d7, -628488704, -1452330820, 0x163138aa, -477237683, -1325724082]; this.v0 = [1937774191, 1226093241, 388252375, -628488704, -1452330820, 372324522, -477237683, -1325724082]; this.v = new Array(8); this.v_ = new Array(8); this.X0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; this.X = new Array(68); this.xOff = 0; this.T_00_15 = 0x79cc4519; this.T_16_63 = 0x7a879d8a; if (arguments.length > 0) { this.InitDigest(arguments[0]) } else { this.Init() } } SM3Digest.prototype = { Init: function() { this.xBuf = new Array(4); this.Reset() }, InitKey:function(key) { this.v0=key; this.xBuf = new Array(4); this.Reset() }, InitDigest: function(t) { this.xBuf = new Array(t.xBuf.length); Array.Copy(t.xBuf, 0, this.xBuf, 0, t.xBuf.length); this.xBufOff = t.xBufOff; this.byteCount = t.byteCount; Array.Copy(t.X, 0, this.X, 0, t.X.length); this.xOff = t.xOff; Array.Copy(t.v, 0, this.v, 0, t.v.length) }, GetDigestSize: function() { return this.DIGEST_LENGTH }, Reset: function() { this.byteCount = 0; this.xBufOff = 0; Array.Clear(this.xBuf, 0, this.xBuf.length); Array.Copy(this.v0, 0, this.v, 0, this.v0.length); this.xOff = 0; Array.Copy(this.X0, 0, this.X, 0, this.X0.length) }, GetByteLength: function() { return this.BYTE_LENGTH }, ProcessBlock: function() { var i; var ww = this.X; var ww_ = new Array(64); for (i = 16; i < 68; i++) { ww[i] = this.P1(ww[i - 16] ^ ww[i - 9] ^ (this.ROTATE(ww[i - 3], 15))) ^ (this.ROTATE(ww[i - 13], 7)) ^ ww[i - 6] } for (i = 0; i < 64; i++) { ww_[i] = ww[i] ^ ww[i + 4] } var vv = this.v; var vv_ = this.v_; Array.Copy(vv, 0, vv_, 0, this.v0.length); var SS1, SS2, TT1, TT2, aaa; for (i = 0; i < 16; i++) { aaa = this.ROTATE(vv_[0], 12); SS1 = Int32.parse(Int32.parse(aaa + vv_[4]) + this.ROTATE(this.T_00_15, i)); SS1 = this.ROTATE(SS1, 7); SS2 = SS1 ^ aaa; TT1 = Int32.parse(Int32.parse(this.FF_00_15(vv_[0], vv_[1], vv_[2]) + vv_[3]) + SS2) + ww_[i]; TT2 = Int32.parse(Int32.parse(this.GG_00_15(vv_[4], vv_[5], vv_[6]) + vv_[7]) + SS1) + ww[i]; vv_[3] = vv_[2]; vv_[2] = this.ROTATE(vv_[1], 9); vv_[1] = vv_[0]; vv_[0] = TT1; vv_[7] = vv_[6]; vv_[6] = this.ROTATE(vv_[5], 19); vv_[5] = vv_[4]; vv_[4] = this.P0(TT2) } for (i = 16; i < 64; i++) { aaa = this.ROTATE(vv_[0], 12); SS1 = Int32.parse(Int32.parse(aaa + vv_[4]) + this.ROTATE(this.T_16_63, i)); SS1 = this.ROTATE(SS1, 7); SS2 = SS1 ^ aaa; TT1 = Int32.parse(Int32.parse(this.FF_16_63(vv_[0], vv_[1], vv_[2]) + vv_[3]) + SS2) + ww_[i]; TT2 = Int32.parse(Int32.parse(this.GG_16_63(vv_[4], vv_[5], vv_[6]) + vv_[7]) + SS1) + ww[i]; vv_[3] = vv_[2]; vv_[2] = this.ROTATE(vv_[1], 9); vv_[1] = vv_[0]; vv_[0] = TT1; vv_[7] = vv_[6]; vv_[6] = this.ROTATE(vv_[5], 19); vv_[5] = vv_[4]; vv_[4] = this.P0(TT2) } for (i = 0; i < 8; i++) { vv[i] ^= Int32.parse(vv_[i]) } this.xOff = 0; Array.Copy(this.X0, 0, this.X, 0, this.X0.length) }, ProcessWord: function(in_Renamed, inOff) { var n = in_Renamed[inOff] << 24; n |= (in_Renamed[++inOff] & 0xff) << 16; n |= (in_Renamed[++inOff] & 0xff) << 8; n |= (in_Renamed[++inOff] & 0xff); this.X[this.xOff] = n; if (++this.xOff == 16) { this.ProcessBlock() } }, ProcessLength: function(bitLength) { if (this.xOff > 14) { this.ProcessBlock() } this.X[14] = (this.URShiftLong(bitLength, 32)); this.X[15] = (bitLength & (0xffffffff)) }, IntToBigEndian: function(n, bs, off) { bs[off] = Int32.parseByte(this.URShift(n, 24)); bs[++off] = Int32.parseByte(this.URShift(n, 16)); bs[++off] = Int32.parseByte(this.URShift(n, 8)); bs[++off] = Int32.parseByte(n) }, DoFinal: function(out_Renamed, outOff) { this.Finish(); for (var i = 0; i < 8; i++) { this.IntToBigEndian(this.v[i], out_Renamed, outOff + i * 4) } this.Reset(); return this.DIGEST_LENGTH }, Update: function(input) { this.xBuf[this.xBufOff++] = input; if (this.xBufOff == this.xBuf.length) { this.ProcessWord(this.xBuf, 0); this.xBufOff = 0 } this.byteCount++ }, BlockUpdate: function(input, inOff, length) { while ((this.xBufOff != 0) && (length > 0)) { this.Update(input[inOff]); inOff++; length-- } while (length > this.xBuf.length) { this.ProcessWord(input, inOff); inOff += this.xBuf.length; length -= this.xBuf.length; this.byteCount += this.xBuf.length } while (length > 0) { this.Update(input[inOff]); inOff++; length-- } }, Finish: function() { var bitLength = (this.byteCount << 3); this.Update((128)); while (this.xBufOff != 0) this.Update((0)); this.ProcessLength(bitLength); this.ProcessBlock() }, ROTATE: function(x, n) { return (x << n) | (this.URShift(x, (32 - n))) }, P0: function(X) { return ((X) ^ this.ROTATE((X), 9) ^ this.ROTATE((X), 17)) }, P1: function(X) { return ((X) ^ this.ROTATE((X), 15) ^ this.ROTATE((X), 23)) }, FF_00_15: function(X, Y, Z) { return (X ^ Y ^ Z) }, FF_16_63: function(X, Y, Z) { return ((X & Y) | (X & Z) | (Y & Z)) }, GG_00_15: function(X, Y, Z) { return (X ^ Y ^ Z) }, GG_16_63: function(X, Y, Z) { return ((X & Y) | (~X & Z)) }, URShift: function(number, bits) { if (number > Int32.maxValue || number < Int32.minValue) { number = Int32.parse(number) } if (number >= 0) { return number >> bits } else { return (number >> bits) + (2 << ~bits) } }, URShiftLong: function(number, bits) { var returnV; var big = new BigInteger(); big.fromInt(number); if (big.signum() >= 0) { returnV = big.shiftRight(bits).intValue() } else { var bigAdd = new BigInteger(); bigAdd.fromInt(2); var shiftLeftBits = ~bits; var shiftLeftNumber = ''; if (shiftLeftBits < 0) { var shiftRightBits = 64 + shiftLeftBits; for (var i = 0; i < shiftRightBits; i++) { shiftLeftNumber += '0' } var shiftLeftNumberBigAdd = new BigInteger(); shiftLeftNumberBigAdd.fromInt(number >> bits); var shiftLeftNumberBig = new BigInteger("10" + shiftLeftNumber, 2); shiftLeftNumber = shiftLeftNumberBig.toRadix(10); var r = shiftLeftNumberBig.add(shiftLeftNumberBigAdd); returnV = r.toRadix(10) } else { shiftLeftNumber = bigAdd.shiftLeft((~bits)).intValue(); returnV = (number >> bits) + shiftLeftNumber } } return returnV }, GetZ: function(g, pubKeyHex) { var userId = CryptoJS.enc.Utf8.parse("1234567812345678"); var len = userId.words.length * 4 * 8; this.Update((len >> 8 & 0x00ff)); this.Update((len & 0x00ff)); var userIdWords = this.GetWords(userId.toString()); this.BlockUpdate(userIdWords, 0, userIdWords.length); var aWords = this.GetWords(g.curve.a.toBigInteger().toRadix(16)); var bWords = this.GetWords(g.curve.b.toBigInteger().toRadix(16)); var gxWords = this.GetWords(g.getX().toBigInteger().toRadix(16)); var gyWords = this.GetWords(g.getY().toBigInteger().toRadix(16)); var pxWords = this.GetWords(pubKeyHex.substr(0, 64)); var pyWords = this.GetWords(pubKeyHex.substr(64, 64)); this.BlockUpdate(aWords, 0, aWords.length); this.BlockUpdate(bWords, 0, bWords.length); this.BlockUpdate(gxWords, 0, gxWords.length); this.BlockUpdate(gyWords, 0, gyWords.length); this.BlockUpdate(pxWords, 0, pxWords.length); this.BlockUpdate(pyWords, 0, pyWords.length); var md = new Array(this.GetDigestSize()); this.DoFinal(md, 0); return md }, GetWords: function(hexStr) { var words = []; var hexStrLength = hexStr.length; for (var i = 0; i < hexStrLength; i += 2) { words[words.length] = parseInt(hexStr.substr(i, 2), 16) } return words }, GetHex: function(arr) { var words = []; var j = 0; for (var i = 0; i < arr.length * 2; i += 2) { words[i >>> 3] |= parseInt(arr[j]) << (24 - (i % 8) * 4); j++ } var wordArray = new CryptoJS.lib.WordArray.init(words, arr.length); return wordArray } }; Array.Clear = function(destinationArray, destinationIndex, length) { for (elm in destinationArray) { destinationArray[elm] = null } }; Array.Copy = function(sourceArray, sourceIndex, destinationArray, destinationIndex, length) { var cloneArray = sourceArray.slice(sourceIndex, sourceIndex + length); for (var i = 0; i < cloneArray.length; i++) { destinationArray[destinationIndex] = cloneArray[i]; destinationIndex++ } }; window.Int32 = { minValue: -parseInt('10000000000000000000000000000000', 2), maxValue: parseInt('1111111111111111111111111111111', 2), parse: function(n) { if (n < this.minValue) { var bigInteger = new Number( - n); var bigIntegerRadix = bigInteger.toString(2); var subBigIntegerRadix = bigIntegerRadix.substr(bigIntegerRadix.length - 31, 31); var reBigIntegerRadix = ''; for (var i = 0; i < subBigIntegerRadix.length; i++) { var subBigIntegerRadixItem = subBigIntegerRadix.substr(i, 1); reBigIntegerRadix += subBigIntegerRadixItem == '0' ? '1': '0' } var result = parseInt(reBigIntegerRadix, 2); return (result + 1) } else if (n > this.maxValue) { var bigInteger = Number(n); var bigIntegerRadix = bigInteger.toString(2); var subBigIntegerRadix = bigIntegerRadix.substr(bigIntegerRadix.length - 31, 31); var reBigIntegerRadix = ''; for (var i = 0; i < subBigIntegerRadix.length; i++) { var subBigIntegerRadixItem = subBigIntegerRadix.substr(i, 1); reBigIntegerRadix += subBigIntegerRadixItem == '0' ? '1': '0' } var result = parseInt(reBigIntegerRadix, 2); return - (result + 1) } else { return n } }, parseByte: function(n) { if (n < 0) { var bigInteger = new Number( - n); var bigIntegerRadix = bigInteger.toString(2); var subBigIntegerRadix = bigIntegerRadix.substr(bigIntegerRadix.length - 8, 8); var reBigIntegerRadix = ''; for (var i = 0; i < subBigIntegerRadix.length; i++) { var subBigIntegerRadixItem = subBigIntegerRadix.substr(i, 1); reBigIntegerRadix += subBigIntegerRadixItem == '0' ? '1': '0' } var result = parseInt(reBigIntegerRadix, 2); return (result + 1) } else if (n > 255) { var bigInteger = Number(n); var bigIntegerRadix = bigInteger.toString(2); return parseInt(bigIntegerRadix.substr(bigIntegerRadix.length - 8, 8), 2) } else { return n } } };