water_xcx/node_modules/miniprogram-sm-crypto/miniprogram_dist/index.js

1849 lines
49 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module.exports =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 2);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
module.exports = require("jsbn");
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* 循环左移
*/
function rotl(x, n) {
var result = [];
var a = ~~(n / 8); // 偏移 a 字节
var b = n % 8; // 偏移 b 位
for (var 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) {
var result = [];
for (var i = x.length - 1; i >= 0; i--) {
result[i] = (x[i] ^ y[i]) & 0xff;
}return result;
}
/**
* 二进制与运算
*/
function and(x, y) {
var result = [];
for (var i = x.length - 1; i >= 0; i--) {
result[i] = x[i] & y[i] & 0xff;
}return result;
}
/**
* 二进制或运算
*/
function or(x, y) {
var result = [];
for (var i = x.length - 1; i >= 0; i--) {
result[i] = (x[i] | y[i]) & 0xff;
}return result;
}
/**
* 二进制与运算
*/
function add(x, y) {
var result = [];
var temp = 0;
for (var i = x.length - 1; i >= 0; i--) {
var 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) {
var result = [];
for (var 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) {
// 消息扩展
var W = [];
var M = []; // W'
// 将消息分组B划分为 16 个字 W0 W1……W15
for (var i = 0; i < 16; i++) {
var start = i * 4;
W.push(Bi.slice(start, start + 4));
}
// W16 W67W[j] <- P1(W[j16] xor W[j9] xor (W[j3] <<< 15)) xor (W[j13] <<< 7) xor W[j6]
for (var 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]));
}
// W0 W63W[j] = W[j] xor W[j+4]
for (var _j = 0; _j < 64; _j++) {
M.push(xor(W[_j], W[_j + 4]));
}
// 压缩
var T1 = [0x79, 0xcc, 0x45, 0x19];
var T2 = [0x7a, 0x87, 0x9d, 0x8a];
// 字寄存器
var A = V.slice(0, 4);
var B = V.slice(4, 8);
var C = V.slice(8, 12);
var D = V.slice(12, 16);
var E = V.slice(16, 20);
var F = V.slice(20, 24);
var G = V.slice(24, 28);
var H = V.slice(28, 32);
// 中间变量
var SS1 = void 0;
var SS2 = void 0;
var TT1 = void 0;
var TT2 = void 0;
for (var _j2 = 0; _j2 < 64; _j2++) {
var T = _j2 >= 0 && _j2 <= 15 ? T1 : T2;
SS1 = rotl(add(add(rotl(A, 12), E), rotl(T, _j2)), 7);
SS2 = xor(SS1, rotl(A, 12));
TT1 = add(add(add(FF(A, B, C, _j2), D), SS2), M[_j2]);
TT2 = add(add(add(GG(E, F, G, _j2), H), SS1), W[_j2]);
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);
}
/**
* sm3 本体
*/
function sm3(array) {
// 填充
var len = array.length * 8;
// k 是满足 len + 1 + k = 448mod512 的最小的非负整数
var k = len % 512;
// 如果 448 <= (512 % len) < 512需要多补充 (len % 448) 比特'0'以满足总比特长度为512的倍数
k = k >= 448 ? 512 - k % 448 - 1 : 448 - k - 1;
// 填充
var kArr = new Array((k - 7) / 8);
for (var i = 0, _len = kArr.length; i < _len; i++) {
kArr[i] = 0;
}var lenArr = [];
len = len.toString(2);
for (var _i = 7; _i >= 0; _i--) {
if (len.length > 8) {
var 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;
}
}
var m = [].concat(array, [0x80], kArr, lenArr);
// 迭代压缩
var n = m.length / 64;
var 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 (var _i2 = 0; _i2 < n; _i2++) {
var _start = 64 * _i2;
var B = m.slice(_start, _start + 64);
V = CF(V, B);
}
return V;
}
/**
* hmac 实现
*/
var blockLen = 64;
var iPad = new Array(blockLen);
var oPad = new Array(blockLen);
for (var i = 0; i < blockLen; i++) {
iPad[i] = 0x36;
oPad[i] = 0x5c;
}
function hmac(input, key) {
// 密钥填充
if (key.length > blockLen) key = sm3(key);
while (key.length < blockLen) {
key.push(0);
}var iPadKey = xor(key, iPad);
var hash = iPadKey.concat(input);
hash = sm3(hash);
var oPadKey = xor(key, oPad);
hash = oPadKey.concat(hash);
hash = sm3(hash);
return hash;
}
module.exports = {
sm3: sm3,
hmac: hmac
};
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = {
sm2: __webpack_require__(3),
sm3: __webpack_require__(7),
sm4: __webpack_require__(8)
};
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* eslint-disable no-use-before-define */
var _require = __webpack_require__(0),
BigInteger = _require.BigInteger;
var _require2 = __webpack_require__(4),
encodeDer = _require2.encodeDer,
decodeDer = _require2.decodeDer;
var _ = __webpack_require__(5);
var sm3 = __webpack_require__(1).sm3;
var _$generateEcparam = _.generateEcparam(),
G = _$generateEcparam.G,
curve = _$generateEcparam.curve,
n = _$generateEcparam.n;
var C1C2C3 = 0;
/**
* 加密
*/
function doEncrypt(msg, publicKey) {
var cipherMode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
msg = typeof msg === 'string' ? _.hexToArray(_.utf8ToHex(msg)) : Array.prototype.slice.call(msg);
publicKey = _.getGlobalCurve().decodePointHex(publicKey); // 先将公钥转成点
var keypair = _.generateKeyPairHex();
var k = new BigInteger(keypair.privateKey, 16); // 随机数 k
// c1 = k * G
var c1 = keypair.publicKey;
if (c1.length > 128) c1 = c1.substr(c1.length - 128);
// (x2, y2) = k * publicKey
var p = publicKey.multiply(k);
var x2 = _.hexToArray(_.leftPad(p.getX().toBigInteger().toRadix(16), 64));
var y2 = _.hexToArray(_.leftPad(p.getY().toBigInteger().toRadix(16), 64));
// c3 = hash(x2 || msg || y2)
var c3 = _.arrayToHex(sm3([].concat(x2, msg, y2)));
var ct = 1;
var offset = 0;
var t = []; // 256 位
var z = [].concat(x2, y2);
var nextT = function nextT() {
// (1) Hai = hash(z || ct)
// (2) ct++
t = sm3([].concat(z, [ct >> 24 & 0x00ff, ct >> 16 & 0x00ff, ct >> 8 & 0x00ff, ct & 0x00ff]));
ct++;
offset = 0;
};
nextT(); // 先生成 Ha1
for (var i = 0, len = msg.length; i < len; i++) {
// t = Ha1 || Ha2 || Ha3 || Ha4
if (offset === t.length) nextT();
// c2 = msg ^ t
msg[i] ^= t[offset++] & 0xff;
}
var c2 = _.arrayToHex(msg);
return cipherMode === C1C2C3 ? c1 + c2 + c3 : c1 + c3 + c2;
}
/**
* 解密
*/
function doDecrypt(encryptData, privateKey) {
var cipherMode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
var _ref = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {},
_ref$output = _ref.output,
output = _ref$output === undefined ? 'string' : _ref$output;
privateKey = new BigInteger(privateKey, 16);
var c3 = encryptData.substr(128, 64);
var c2 = encryptData.substr(128 + 64);
if (cipherMode === C1C2C3) {
c3 = encryptData.substr(encryptData.length - 64);
c2 = encryptData.substr(128, encryptData.length - 128 - 64);
}
var msg = _.hexToArray(c2);
var c1 = _.getGlobalCurve().decodePointHex('04' + encryptData.substr(0, 128));
var p = c1.multiply(privateKey);
var x2 = _.hexToArray(_.leftPad(p.getX().toBigInteger().toRadix(16), 64));
var y2 = _.hexToArray(_.leftPad(p.getY().toBigInteger().toRadix(16), 64));
var ct = 1;
var offset = 0;
var t = []; // 256 位
var z = [].concat(x2, y2);
var nextT = function nextT() {
// (1) Hai = hash(z || ct)
// (2) ct++
t = sm3([].concat(z, [ct >> 24 & 0x00ff, ct >> 16 & 0x00ff, ct >> 8 & 0x00ff, ct & 0x00ff]));
ct++;
offset = 0;
};
nextT(); // 先生成 Ha1
for (var i = 0, len = msg.length; i < len; i++) {
// t = Ha1 || Ha2 || Ha3 || Ha4
if (offset === t.length) nextT();
// c2 = msg ^ t
msg[i] ^= t[offset++] & 0xff;
}
// c3 = hash(x2 || msg || y2)
var checkC3 = _.arrayToHex(sm3([].concat(x2, msg, y2)));
if (checkC3 === c3.toLowerCase()) {
return output === 'array' ? msg : _.arrayToUtf8(msg);
} else {
return output === 'array' ? [] : '';
}
}
/**
* 签名
*/
function doSignature(msg, privateKey) {
var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
pointPool = _ref2.pointPool,
der = _ref2.der,
hash = _ref2.hash,
publicKey = _ref2.publicKey,
userId = _ref2.userId;
var hashHex = typeof msg === 'string' ? _.utf8ToHex(msg) : _.arrayToHex(msg);
if (hash) {
// sm3杂凑
publicKey = publicKey || getPublicKeyFromPrivateKey(privateKey);
hashHex = getHash(hashHex, publicKey, userId);
}
var dA = new BigInteger(privateKey, 16);
var e = new BigInteger(hashHex, 16);
// k
var k = null;
var r = null;
var s = null;
do {
do {
var point = void 0;
if (pointPool && pointPool.length) {
point = pointPool.pop();
} else {
point = getPoint();
}
k = point.k;
// r = (e + x1) mod n
r = e.add(point.x1).mod(n);
} while (r.equals(BigInteger.ZERO) || r.add(k).equals(n));
// s = ((1 + dA)^-1 * (k - r * dA)) mod n
s = dA.add(BigInteger.ONE).modInverse(n).multiply(k.subtract(r.multiply(dA))).mod(n);
} while (s.equals(BigInteger.ZERO));
if (der) return encodeDer(r, s); // asn.1 der 编码
return _.leftPad(r.toString(16), 64) + _.leftPad(s.toString(16), 64);
}
/**
* 验签
*/
function doVerifySignature(msg, signHex, publicKey) {
var _ref3 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {},
der = _ref3.der,
hash = _ref3.hash,
userId = _ref3.userId;
var hashHex = typeof msg === 'string' ? _.utf8ToHex(msg) : _.arrayToHex(msg);
if (hash) {
// sm3杂凑
hashHex = getHash(hashHex, publicKey, userId);
}
var r = void 0;var s = void 0;
if (der) {
var decodeDerObj = decodeDer(signHex); // asn.1 der 解码
r = decodeDerObj.r;
s = decodeDerObj.s;
} else {
r = new BigInteger(signHex.substring(0, 64), 16);
s = new BigInteger(signHex.substring(64), 16);
}
var PA = curve.decodePointHex(publicKey);
var e = new BigInteger(hashHex, 16);
// t = (r + s) mod n
var t = r.add(s).mod(n);
if (t.equals(BigInteger.ZERO)) return false;
// x1y1 = s * G + t * PA
var x1y1 = G.multiply(s).add(PA.multiply(t));
// R = (e + x1) mod n
var R = e.add(x1y1.getX().toBigInteger()).mod(n);
return r.equals(R);
}
/**
* sm3杂凑算法
*/
function getHash(hashHex, publicKey) {
var userId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '1234567812345678';
// z = hash(entl || userId || a || b || gx || gy || px || py)
userId = _.utf8ToHex(userId);
var a = _.leftPad(G.curve.a.toBigInteger().toRadix(16), 64);
var b = _.leftPad(G.curve.b.toBigInteger().toRadix(16), 64);
var gx = _.leftPad(G.getX().toBigInteger().toRadix(16), 64);
var gy = _.leftPad(G.getY().toBigInteger().toRadix(16), 64);
if (publicKey.length > 128) publicKey = publicKey.substr(2, 128); // 干掉 '04'
var px = publicKey.substr(0, 64);
var py = publicKey.substr(64, 64);
var data = _.hexToArray(userId + a + b + gx + gy + px + py);
var entl = userId.length * 4;
data.unshift(entl & 0x00ff);
data.unshift(entl >> 8 & 0x00ff);
var z = sm3(data);
// e = hash(z || msg)
return _.arrayToHex(sm3(z.concat(_.hexToArray(hashHex))));
}
/**
* 计算公钥
*/
function getPublicKeyFromPrivateKey(privateKey) {
var PA = G.multiply(new BigInteger(privateKey, 16));
var x = _.leftPad(PA.getX().toBigInteger().toString(16), 64);
var y = _.leftPad(PA.getY().toBigInteger().toString(16), 64);
return '04' + x + y;
}
/**
* 获取椭圆曲线点
*/
function getPoint() {
var keypair = _.generateKeyPairHex();
var PA = curve.decodePointHex(keypair.publicKey);
keypair.k = new BigInteger(keypair.privateKey, 16);
keypair.x1 = PA.getX().toBigInteger();
return keypair;
}
module.exports = {
generateKeyPairHex: _.generateKeyPairHex,
doEncrypt: doEncrypt,
doDecrypt: doDecrypt,
doSignature: doSignature,
doVerifySignature: doVerifySignature,
getPoint: getPoint,
verifyPublicKey: _.verifyPublicKey
};
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/* eslint-disable class-methods-use-this */
var _require = __webpack_require__(0),
BigInteger = _require.BigInteger;
function bigintToValue(bigint) {
var h = bigint.toString(16);
if (h[0] !== '-') {
// 正数
if (h.length % 2 === 1) h = '0' + h; // 补齐到整字节
else if (!h.match(/^[0-7]/)) h = '00' + h; // 非0开头则补一个全0字节
} else {
// 负数
h = h.substr(1);
var len = h.length;
if (len % 2 === 1) len += 1; // 补齐到整字节
else if (!h.match(/^[0-7]/)) len += 2; // 非0开头则补一个全0字节
var mask = '';
for (var i = 0; i < len; i++) {
mask += 'f';
}mask = new BigInteger(mask, 16);
// 对绝对值取反加1
h = mask.xor(bigint).add(BigInteger.ONE);
h = h.toString(16).replace(/^-/, '');
}
return h;
}
var ASN1Object = function () {
function ASN1Object() {
_classCallCheck(this, ASN1Object);
this.tlv = null;
this.t = '00';
this.l = '00';
this.v = '';
}
/**
* 获取 der 编码比特流16进制串
*/
ASN1Object.prototype.getEncodedHex = function getEncodedHex() {
if (!this.tlv) {
this.v = this.getValue();
this.l = this.getLength();
this.tlv = this.t + this.l + this.v;
}
return this.tlv;
};
ASN1Object.prototype.getLength = function getLength() {
var n = this.v.length / 2; // 字节数
var nHex = n.toString(16);
if (nHex.length % 2 === 1) nHex = '0' + nHex; // 补齐到整字节
if (n < 128) {
// 短格式,以 0 开头
return nHex;
} else {
// 长格式,以 1 开头
var head = 128 + nHex.length / 2; // 1(1位) + 真正的长度占用字节数(7位) + 真正的长度
return head.toString(16) + nHex;
}
};
ASN1Object.prototype.getValue = function getValue() {
return '';
};
return ASN1Object;
}();
var DERInteger = function (_ASN1Object) {
_inherits(DERInteger, _ASN1Object);
function DERInteger(bigint) {
_classCallCheck(this, DERInteger);
var _this = _possibleConstructorReturn(this, _ASN1Object.call(this));
_this.t = '02'; // 整型标签说明
if (bigint) _this.v = bigintToValue(bigint);
return _this;
}
DERInteger.prototype.getValue = function getValue() {
return this.v;
};
return DERInteger;
}(ASN1Object);
var DERSequence = function (_ASN1Object2) {
_inherits(DERSequence, _ASN1Object2);
function DERSequence(asn1Array) {
_classCallCheck(this, DERSequence);
var _this2 = _possibleConstructorReturn(this, _ASN1Object2.call(this));
_this2.t = '30'; // 序列标签说明
_this2.asn1Array = asn1Array;
return _this2;
}
DERSequence.prototype.getValue = function getValue() {
this.v = this.asn1Array.map(function (asn1Object) {
return asn1Object.getEncodedHex();
}).join('');
return this.v;
};
return DERSequence;
}(ASN1Object);
/**
* 获取 l 占用字节数
*/
function getLenOfL(str, start) {
if (+str[start + 2] < 8) return 1; // l 以0开头则表示短格式只占一个字节
return +str.substr(start + 2, 2) & 0x7f + 1; // 长格式取第一个字节后7位作为长度真正占用字节数再加上本身
}
/**
* 获取 l
*/
function getL(str, start) {
// 获取 l
var len = getLenOfL(str, start);
var l = str.substr(start + 2, len * 2);
if (!l) return -1;
var bigint = +l[0] < 8 ? new BigInteger(l, 16) : new BigInteger(l.substr(2), 16);
return bigint.intValue();
}
/**
* 获取 v 的位置
*/
function getStartOfV(str, start) {
var len = getLenOfL(str, start);
return start + (len + 1) * 2;
}
module.exports = {
/**
* ASN.1 der 编码,针对 sm2 签名
*/
encodeDer: function encodeDer(r, s) {
var derR = new DERInteger(r);
var derS = new DERInteger(s);
var derSeq = new DERSequence([derR, derS]);
return derSeq.getEncodedHex();
},
/**
* 解析 ASN.1 der针对 sm2 验签
*/
decodeDer: function decodeDer(input) {
// 结构:
// input = | tSeq | lSeq | vSeq |
// vSeq = | tR | lR | vR | tS | lS | vS |
var start = getStartOfV(input, 0);
var vIndexR = getStartOfV(input, start);
var lR = getL(input, start);
var vR = input.substr(vIndexR, lR * 2);
var nextStart = vIndexR + vR.length;
var vIndexS = getStartOfV(input, nextStart);
var lS = getL(input, nextStart);
var vS = input.substr(vIndexS, lS * 2);
var r = new BigInteger(vR, 16);
var s = new BigInteger(vS, 16);
return { r: r, s: s };
}
};
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* eslint-disable no-bitwise, no-mixed-operators, no-use-before-define, max-len */
var _require = __webpack_require__(0),
BigInteger = _require.BigInteger,
SecureRandom = _require.SecureRandom;
var _require2 = __webpack_require__(6),
ECCurveFp = _require2.ECCurveFp;
var rng = new SecureRandom();
var _generateEcparam = generateEcparam(),
curve = _generateEcparam.curve,
G = _generateEcparam.G,
n = _generateEcparam.n;
/**
* 获取公共椭圆曲线
*/
function getGlobalCurve() {
return curve;
}
/**
* 生成ecparam
*/
function generateEcparam() {
// 椭圆曲线
var p = new BigInteger('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF', 16);
var a = new BigInteger('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC', 16);
var b = new BigInteger('28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', 16);
var curve = new ECCurveFp(p, a, b);
// 基点
var gxHex = '32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7';
var gyHex = 'BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0';
var G = curve.decodePointHex('04' + gxHex + gyHex);
var n = new BigInteger('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123', 16);
return { curve: curve, G: G, n: n };
}
/**
* 生成密钥对publicKey = privateKey * G
*/
function generateKeyPairHex(a, b, c) {
var random = a ? new BigInteger(a, b, c) : new BigInteger(n.bitLength(), rng);
var d = random.mod(n.subtract(BigInteger.ONE)).add(BigInteger.ONE); // 随机数
var privateKey = leftPad(d.toString(16), 64);
var P = G.multiply(d); // P = dGp 为公钥d 为私钥
var Px = leftPad(P.getX().toBigInteger().toString(16), 64);
var Py = leftPad(P.getY().toBigInteger().toString(16), 64);
var publicKey = '04' + Px + Py;
return { privateKey: privateKey, publicKey: publicKey };
}
/**
* utf8串转16进制串
*/
function utf8ToHex(input) {
input = unescape(encodeURIComponent(input));
var length = input.length;
// 转换到字数组
var words = [];
for (var i = 0; i < length; i++) {
words[i >>> 2] |= (input.charCodeAt(i) & 0xff) << 24 - i % 4 * 8;
}
// 转换到16进制
var hexChars = [];
for (var _i = 0; _i < length; _i++) {
var bite = words[_i >>> 2] >>> 24 - _i % 4 * 8 & 0xff;
hexChars.push((bite >>> 4).toString(16));
hexChars.push((bite & 0x0f).toString(16));
}
return hexChars.join('');
}
/**
* 补全16进制字符串
*/
function leftPad(input, num) {
if (input.length >= num) return input;
return new Array(num - input.length + 1).join('0') + input;
}
/**
* 转成16进制串
*/
function arrayToHex(arr) {
return arr.map(function (item) {
item = item.toString(16);
return item.length === 1 ? '0' + item : item;
}).join('');
}
/**
* 转成utf8串
*/
function arrayToUtf8(arr) {
var words = [];
var j = 0;
for (var i = 0; i < arr.length * 2; i += 2) {
words[i >>> 3] |= parseInt(arr[j], 10) << 24 - i % 8 * 4;
j++;
}
try {
var latin1Chars = [];
for (var _i2 = 0; _i2 < arr.length; _i2++) {
var bite = words[_i2 >>> 2] >>> 24 - _i2 % 4 * 8 & 0xff;
latin1Chars.push(String.fromCharCode(bite));
}
return decodeURIComponent(escape(latin1Chars.join('')));
} catch (e) {
throw new Error('Malformed UTF-8 data');
}
}
/**
* 转成字节数组
*/
function hexToArray(hexStr) {
var words = [];
var hexStrLength = hexStr.length;
if (hexStrLength % 2 !== 0) {
hexStr = leftPad(hexStr, hexStrLength + 1);
}
hexStrLength = hexStr.length;
for (var i = 0; i < hexStrLength; i += 2) {
words.push(parseInt(hexStr.substr(i, 2), 16));
}
return words;
}
/**
* 验证公钥是否为椭圆曲线上的点
*/
function verifyPublicKey(publicKey) {
var point = curve.decodePointHex(publicKey);
if (!point) return false;
var x = point.getX();
var y = point.getY();
// 验证 y^2 是否等于 x^3 + ax + b
return y.square().equals(x.multiply(x.square()).add(x.multiply(curve.a)).add(curve.b));
}
module.exports = {
getGlobalCurve: getGlobalCurve,
generateEcparam: generateEcparam,
generateKeyPairHex: generateKeyPairHex,
utf8ToHex: utf8ToHex,
leftPad: leftPad,
arrayToHex: arrayToHex,
arrayToUtf8: arrayToUtf8,
hexToArray: hexToArray,
verifyPublicKey: verifyPublicKey
};
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/* eslint-disable no-case-declarations, max-len */
var _require = __webpack_require__(0),
BigInteger = _require.BigInteger;
/**
* thanks for Tom Wu : http://www-cs-students.stanford.edu/~tjw/jsbn/
*
* Basic Javascript Elliptic Curve implementation
* Ported loosely from BouncyCastle's Java EC code
* Only Fp curves implemented for now
*/
var THREE = new BigInteger('3');
/**
* 椭圆曲线域元素
*/
var ECFieldElementFp = function () {
function ECFieldElementFp(q, x) {
_classCallCheck(this, ECFieldElementFp);
this.x = x;
this.q = q;
// TODO if (x.compareTo(q) >= 0) error
}
/**
* 判断相等
*/
ECFieldElementFp.prototype.equals = function equals(other) {
if (other === this) return true;
return this.q.equals(other.q) && this.x.equals(other.x);
};
/**
* 返回具体数值
*/
ECFieldElementFp.prototype.toBigInteger = function toBigInteger() {
return this.x;
};
/**
* 取反
*/
ECFieldElementFp.prototype.negate = function negate() {
return new ECFieldElementFp(this.q, this.x.negate().mod(this.q));
};
/**
* 相加
*/
ECFieldElementFp.prototype.add = function add(b) {
return new ECFieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q));
};
/**
* 相减
*/
ECFieldElementFp.prototype.subtract = function subtract(b) {
return new ECFieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q));
};
/**
* 相乘
*/
ECFieldElementFp.prototype.multiply = function multiply(b) {
return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q));
};
/**
* 相除
*/
ECFieldElementFp.prototype.divide = function divide(b) {
return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q));
};
/**
* 平方
*/
ECFieldElementFp.prototype.square = function square() {
return new ECFieldElementFp(this.q, this.x.square().mod(this.q));
};
return ECFieldElementFp;
}();
var ECPointFp = function () {
function ECPointFp(curve, x, y, z) {
_classCallCheck(this, ECPointFp);
this.curve = curve;
this.x = x;
this.y = y;
// 标准射影坐标系zinv == null 或 z * zinv == 1
this.z = z == null ? BigInteger.ONE : z;
this.zinv = null;
// TODO: compression flag
}
ECPointFp.prototype.getX = function getX() {
if (this.zinv === null) this.zinv = this.z.modInverse(this.curve.q);
return this.curve.fromBigInteger(this.x.toBigInteger().multiply(this.zinv).mod(this.curve.q));
};
ECPointFp.prototype.getY = function getY() {
if (this.zinv === null) this.zinv = this.z.modInverse(this.curve.q);
return this.curve.fromBigInteger(this.y.toBigInteger().multiply(this.zinv).mod(this.curve.q));
};
/**
* 判断相等
*/
ECPointFp.prototype.equals = function equals(other) {
if (other === this) return true;
if (this.isInfinity()) return other.isInfinity();
if (other.isInfinity()) return this.isInfinity();
// u = y2 * z1 - y1 * z2
var u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q);
if (!u.equals(BigInteger.ZERO)) return false;
// v = x2 * z1 - x1 * z2
var v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q);
return v.equals(BigInteger.ZERO);
};
/**
* 是否是无穷远点
*/
ECPointFp.prototype.isInfinity = function isInfinity() {
if (this.x === null && this.y === null) return true;
return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO);
};
/**
* 取反x 轴对称点
*/
ECPointFp.prototype.negate = function negate() {
return new ECPointFp(this.curve, this.x, this.y.negate(), this.z);
};
/**
* 相加
*
* 标准射影坐标系:
*
* λ1 = x1 * z2
* λ2 = x2 * z1
* λ3 = λ1 λ2
* λ4 = y1 * z2
* λ5 = y2 * z1
* λ6 = λ4 λ5
* λ7 = λ1 + λ2
* λ8 = z1 * z2
* λ9 = λ3^2
* λ10 = λ3 * λ9
* λ11 = λ8 * λ6^2 λ7 * λ9
* x3 = λ3 * λ11
* y3 = λ6 * (λ9 * λ1 λ11) λ4 * λ10
* z3 = λ10 * λ8
*/
ECPointFp.prototype.add = function add(b) {
if (this.isInfinity()) return b;
if (b.isInfinity()) return this;
var x1 = this.x.toBigInteger();
var y1 = this.y.toBigInteger();
var z1 = this.z;
var x2 = b.x.toBigInteger();
var y2 = b.y.toBigInteger();
var z2 = b.z;
var q = this.curve.q;
var w1 = x1.multiply(z2).mod(q);
var w2 = x2.multiply(z1).mod(q);
var w3 = w1.subtract(w2);
var w4 = y1.multiply(z2).mod(q);
var w5 = y2.multiply(z1).mod(q);
var w6 = w4.subtract(w5);
if (BigInteger.ZERO.equals(w3)) {
if (BigInteger.ZERO.equals(w6)) {
return this.twice(); // this == b计算自加
}
return this.curve.infinity; // this == -b则返回无穷远点
}
var w7 = w1.add(w2);
var w8 = z1.multiply(z2).mod(q);
var w9 = w3.square().mod(q);
var w10 = w3.multiply(w9).mod(q);
var w11 = w8.multiply(w6.square()).subtract(w7.multiply(w9)).mod(q);
var x3 = w3.multiply(w11).mod(q);
var y3 = w6.multiply(w9.multiply(w1).subtract(w11)).subtract(w4.multiply(w10)).mod(q);
var z3 = w10.multiply(w8).mod(q);
return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3);
};
/**
* 自加
*
* 标准射影坐标系:
*
* λ1 = 3 * x1^2 + a * z1^2
* λ2 = 2 * y1 * z1
* λ3 = y1^2
* λ4 = λ3 * x1 * z1
* λ5 = λ2^2
* λ6 = λ1^2 8 * λ4
* x3 = λ2 * λ6
* y3 = λ1 * (4 * λ4 λ6) 2 * λ5 * λ3
* z3 = λ2 * λ5
*/
ECPointFp.prototype.twice = function twice() {
if (this.isInfinity()) return this;
if (!this.y.toBigInteger().signum()) return this.curve.infinity;
var x1 = this.x.toBigInteger();
var y1 = this.y.toBigInteger();
var z1 = this.z;
var q = this.curve.q;
var a = this.curve.a.toBigInteger();
var w1 = x1.square().multiply(THREE).add(a.multiply(z1.square())).mod(q);
var w2 = y1.shiftLeft(1).multiply(z1).mod(q);
var w3 = y1.square().mod(q);
var w4 = w3.multiply(x1).multiply(z1).mod(q);
var w5 = w2.square().mod(q);
var w6 = w1.square().subtract(w4.shiftLeft(3)).mod(q);
var x3 = w2.multiply(w6).mod(q);
var y3 = w1.multiply(w4.shiftLeft(2).subtract(w6)).subtract(w5.shiftLeft(1).multiply(w3)).mod(q);
var z3 = w2.multiply(w5).mod(q);
return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3);
};
/**
* 倍点计算
*/
ECPointFp.prototype.multiply = function multiply(k) {
if (this.isInfinity()) return this;
if (!k.signum()) return this.curve.infinity;
// 使用加减法
var k3 = k.multiply(THREE);
var neg = this.negate();
var Q = this;
for (var i = k3.bitLength() - 2; i > 0; i--) {
Q = Q.twice();
var k3Bit = k3.testBit(i);
var kBit = k.testBit(i);
if (k3Bit !== kBit) {
Q = Q.add(k3Bit ? this : neg);
}
}
return Q;
};
return ECPointFp;
}();
/**
* 椭圆曲线 y^2 = x^3 + ax + b
*/
var ECCurveFp = function () {
function ECCurveFp(q, a, b) {
_classCallCheck(this, ECCurveFp);
this.q = q;
this.a = this.fromBigInteger(a);
this.b = this.fromBigInteger(b);
this.infinity = new ECPointFp(this, null, null); // 无穷远点
}
/**
* 判断两个椭圆曲线是否相等
*/
ECCurveFp.prototype.equals = function equals(other) {
if (other === this) return true;
return this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b);
};
/**
* 生成椭圆曲线域元素
*/
ECCurveFp.prototype.fromBigInteger = function fromBigInteger(x) {
return new ECFieldElementFp(this.q, x);
};
/**
* 解析 16 进制串为椭圆曲线点
*/
ECCurveFp.prototype.decodePointHex = function decodePointHex(s) {
switch (parseInt(s.substr(0, 2), 16)) {
// 第一个字节
case 0:
return this.infinity;
case 2:
case 3:
// 不支持的压缩方式
return null;
case 4:
case 6:
case 7:
var len = (s.length - 2) / 2;
var xHex = s.substr(2, len);
var yHex = s.substr(len + 2, len);
return new ECPointFp(this, this.fromBigInteger(new BigInteger(xHex, 16)), this.fromBigInteger(new BigInteger(yHex, 16)));
default:
// 不支持
return null;
}
};
return ECCurveFp;
}();
module.exports = {
ECPointFp: ECPointFp,
ECCurveFp: ECCurveFp
};
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(1),
sm3 = _require.sm3,
hmac = _require.hmac;
/**
* 补全16进制字符串
*/
function leftPad(input, num) {
if (input.length >= num) return input;
return new Array(num - input.length + 1).join('0') + input;
}
/**
* 字节数组转 16 进制串
*/
function ArrayToHex(arr) {
return arr.map(function (item) {
item = item.toString(16);
return item.length === 1 ? '0' + item : item;
}).join('');
}
/**
* 转成字节数组
*/
function hexToArray(hexStr) {
var words = [];
var hexStrLength = hexStr.length;
if (hexStrLength % 2 !== 0) {
hexStr = leftPad(hexStr, hexStrLength + 1);
}
hexStrLength = hexStr.length;
for (var i = 0; i < hexStrLength; i += 2) {
words.push(parseInt(hexStr.substr(i, 2), 16));
}
return words;
}
/**
* utf8 串转字节数组
*/
function utf8ToArray(str) {
var arr = [];
for (var i = 0, len = str.length; i < len; i++) {
var point = str.codePointAt(i);
if (point <= 0x007f) {
// 单字节标量值00000000 00000000 0zzzzzzz
arr.push(point);
} else if (point <= 0x07ff) {
// 双字节标量值00000000 00000yyy yyzzzzzz
arr.push(0xc0 | point >>> 6); // 110yyyyy0xc0-0xdf
arr.push(0x80 | point & 0x3f); // 10zzzzzz0x80-0xbf
} else if (point <= 0xD7FF || point >= 0xE000 && point <= 0xFFFF) {
// 三字节标量值00000000 xxxxyyyy yyzzzzzz
arr.push(0xe0 | point >>> 12); // 1110xxxx0xe0-0xef
arr.push(0x80 | point >>> 6 & 0x3f); // 10yyyyyy0x80-0xbf
arr.push(0x80 | point & 0x3f); // 10zzzzzz0x80-0xbf
} else if (point >= 0x010000 && point <= 0x10FFFF) {
// 四字节标量值000wwwxx xxxxyyyy yyzzzzzz
i++;
arr.push(0xf0 | point >>> 18 & 0x1c); // 11110www0xf0-0xf7
arr.push(0x80 | point >>> 12 & 0x3f); // 10xxxxxx0x80-0xbf
arr.push(0x80 | point >>> 6 & 0x3f); // 10yyyyyy0x80-0xbf
arr.push(0x80 | point & 0x3f); // 10zzzzzz0x80-0xbf
} else {
// 五、六字节,暂时不支持
arr.push(point);
throw new Error('input is not supported');
}
}
return arr;
}
module.exports = function (input, options) {
input = typeof input === 'string' ? utf8ToArray(input) : Array.prototype.slice.call(input);
if (options) {
var mode = options.mode || 'hmac';
if (mode !== 'hmac') throw new Error('invalid mode');
var key = options.key;
if (!key) throw new Error('invalid key');
key = typeof key === 'string' ? hexToArray(key) : Array.prototype.slice.call(key);
return ArrayToHex(hmac(input, key));
}
return ArrayToHex(sm3(input));
};
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* eslint-disable no-bitwise, no-mixed-operators, complexity */
var DECRYPT = 0;
var ROUND = 32;
var BLOCK = 16;
var Sbox = [0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8, 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f, 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48];
var CK = [0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279];
/**
* 16 进制串转字节数组
*/
function hexToArray(str) {
var arr = [];
for (var i = 0, len = str.length; i < len; i += 2) {
arr.push(parseInt(str.substr(i, 2), 16));
}
return arr;
}
/**
* 字节数组转 16 进制串
*/
function ArrayToHex(arr) {
return arr.map(function (item) {
item = item.toString(16);
return item.length === 1 ? '0' + item : item;
}).join('');
}
/**
* utf8 串转字节数组
*/
function utf8ToArray(str) {
var arr = [];
for (var i = 0, len = str.length; i < len; i++) {
var point = str.codePointAt(i);
if (point <= 0x007f) {
// 单字节标量值00000000 00000000 0zzzzzzz
arr.push(point);
} else if (point <= 0x07ff) {
// 双字节标量值00000000 00000yyy yyzzzzzz
arr.push(0xc0 | point >>> 6); // 110yyyyy0xc0-0xdf
arr.push(0x80 | point & 0x3f); // 10zzzzzz0x80-0xbf
} else if (point <= 0xD7FF || point >= 0xE000 && point <= 0xFFFF) {
// 三字节标量值00000000 xxxxyyyy yyzzzzzz
arr.push(0xe0 | point >>> 12); // 1110xxxx0xe0-0xef
arr.push(0x80 | point >>> 6 & 0x3f); // 10yyyyyy0x80-0xbf
arr.push(0x80 | point & 0x3f); // 10zzzzzz0x80-0xbf
} else if (point >= 0x010000 && point <= 0x10FFFF) {
// 四字节标量值000wwwxx xxxxyyyy yyzzzzzz
i++;
arr.push(0xf0 | point >>> 18 & 0x1c); // 11110www0xf0-0xf7
arr.push(0x80 | point >>> 12 & 0x3f); // 10xxxxxx0x80-0xbf
arr.push(0x80 | point >>> 6 & 0x3f); // 10yyyyyy0x80-0xbf
arr.push(0x80 | point & 0x3f); // 10zzzzzz0x80-0xbf
} else {
// 五、六字节,暂时不支持
arr.push(point);
throw new Error('input is not supported');
}
}
return arr;
}
/**
* 字节数组转 utf8 串
*/
function arrayToUtf8(arr) {
var str = [];
for (var i = 0, len = arr.length; i < len; i++) {
if (arr[i] >= 0xf0 && arr[i] <= 0xf7) {
// 四字节
str.push(String.fromCodePoint(((arr[i] & 0x07) << 18) + ((arr[i + 1] & 0x3f) << 12) + ((arr[i + 2] & 0x3f) << 6) + (arr[i + 3] & 0x3f)));
i += 3;
} else if (arr[i] >= 0xe0 && arr[i] <= 0xef) {
// 三字节
str.push(String.fromCodePoint(((arr[i] & 0x0f) << 12) + ((arr[i + 1] & 0x3f) << 6) + (arr[i + 2] & 0x3f)));
i += 2;
} else if (arr[i] >= 0xc0 && arr[i] <= 0xdf) {
// 双字节
str.push(String.fromCodePoint(((arr[i] & 0x1f) << 6) + (arr[i + 1] & 0x3f)));
i++;
} else {
// 单字节
str.push(String.fromCodePoint(arr[i]));
}
}
return str.join('');
}
/**
* 32 比特循环左移
*/
function rotl(x, y) {
return x << y | x >>> 32 - y;
}
/**
* 非线性变换
*/
function byteSub(a) {
return (Sbox[a >>> 24 & 0xFF] & 0xFF) << 24 | (Sbox[a >>> 16 & 0xFF] & 0xFF) << 16 | (Sbox[a >>> 8 & 0xFF] & 0xFF) << 8 | Sbox[a & 0xFF] & 0xFF;
}
/**
* 线性变换,加密/解密用
*/
function l1(b) {
return b ^ rotl(b, 2) ^ rotl(b, 10) ^ rotl(b, 18) ^ rotl(b, 24);
}
/**
* 线性变换,生成轮密钥用
*/
function l2(b) {
return b ^ rotl(b, 13) ^ rotl(b, 23);
}
/**
* 以一组 128 比特进行加密/解密操作
*/
function sms4Crypt(input, output, roundKey) {
var x = new Array(4);
// 字节数组转成字数组(此处 1 字 = 32 比特)
var tmp = new Array(4);
for (var i = 0; i < 4; i++) {
tmp[0] = input[4 * i] & 0xff;
tmp[1] = input[4 * i + 1] & 0xff;
tmp[2] = input[4 * i + 2] & 0xff;
tmp[3] = input[4 * i + 3] & 0xff;
x[i] = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3];
}
// x[i + 4] = x[i] ^ l1(byteSub(x[i + 1] ^ x[i + 2] ^ x[i + 3] ^ roundKey[i]))
for (var r = 0, mid; r < 32; r += 4) {
mid = x[1] ^ x[2] ^ x[3] ^ roundKey[r + 0];
x[0] ^= l1(byteSub(mid)); // x[4]
mid = x[2] ^ x[3] ^ x[0] ^ roundKey[r + 1];
x[1] ^= l1(byteSub(mid)); // x[5]
mid = x[3] ^ x[0] ^ x[1] ^ roundKey[r + 2];
x[2] ^= l1(byteSub(mid)); // x[6]
mid = x[0] ^ x[1] ^ x[2] ^ roundKey[r + 3];
x[3] ^= l1(byteSub(mid)); // x[7]
}
// 反序变换
for (var j = 0; j < 16; j += 4) {
output[j] = x[3 - j / 4] >>> 24 & 0xff;
output[j + 1] = x[3 - j / 4] >>> 16 & 0xff;
output[j + 2] = x[3 - j / 4] >>> 8 & 0xff;
output[j + 3] = x[3 - j / 4] & 0xff;
}
}
/**
* 密钥扩展算法
*/
function sms4KeyExt(key, roundKey, cryptFlag) {
var x = new Array(4);
// 字节数组转成字数组(此处 1 字 = 32 比特)
var tmp = new Array(4);
for (var i = 0; i < 4; i++) {
tmp[0] = key[0 + 4 * i] & 0xff;
tmp[1] = key[1 + 4 * i] & 0xff;
tmp[2] = key[2 + 4 * i] & 0xff;
tmp[3] = key[3 + 4 * i] & 0xff;
x[i] = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3];
}
// 与系统参数做异或
x[0] ^= 0xa3b1bac6;
x[1] ^= 0x56aa3350;
x[2] ^= 0x677d9197;
x[3] ^= 0xb27022dc;
// roundKey[i] = x[i + 4] = x[i] ^ l2(byteSub(x[i + 1] ^ x[i + 2] ^ x[i + 3] ^ CK[i]))
for (var r = 0, mid; r < 32; r += 4) {
mid = x[1] ^ x[2] ^ x[3] ^ CK[r + 0];
roundKey[r + 0] = x[0] ^= l2(byteSub(mid)); // x[4]
mid = x[2] ^ x[3] ^ x[0] ^ CK[r + 1];
roundKey[r + 1] = x[1] ^= l2(byteSub(mid)); // x[5]
mid = x[3] ^ x[0] ^ x[1] ^ CK[r + 2];
roundKey[r + 2] = x[2] ^= l2(byteSub(mid)); // x[6]
mid = x[0] ^ x[1] ^ x[2] ^ CK[r + 3];
roundKey[r + 3] = x[3] ^= l2(byteSub(mid)); // x[7]
}
// 解密时使用反序的轮密钥
if (cryptFlag === DECRYPT) {
for (var _r = 0, _mid; _r < 16; _r++) {
_mid = roundKey[_r];
roundKey[_r] = roundKey[31 - _r];
roundKey[31 - _r] = _mid;
}
}
}
function sm4(inArray, key, cryptFlag) {
var _ref = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {},
_ref$padding = _ref.padding,
padding = _ref$padding === undefined ? 'pkcs#7' : _ref$padding,
mode = _ref.mode,
_ref$iv = _ref.iv,
iv = _ref$iv === undefined ? [] : _ref$iv,
_ref$output = _ref.output,
output = _ref$output === undefined ? 'string' : _ref$output;
if (mode === 'cbc') {
// CBC 模式,默认走 ECB 模式
if (typeof iv === 'string') iv = hexToArray(iv);
if (iv.length !== 128 / 8) {
// iv 不是 128 比特
throw new Error('iv is invalid');
}
}
// 检查 key
if (typeof key === 'string') key = hexToArray(key);
if (key.length !== 128 / 8) {
// key 不是 128 比特
throw new Error('key is invalid');
}
// 检查输入
if (typeof inArray === 'string') {
if (cryptFlag !== DECRYPT) {
// 加密,输入为 utf8 串
inArray = utf8ToArray(inArray);
} else {
// 解密,输入为 16 进制串
inArray = hexToArray(inArray);
}
} else {
inArray = [].concat(inArray);
}
// 新增填充sm4 是 16 个字节一个分组,所以统一走到 pkcs#7
if ((padding === 'pkcs#5' || padding === 'pkcs#7') && cryptFlag !== DECRYPT) {
var paddingCount = BLOCK - inArray.length % BLOCK;
for (var i = 0; i < paddingCount; i++) {
inArray.push(paddingCount);
}
}
// 生成轮密钥
var roundKey = new Array(ROUND);
sms4KeyExt(key, roundKey, cryptFlag);
var outArray = [];
var lastVector = iv;
var restLen = inArray.length;
var point = 0;
while (restLen >= BLOCK) {
var input = inArray.slice(point, point + 16);
var _output = new Array(16);
if (mode === 'cbc') {
for (var _i = 0; _i < BLOCK; _i++) {
if (cryptFlag !== DECRYPT) {
// 加密过程在组加密前进行异或
input[_i] ^= lastVector[_i];
}
}
}
sms4Crypt(input, _output, roundKey);
for (var _i2 = 0; _i2 < BLOCK; _i2++) {
if (mode === 'cbc') {
if (cryptFlag === DECRYPT) {
// 解密过程在组解密后进行异或
_output[_i2] ^= lastVector[_i2];
}
}
outArray[point + _i2] = _output[_i2];
}
if (mode === 'cbc') {
if (cryptFlag !== DECRYPT) {
// 使用上一次输出作为加密向量
lastVector = _output;
} else {
// 使用上一次输入作为解密向量
lastVector = input;
}
}
restLen -= BLOCK;
point += BLOCK;
}
// 去除填充sm4 是 16 个字节一个分组,所以统一走到 pkcs#7
if ((padding === 'pkcs#5' || padding === 'pkcs#7') && cryptFlag === DECRYPT) {
var len = outArray.length;
var _paddingCount = outArray[len - 1];
for (var _i3 = 1; _i3 <= _paddingCount; _i3++) {
if (outArray[len - _i3] !== _paddingCount) throw new Error('padding is invalid');
}
outArray.splice(len - _paddingCount, _paddingCount);
}
// 调整输出
if (output !== 'array') {
if (cryptFlag !== DECRYPT) {
// 加密,输出转 16 进制串
return ArrayToHex(outArray);
} else {
// 解密,输出转 utf8 串
return arrayToUtf8(outArray);
}
} else {
return outArray;
}
}
module.exports = {
encrypt: function encrypt(inArray, key, options) {
return sm4(inArray, key, 1, options);
},
decrypt: function decrypt(inArray, key, options) {
return sm4(inArray, key, 0, options);
}
};
/***/ })
/******/ ]);