UNPKG

@zlattice/lattice-js

Version:

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

138 lines 4.58 kB
import { stripHexPrefix } from "../../utils/string.js"; import { mod } from '@noble/curves/abstract/modular'; /* eslint-disable no-bitwise, no-mixed-operators, no-use-before-define, max-len */ import * as utils from '@noble/curves/abstract/utils'; import { ONE, TWO, ZERO } from './bn.js'; import { sm2Curve } from './ec.js'; /** * 生成密钥对:publicKey = privateKey * G */ export function generateKeyPairHex(str) { const privateKey = str ? utils.numberToBytesBE((mod(BigInt(str), ONE) + ONE), 32) : sm2Curve.utils.randomPrivateKey(); // const random = typeof a === 'string' ? new BigInteger(a, b) : // a ? new BigInteger(a, b!, c!) : new BigInteger(n.bitLength(), rng) // const d = random.mod(n.subtract(BigInteger.ONE)).add(BigInteger.ONE) // 随机数 // const privateKey = leftPad(d.toString(16), 64) // const P = G!.multiply(d) // P = dG,p 为公钥,d 为私钥 // const Px = leftPad(P.getX().toBigInteger().toString(16), 64) // const Py = leftPad(P.getY().toBigInteger().toString(16), 64) // const publicKey = '04' + Px + Py const publicKey = sm2Curve.getPublicKey(privateKey, false); const privPad = leftPad(utils.bytesToHex(privateKey), 64); const pubPad = leftPad(utils.bytesToHex(publicKey), 64); return { privateKey: privPad, publicKey: pubPad }; } /** * 生成压缩公钥 */ export function compressPublicKeyHex(s) { if (stripHexPrefix(s).length === 66) { return stripHexPrefix(s); } if (s.length !== 130) throw new Error("Invalid public key to compress"); const len = (s.length - 2) / 2; const xHex = s.substring(2, 2 + len); const y = utils.hexToNumber(s.substring(len + 2, len + len + 2)); let prefix = "03"; if (mod(y, TWO) === ZERO) prefix = "02"; return prefix + xHex; } /** * utf8串转16进制串 */ export function utf8ToHex(input) { const bytes = utils.utf8ToBytes(input); return utils.bytesToHex(bytes); } /** * 补全16进制字符串 */ export function leftPad(input, num) { if (input.length >= num) return input; return (new Array(num - input.length + 1)).join('0') + input; } /** * 转成16进制串 */ export function arrayToHex(arr) { return arr.map(item => { const hex = item.toString(16); return hex.length === 1 ? `0${hex}` : hex; }).join(''); } /** * 转成utf8串 */ export function arrayToUtf8(arr) { const str = []; for (let 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(''); } /** * 转成字节数组 */ export function hexToArray(hexStr) { let hexStrLength = hexStr.length; const _hexStr = hexStrLength % 2 !== 0 ? leftPad(hexStr, hexStrLength + 1) : hexStr; hexStrLength = _hexStr.length; const wordLength = hexStrLength / 2; const words = new Uint8Array(wordLength); for (let i = 0; i < wordLength; i++) { words[i] = parseInt(_hexStr.substring(i * 2, i * 2 + 2), 16); } return words; } /** * 验证公钥是否为椭圆曲线上的点 */ export function verifyPublicKey(publicKey) { const point = sm2Curve.ProjectivePoint.fromHex(publicKey); if (!point) return false; try { point.assertValidity(); return true; } catch (error) { return false; } } export function isValidPrivateKey(privateKey) { return sm2Curve.utils.isValidPrivateKey(privateKey); } /** * 验证公钥是否等价,等价返回true */ export function comparePublicKeyHex(publicKey1, publicKey2) { const point1 = sm2Curve.ProjectivePoint.fromHex(publicKey1); if (!point1) return false; const point2 = sm2Curve.ProjectivePoint.fromHex(publicKey2); if (!point2) return false; return point1.equals(point2); } //# sourceMappingURL=utils.js.map