Skip to content

Commit

Permalink
chore
Browse files Browse the repository at this point in the history
  • Loading branch information
Cubelrti committed Jan 30, 2024
1 parent 4b5ff34 commit 53e0065
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 13 deletions.
2 changes: 1 addition & 1 deletion benchmark/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { run, mark, utils } from 'micro-bmark';
import * as sm from 'sm-crypto'
import * as smV2 from '../dist/index.js'
import * as smV2 from 'sm-crypto-v2'

const msg = 'Hello world~!'
const longMsg = msg.repeat(10000)
Expand Down
21 changes: 21 additions & 0 deletions src/sm2/globalThis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

(function (Object) {
typeof globalThis !== 'object' && (
// @ts-ignore
this ?
get() :
(Object.defineProperty(Object.prototype, '_T_', {
configurable: true,
get: get
// @ts-ignore
}), _T_)
);
function get() {
// @ts-ignore
var global = this || self;
global.globalThis = global;
// @ts-ignore
delete Object.prototype._T_;
}
}(Object));
export default globalThis as any;
50 changes: 45 additions & 5 deletions src/sm2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,39 @@ export const EmptyArray = new Uint8Array()
/**
* 加密
*/
class LRUMap<K, V> extends Map<K, V> {
length: number
constructor(length: number) {
super();
this.length = length;
}
set(key: K, value: V) {
super.delete(this.size < this.length ? key : super.keys().next().value);
return super.set(key, value);
}
}
// 保存最后 3 个加密的公钥,用来保证在这个情况下,性能不退化的太厉害
const precomputedPublicKey = new LRUMap<string, ProjPointType<JSBI>>(3)
export function doEncrypt(msg: string | Uint8Array, publicKey: string | ProjPointType<JSBI>, cipherMode = 1, options?: {
asn1?: boolean // 使用 ASN.1 对 C1 编码
}) {

const msgArr = typeof msg === 'string' ? hexToArray(utf8ToHex(msg)) : Uint8Array.from(msg)
const publicKeyPoint = typeof publicKey === 'string' ? sm2Curve.ProjectivePoint.fromHex(publicKey) :
publicKey

let publicKeyPoint: ProjPointType<JSBI>
if (typeof publicKey === 'string') {
const cached = precomputedPublicKey.get(publicKey)
if (cached) {
publicKeyPoint = cached
} else {
const point = sm2Curve.ProjectivePoint.fromHex(publicKey)
sm2Curve.utils.precompute(undefined, point)
precomputedPublicKey.set(publicKey, point)
publicKeyPoint = point
}
} else {
publicKeyPoint = publicKey
}
// publicKeyPoint = typeof publicKey === 'string' ? sm2Curve.ProjectivePoint.fromHex(publicKey) :
// publicKey
const keypair = generateKeyPairHex()
const k = utils.hexToNumber(keypair.privateKey)

Expand Down Expand Up @@ -222,7 +247,22 @@ export function doVerifySignature(msg: string | Uint8Array, signHex: string, pub
s = utils.hexToNumber(signHex.substring(64))
}

const PA = typeof publicKey === 'string' ? sm2Curve.ProjectivePoint.fromHex(publicKey) : publicKey
let PA: ProjPointType<JSBI>

if (typeof publicKey === 'string') {
const cached = precomputedPublicKey.get(publicKey)
if (cached) {
PA = cached
} else {
const point = sm2Curve.ProjectivePoint.fromHex(publicKey)
sm2Curve.utils.precompute(undefined, point)
precomputedPublicKey.set(publicKey, point)
PA = point
}
} else {
PA = publicKey
}

const e = utils.hexToNumber(hashHex)

// t = (r + s) mod n
Expand Down
2 changes: 2 additions & 0 deletions src/sm2/rng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// Web: globalThis.crypto
// Node: async import("crypto").webcrypto
// Mini Program: wx.getRandomValues
import globalThis from './globalThis';

declare module wx {
function getRandomValues(options: {
length: number;
Expand Down
15 changes: 8 additions & 7 deletions src/sm2/sm3.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
// import assert from './_assert.js';
import JSBI from 'jsbi';
import { Hash, createView, Input, toBytes, wrapConstructor } from '../sm3/utils.js';

const BoolA = (A: number, B: number, C: number) => ((A & B) | (A & C)) | (B & C)
const BoolB = (A: number, B: number, C: number) => ((A ^ B) ^ C)
const BoolC = (A: number, B: number, C: number) => (A & B) | ((~A) & C)
// Polyfill for Safari 14
function setBigUint64(view: DataView, byteOffset: number, value: bigint, isLE: boolean): void {
if (typeof view.setBigUint64 === 'function') return view.setBigUint64(byteOffset, value, isLE);
const _32n = BigInt(32);
const _u32_max = BigInt(0xffffffff);
const wh = Number((value >> _32n) & _u32_max);
const wl = Number(value & _u32_max);
function setBigUint64(view: DataView, byteOffset: number, value: JSBI, isLE: boolean): void {
// if (typeof view.setBigUint64 === 'function') return view.setBigUint64(byteOffset, value, isLE);
const _32n = JSBI.BigInt(32);
const _u32_max = JSBI.BigInt(0xffffffff);
const wh = Number((JSBI.bitwiseAnd(JSBI.signedRightShift(value, _32n), _u32_max)));
const wl = Number(JSBI.bitwiseAnd(value, _u32_max));
const h = isLE ? 4 : 0;
const l = isLE ? 0 : 4;
view.setUint32(byteOffset + h, wh, isLE);
Expand Down Expand Up @@ -120,7 +121,7 @@ export abstract class SHA2<T extends SHA2<T>> extends Hash<T> {
// Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
// You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
// So we just write lowest 64 bits of that value.
setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
setBigUint64(view, blockLen - 8, JSBI.BigInt(this.length * 8), isLE);
this.process(view, 0);
const oview = createView(out);
const len = this.outputLen;
Expand Down

0 comments on commit 53e0065

Please sign in to comment.