@zlattice/lattice-js
Version:
Lattice blockchain TypeScript SDK with dual module support (CJS + ESM)
305 lines • 12.2 kB
JavaScript
;
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