UNPKG

@zlattice/lattice-js

Version:

Lattice blockchain TypeScript SDK with dual module support (CJS + ESM)

305 lines 12.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EmptyArray = exports.calculateSharedKey = exports.initRNGPool = void 0; exports.doEncrypt = doEncrypt; exports.doDecrypt = doDecrypt; exports.doSignature = doSignature; exports.doVerifySignature = doVerifySignature; exports.getZ = getZ; exports.getHash = getHash; exports.precomputePublicKey = precomputePublicKey; exports.getPublicKeyFromPrivateKey = getPublicKeyFromPrivateKey; exports.getPoint = getPoint; const utils_1 = require("../../crypto/sm3/utils.js"); const utils = __importStar(require("@noble/curves/abstract/utils")); /* eslint-disable no-use-before-define */ const asn1_1 = require("./asn1.js"); const bn_1 = require("./bn.js"); const ec_1 = require("./ec.js"); const sm3_1 = require("./sm3.js"); const utils_2 = require("./utils.js"); __exportStar(require("./utils.js"), exports); var rng_1 = require("./rng.js"); Object.defineProperty(exports, "initRNGPool", { enumerable: true, get: function () { return rng_1.initRNGPool; } }); var kx_1 = require("./kx.js"); Object.defineProperty(exports, "calculateSharedKey", { enumerable: true, get: function () { return kx_1.calculateSharedKey; } }); const C1C2C3 = 0; // a empty array, just make tsc happy exports.EmptyArray = new Uint8Array(); /** * 加密 */ function doEncrypt(msg, publicKey, cipherMode = 1, options) { const msgArr = typeof msg === 'string' ? (0, utils_2.hexToArray)((0, utils_2.utf8ToHex)(msg)) : Uint8Array.from(msg); const publicKeyPoint = typeof publicKey === 'string' ? ec_1.sm2Curve.ProjectivePoint.fromHex(publicKey) : publicKey; const keypair = (0, utils_2.generateKeyPairHex)(); const k = utils.hexToNumber(keypair.privateKey); // c1 = k * G let c1 = keypair.publicKey; if (c1.length > 128) c1 = c1.substring(c1.length - 128); const p = publicKeyPoint.multiply(k); // (x2, y2) = k * publicKey const x2 = (0, utils_2.hexToArray)((0, utils_2.leftPad)(utils.numberToHexUnpadded(p.x), 64)); const y2 = (0, utils_2.hexToArray)((0, utils_2.leftPad)(utils.numberToHexUnpadded(p.y), 64)); // c3 = hash(x2 || msg || y2) const c3 = (0, utils_1.bytesToHex)((0, sm3_1.sm3)(utils.concatBytes(x2, msgArr, y2))); xorCipherStream(x2, y2, msgArr); const c2 = (0, utils_1.bytesToHex)(msgArr); if (options?.asn1) { const point = ec_1.sm2Curve.ProjectivePoint.fromHex(keypair.publicKey); const encode = cipherMode === C1C2C3 ? (0, asn1_1.encodeEnc)(point.x, point.y, c2, c3) : (0, asn1_1.encodeEnc)(point.x, point.y, c3, c2); return encode; } return cipherMode === C1C2C3 ? c1 + c2 + c3 : c1 + c3 + c2; } function xorCipherStream(x2, y2, msg) { let ct = 1; let offset = 0; let t = exports.EmptyArray; const ctShift = new Uint8Array(4); const nextT = () => { // (1) Hai = hash(z || ct) // (2) ct++ ctShift[0] = ct >> 24 & 0x00ff; ctShift[1] = ct >> 16 & 0x00ff; ctShift[2] = ct >> 8 & 0x00ff; ctShift[3] = ct & 0x00ff; t = (0, sm3_1.sm3)(utils.concatBytes(x2, y2, ctShift)); ct++; offset = 0; }; nextT(); // 先生成 Ha1 for (let 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; } } function doDecrypt(encryptData, privateKey, cipherMode = 1, options) { const { output = 'string', asn1 = false } = options || {}; const privateKeyInteger = utils.hexToNumber(privateKey); let c1; let c2; let c3; if (asn1) { const { x, y, cipher, hash } = (0, asn1_1.decodeEnc)(encryptData); c1 = ec_1.sm2Curve.ProjectivePoint.fromAffine({ x, y }); c3 = hash; c2 = cipher; if (cipherMode === C1C2C3) { [c2, c3] = [c3, c2]; } } else { // c1c3c2 c1 = ec_1.sm2Curve.ProjectivePoint.fromHex(`04${encryptData.substring(0, 128)}`); c3 = encryptData.substring(128, 128 + 64); c2 = encryptData.substring(128 + 64); if (cipherMode === C1C2C3) { c3 = encryptData.substring(encryptData.length - 64); c2 = encryptData.substring(128, encryptData.length - 64); } } const msg = (0, utils_2.hexToArray)(c2); const p = c1.multiply(privateKeyInteger); const x2 = (0, utils_2.hexToArray)((0, utils_2.leftPad)(utils.numberToHexUnpadded(p.x), 64)); const y2 = (0, utils_2.hexToArray)((0, utils_2.leftPad)(utils.numberToHexUnpadded(p.y), 64)); xorCipherStream(x2, y2, msg); // c3 = hash(x2 || msg || y2) const checkC3 = (0, utils_2.arrayToHex)(Array.from((0, sm3_1.sm3)(utils.concatBytes(x2, msg, y2)))); if (checkC3 === c3.toLowerCase()) { return output === 'array' ? msg : (0, utils_2.arrayToUtf8)(msg); } return output === 'array' ? [] : ''; } /** * 签名 */ function doSignature(msg, privateKey, options = {}) { let { pointPool, der, hash, publicKey, userId } = options; let hashHex = typeof msg === 'string' ? (0, utils_2.utf8ToHex)(msg) : (0, utils_2.arrayToHex)(Array.from(msg)); if (hash) { // sm3杂凑 publicKey = publicKey || getPublicKeyFromPrivateKey(privateKey); hashHex = getHash(hashHex, publicKey, userId); } const dA = utils.hexToNumber(privateKey); const e = utils.hexToNumber(hashHex); // k let k = null; let r = null; let s = null; do { do { let point; if (pointPool?.length) { point = pointPool.pop(); } else { point = getPoint(); } k = point.k; // r = (e + x1) mod n r = ec_1.field.add(e, point.x1); } while (r === bn_1.ZERO || (r + k) === ec_1.sm2Curve.CURVE.n); // s = ((1 + dA)^-1 * (k - r * dA)) mod n s = ec_1.field.mul(ec_1.field.inv(ec_1.field.addN(dA, bn_1.ONE)), ec_1.field.subN(k, ec_1.field.mulN(r, dA))); } while (s === bn_1.ZERO); if (der) return (0, asn1_1.encodeDer)(r, s); // asn.1 der 编码 return (0, utils_2.leftPad)(utils.numberToHexUnpadded(r), 64) + (0, utils_2.leftPad)(utils.numberToHexUnpadded(s), 64); } /** * 验签 */ function doVerifySignature(msg, signHex, publicKey, options = {}) { let hashHex; const { hash, der, userId, } = options; const publicKeyHex = typeof publicKey === 'string' ? publicKey : publicKey.toHex(false); if (hash) { // sm3杂凑 hashHex = getHash(typeof msg === 'string' ? (0, utils_2.utf8ToHex)(msg) : msg, publicKeyHex, userId); } else { hashHex = typeof msg === 'string' ? (0, utils_2.utf8ToHex)(msg) : (0, utils_2.arrayToHex)(Array.from(msg)); } let r; let s; if (der) { const decodeDerObj = (0, asn1_1.decodeDer)(signHex); // asn.1 der 解码 r = decodeDerObj.r; s = decodeDerObj.s; } else { r = utils.hexToNumber(signHex.substring(0, 64)); s = utils.hexToNumber(signHex.substring(64)); } const PA = typeof publicKey === 'string' ? ec_1.sm2Curve.ProjectivePoint.fromHex(publicKey) : publicKey; const e = utils.hexToNumber(hashHex); // t = (r + s) mod n const t = ec_1.field.add(r, s); if (t === bn_1.ZERO) return false; // x1y1 = s * G + t * PA const x1y1 = ec_1.sm2Curve.ProjectivePoint.BASE.multiply(s).add(PA.multiply(t)); // R = (e + x1) mod n // const R = e.add(x1y1.getX().toBigInteger()).mod(n) const R = ec_1.field.add(e, x1y1.x); // return r.equals(R) return r === R; } function getZ(publicKey, userId = '1234567812345678') { // z = hash(entl || userId || a || b || gx || gy || px || py) userId = (0, utils_2.utf8ToHex)(userId); const a = (0, utils_2.leftPad)(utils.numberToHexUnpadded(ec_1.sm2Curve.CURVE.a), 64); // const b = leftPad(G.curve.b.toBigInteger().toRadix(16), 64) const b = (0, utils_2.leftPad)(utils.numberToHexUnpadded(ec_1.sm2Curve.CURVE.b), 64); // const gx = leftPad(G.getX().toBigInteger().toRadix(16), 64) const gx = (0, utils_2.leftPad)(utils.numberToHexUnpadded(ec_1.sm2Curve.ProjectivePoint.BASE.x), 64); // const gy = leftPad(G.getY().toBigInteger().toRadix(16), 64) const gy = (0, utils_2.leftPad)(utils.numberToHexUnpadded(ec_1.sm2Curve.ProjectivePoint.BASE.y), 64); let px; let py; if (publicKey.length === 128) { px = publicKey.substring(0, 64); py = publicKey.substring(64, 128); } else { // const point = G.curve.decodePointHex(publicKey)! const point = ec_1.sm2Curve.ProjectivePoint.fromHex(publicKey); // px = leftPad(point.getX().toBigInteger().toRadix(16), 64) px = (0, utils_2.leftPad)(utils.numberToHexUnpadded(point.x), 64); // py = leftPad(point.getY().toBigInteger().toRadix(16), 64) py = (0, utils_2.leftPad)(utils.numberToHexUnpadded(point.y), 64); } const data = (0, utils_2.hexToArray)(userId + a + b + gx + gy + px + py); const entl = userId.length * 4; const z = (0, sm3_1.sm3)(utils.concatBytes(new Uint8Array([entl >> 8 & 0x00ff, entl & 0x00ff]), data)); return z; } /** * sm3杂凑算法 */ function getHash(hashHex, publicKey, userId = '1234567812345678') { const z = getZ(publicKey, userId); // e = hash(z || msg) return (0, utils_1.bytesToHex)((0, sm3_1.sm3)(utils.concatBytes(z, typeof hashHex === 'string' ? (0, utils_2.hexToArray)(hashHex) : hashHex))); } /** * 预计算公钥点,可用于提升加密性能 * @export * @param {string} publicKey 公钥 * @param windowSize 计算窗口大小,默认为 8 * @returns {ProjPointType<bigint>} 预计算的点 */ function precomputePublicKey(publicKey, windowSize) { const point = ec_1.sm2Curve.ProjectivePoint.fromHex(publicKey); return ec_1.sm2Curve.utils.precompute(windowSize, point); } /** * 计算公钥 */ function getPublicKeyFromPrivateKey(privateKey, compressed = false) { const pubKey = ec_1.sm2Curve.getPublicKey(privateKey, compressed); const pubPad = (0, utils_2.leftPad)(utils.bytesToHex(pubKey), 64); return pubPad; } /** * 获取椭圆曲线点 */ function getPoint() { const keypair = (0, utils_2.generateKeyPairHex)(); const PA = ec_1.sm2Curve.ProjectivePoint.fromHex(keypair.publicKey); const k = utils.hexToNumber(keypair.privateKey); if (!PA) { throw new Error('Invalid public key'); } return { ...keypair, k, x1: PA.x, }; } //# sourceMappingURL=index.js.map