sm-crypto-v2 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +29 -2
- package/benchmark/index.js +29 -0
- package/benchmark/package.json +19 -0
- package/benchmark/pnpm-lock.yaml +28 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +19 -13
- package/dist/index.mjs +19 -13
- package/package.json +2 -3
- package/pnpm-lock.yaml +0 -7
- package/src/sm2/ec.ts +18 -12
- package/src/sm2/index.ts +3 -1
- package/src/sm2/utils.ts +3 -3
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,22 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
4
4
|
|
5
|
+
## [1.3.0](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.2.2...v1.3.0) (2023-06-07)
|
6
|
+
|
7
|
+
|
8
|
+
### Features
|
9
|
+
|
10
|
+
* **sm2:** add benchmark and optimize rng pooling ([b162377](https://github.com/Cubelrti/sm-crypto-v2/commit/b1623774cc4374deea61499f13790c5e8b17041a))
|
11
|
+
|
12
|
+
### [1.2.2](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.2.1...v1.2.2) (2023-06-07)
|
13
|
+
|
14
|
+
|
15
|
+
### Bug Fixes
|
16
|
+
|
17
|
+
* **sm2:** add test for prng ([6502a34](https://github.com/Cubelrti/sm-crypto-v2/commit/6502a3440dae2ecfe62603239448076a11c760cf))
|
18
|
+
|
19
|
+
### [1.2.1](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.2.0...v1.2.1) (2023-06-07)
|
20
|
+
|
5
21
|
## [1.2.0](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.1.0...v1.2.0) (2023-06-07)
|
6
22
|
|
7
23
|
|
package/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# sm-crypto-v2
|
2
2
|
|
3
|
+
[](https://badge.fury.io/js/sm-crypto-v2)
|
3
4
|
[](https://github.com/cubelrti/sm-crypto-v2/actions)
|
4
5
|
[](https://github.com/cubelrti/sm-crypto-v2/actions)
|
5
6
|
|
@@ -36,10 +37,12 @@ privateKey = keypair.privateKey // 私钥
|
|
36
37
|
const compressedPublicKey = sm2.compressPublicKeyHex(publicKey) // compressedPublicKey 和 publicKey 等价
|
37
38
|
sm2.comparePublicKeyHex(publicKey, compressedPublicKey) // 判断公钥是否等价
|
38
39
|
|
39
|
-
// 自定义随机数,参数会直接透传给
|
40
|
+
// 自定义随机数,参数会直接透传给 BigInt 构造器
|
40
41
|
// 注意:开发者使用自定义随机数,需要自行确保传入的随机数符合密码学安全
|
41
42
|
let keypair2 = sm2.generateKeyPairHex('123123123123123')
|
42
|
-
|
43
|
+
|
44
|
+
// 初始化随机数池,在某些场景下可能会用到
|
45
|
+
await sm2.initRNGPool()
|
43
46
|
|
44
47
|
let verifyResult = sm2.verifyPublicKey(publicKey) // 验证公钥
|
45
48
|
verifyResult = sm2.verifyPublicKey(compressedPublicKey) // 验证公钥
|
@@ -167,6 +170,30 @@ let decryptData = sm4.decrypt(encryptData, key, {mode: 'cbc', iv: 'fedcba9876543
|
|
167
170
|
* java 实现(感谢 @antherd 提供):[https://github.com/antherd/sm-crypto](https://github.com/antherd/sm-crypto)
|
168
171
|
* dart 实现(感谢 @luckykellan 提供):[https://github.com/luckykellan/dart_sm](https://github.com/luckykellan/dart_sm)
|
169
172
|
|
173
|
+
## 性能
|
174
|
+
|
175
|
+
CPU: Apple M1 Pro
|
176
|
+
|
177
|
+
```
|
178
|
+
❯ npm run bench
|
179
|
+
|
180
|
+
> benchmark@0.1.0 bench
|
181
|
+
> node index.js
|
182
|
+
|
183
|
+
Benchmarking
|
184
|
+
|
185
|
+
=== sm-crypto ===
|
186
|
+
sm2 generateKeyPair x 134 ops/sec @ 7ms/op ± 4.12% (min: 6ms, max: 21ms)
|
187
|
+
sm2 encrypt x 71 ops/sec @ 14ms/op
|
188
|
+
sm2 sign x 139 ops/sec @ 7ms/op
|
189
|
+
sm2 verify x 70 ops/sec @ 14ms/op
|
190
|
+
=== sm-crypto-v2 ===
|
191
|
+
sm2 generateKeyPair x 2,835 ops/sec @ 352μs/op ± 6.34% (min: 286μs, max: 1ms)
|
192
|
+
sm2 encrypt x 253 ops/sec @ 3ms/op ± 2.11% (min: 3ms, max: 24ms)
|
193
|
+
sm2 sign x 3,186 ops/sec @ 313μs/op ± 1.26% (min: 277μs, max: 854μs)
|
194
|
+
sm2 verify x 258 ops/sec @ 3ms/op
|
195
|
+
```
|
196
|
+
|
170
197
|
## 协议
|
171
198
|
|
172
199
|
MIT
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { run, mark, utils } from 'micro-bmark';
|
2
|
+
import * as sm from 'sm-crypto'
|
3
|
+
import * as smV2 from 'sm-crypto-v2'
|
4
|
+
|
5
|
+
const msg = 'Hello world~!'
|
6
|
+
|
7
|
+
const keypair = smV2.sm2.generateKeyPairHex('12345678901234567890')
|
8
|
+
|
9
|
+
run(async () => {
|
10
|
+
await smV2.sm2.initRNGPool()
|
11
|
+
const sig = smV2.sm2.doSignature(msg, keypair.privateKey, { publicKey: keypair.publicKey})
|
12
|
+
|
13
|
+
const RAM = false
|
14
|
+
console.log();
|
15
|
+
if (RAM) utils.logMem();
|
16
|
+
console.log('=== sm-crypto ===')
|
17
|
+
await mark('sm2 generateKeyPair', 100, () => sm.sm2.generateKeyPairHex())
|
18
|
+
await mark('sm2 encrypt', 500, () => sm.sm2.doEncrypt(msg, keypair.publicKey));
|
19
|
+
await mark('sm2 sign', 500, () => sm.sm2.doSignature(msg, keypair.privateKey, { publicKey: keypair.publicKey}));
|
20
|
+
await mark('sm2 verify', 500, () => sm.sm2.doVerifySignature(msg, sig, keypair.publicKey));
|
21
|
+
if (RAM) utils.logMem();
|
22
|
+
if (RAM) utils.logMem();
|
23
|
+
console.log('=== sm-crypto-v2 ===')
|
24
|
+
await mark('sm2 generateKeyPair', 100, () => smV2.sm2.generateKeyPairHex())
|
25
|
+
await mark('sm2 encrypt', 500, () => smV2.sm2.doEncrypt(msg, keypair.publicKey));
|
26
|
+
await mark('sm2 sign', 500, () => smV2.sm2.doSignature(msg, keypair.privateKey, { publicKey: keypair.publicKey}));
|
27
|
+
await mark('sm2 verify', 500, () => smV2.sm2.doVerifySignature(msg, sig, keypair.publicKey));
|
28
|
+
if (RAM) utils.logMem();
|
29
|
+
});
|
@@ -0,0 +1,19 @@
|
|
1
|
+
{
|
2
|
+
"name": "benchmark",
|
3
|
+
"private": true,
|
4
|
+
"version": "0.1.0",
|
5
|
+
"description": "benchmarks",
|
6
|
+
"main": "index.js",
|
7
|
+
"type": "module",
|
8
|
+
"scripts": {
|
9
|
+
"bench": "node index.js"
|
10
|
+
},
|
11
|
+
"keywords": [],
|
12
|
+
"author": "",
|
13
|
+
"license": "MIT",
|
14
|
+
"dependencies": {
|
15
|
+
"micro-bmark": "^0.3.1",
|
16
|
+
"sm-crypto": "^0.3.12",
|
17
|
+
"sm-crypto-v2": "^1.2.2"
|
18
|
+
}
|
19
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
lockfileVersion: '6.0'
|
2
|
+
|
3
|
+
dependencies:
|
4
|
+
micro-bmark:
|
5
|
+
specifier: ^0.3.1
|
6
|
+
version: 0.3.1
|
7
|
+
sm-crypto:
|
8
|
+
specifier: ^0.3.12
|
9
|
+
version: 0.3.12
|
10
|
+
sm-crypto-v2:
|
11
|
+
specifier: ^1.2.2
|
12
|
+
version: link:..
|
13
|
+
|
14
|
+
packages:
|
15
|
+
|
16
|
+
/jsbn@1.1.0:
|
17
|
+
resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==}
|
18
|
+
dev: false
|
19
|
+
|
20
|
+
/micro-bmark@0.3.1:
|
21
|
+
resolution: {integrity: sha512-bNaKObD4yPAAPrpEqp5jO6LJ2sEFgLoFSmRjEY809mJ62+2AehI/K3+RlVpN3Oo92RHpgC2RQhj6b1Tb4dmo+w==}
|
22
|
+
dev: false
|
23
|
+
|
24
|
+
/sm-crypto@0.3.12:
|
25
|
+
resolution: {integrity: sha512-272PBzB4PYaBdeGa41TH9ZlMGLPVRmS36Gs4FjmHwXIdihQypAbhhFWZTaa/3de69q2KfMme1M5O2W5+spAdrg==}
|
26
|
+
dependencies:
|
27
|
+
jsbn: 1.1.0
|
28
|
+
dev: false
|
package/dist/index.d.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* 生成密钥对:publicKey = privateKey * G
|
3
3
|
*/
|
4
|
-
declare function generateKeyPairHex(): {
|
4
|
+
declare function generateKeyPairHex(str?: string): {
|
5
5
|
privateKey: string;
|
6
6
|
publicKey: string;
|
7
7
|
};
|
@@ -39,6 +39,8 @@ declare function verifyPublicKey(publicKey: string): boolean;
|
|
39
39
|
declare function comparePublicKeyHex(publicKey1: string, publicKey2: string): boolean;
|
40
40
|
declare function concatArray(...arrays: Uint8Array[]): Uint8Array;
|
41
41
|
|
42
|
+
declare function initRNGPool(): Promise<void>;
|
43
|
+
|
42
44
|
/**
|
43
45
|
* 加密
|
44
46
|
*/
|
@@ -100,6 +102,7 @@ declare const index$2_doVerifySignature: typeof doVerifySignature;
|
|
100
102
|
declare const index$2_getHash: typeof getHash;
|
101
103
|
declare const index$2_getPublicKeyFromPrivateKey: typeof getPublicKeyFromPrivateKey;
|
102
104
|
declare const index$2_getPoint: typeof getPoint;
|
105
|
+
declare const index$2_initRNGPool: typeof initRNGPool;
|
103
106
|
declare const index$2_generateKeyPairHex: typeof generateKeyPairHex;
|
104
107
|
declare const index$2_compressPublicKeyHex: typeof compressPublicKeyHex;
|
105
108
|
declare const index$2_utf8ToHex: typeof utf8ToHex;
|
@@ -120,6 +123,7 @@ declare namespace index$2 {
|
|
120
123
|
index$2_getHash as getHash,
|
121
124
|
index$2_getPublicKeyFromPrivateKey as getPublicKeyFromPrivateKey,
|
122
125
|
index$2_getPoint as getPoint,
|
126
|
+
index$2_initRNGPool as initRNGPool,
|
123
127
|
index$2_generateKeyPairHex as generateKeyPairHex,
|
124
128
|
index$2_compressPublicKeyHex as compressPublicKeyHex,
|
125
129
|
index$2_utf8ToHex as utf8ToHex,
|
package/dist/index.js
CHANGED
@@ -49,6 +49,7 @@ __export(sm2_exports, {
|
|
49
49
|
getPoint: () => getPoint,
|
50
50
|
getPublicKeyFromPrivateKey: () => getPublicKeyFromPrivateKey,
|
51
51
|
hexToArray: () => hexToArray,
|
52
|
+
initRNGPool: () => initRNGPool,
|
52
53
|
leftPad: () => leftPad2,
|
53
54
|
utf8ToHex: () => utf8ToHex,
|
54
55
|
verifyPublicKey: () => verifyPublicKey
|
@@ -359,11 +360,14 @@ function sm32(input, options) {
|
|
359
360
|
}
|
360
361
|
|
361
362
|
// src/sm2/ec.ts
|
362
|
-
var DEFAULT_PRNG_POOL_SIZE =
|
363
|
-
var prngPool = new Uint8Array(
|
364
|
-
|
365
|
-
|
363
|
+
var DEFAULT_PRNG_POOL_SIZE = 16384;
|
364
|
+
var prngPool = new Uint8Array(0);
|
365
|
+
var _syncCrypto;
|
366
|
+
async function initRNGPool() {
|
367
|
+
if ("crypto" in globalThis) {
|
368
|
+
_syncCrypto = globalThis.crypto;
|
366
369
|
return;
|
370
|
+
}
|
367
371
|
if (prngPool.length > DEFAULT_PRNG_POOL_SIZE / 2)
|
368
372
|
return;
|
369
373
|
if ("wx" in globalThis) {
|
@@ -381,31 +385,33 @@ async function FillPRNGPoolIfNeeded() {
|
|
381
385
|
/* webpackIgnore: true */
|
382
386
|
"crypto"
|
383
387
|
);
|
388
|
+
_syncCrypto = crypto.webcrypto;
|
384
389
|
const array = new Uint8Array(DEFAULT_PRNG_POOL_SIZE);
|
385
|
-
|
390
|
+
_syncCrypto.getRandomValues(array);
|
386
391
|
prngPool = array;
|
387
392
|
} catch (error) {
|
388
393
|
throw new Error("no available csprng, abort.");
|
389
394
|
}
|
390
395
|
}
|
391
396
|
}
|
392
|
-
|
397
|
+
initRNGPool();
|
393
398
|
function consumePool(length) {
|
394
399
|
if (prngPool.length > length) {
|
395
400
|
const prng = prngPool.slice(0, length);
|
396
401
|
prngPool = prngPool.slice(length);
|
397
|
-
|
402
|
+
initRNGPool();
|
398
403
|
return prng;
|
399
404
|
} else {
|
400
|
-
throw new Error("random number pool is insufficient, prevent getting too long random values or too often.");
|
405
|
+
throw new Error("random number pool is not ready or insufficient, prevent getting too long random values or too often.");
|
401
406
|
}
|
402
407
|
}
|
403
408
|
function randomBytes(length = 0) {
|
404
409
|
const array = new Uint8Array(length);
|
405
|
-
if (
|
406
|
-
return
|
410
|
+
if (_syncCrypto) {
|
411
|
+
return _syncCrypto.getRandomValues(array);
|
407
412
|
} else {
|
408
|
-
|
413
|
+
const result = consumePool(length);
|
414
|
+
return result;
|
409
415
|
}
|
410
416
|
}
|
411
417
|
function createHash() {
|
@@ -431,8 +437,8 @@ var sm2Curve = (0, import_weierstrass.weierstrass)({
|
|
431
437
|
|
432
438
|
// src/sm2/utils.ts
|
433
439
|
var import_modular2 = require("@noble/curves/abstract/modular");
|
434
|
-
function generateKeyPairHex() {
|
435
|
-
const privateKey = sm2Curve.utils.randomPrivateKey();
|
440
|
+
function generateKeyPairHex(str) {
|
441
|
+
const privateKey = str ? utils2.numberToBytesBE((0, import_modular2.mod)(BigInt(str), ONE) + ONE, 32) : sm2Curve.utils.randomPrivateKey();
|
436
442
|
const publicKey = sm2Curve.getPublicKey(privateKey, false);
|
437
443
|
const privPad = leftPad2(utils2.bytesToHex(privateKey), 64);
|
438
444
|
const pubPad = leftPad2(utils2.bytesToHex(publicKey), 64);
|
package/dist/index.mjs
CHANGED
@@ -21,6 +21,7 @@ __export(sm2_exports, {
|
|
21
21
|
getPoint: () => getPoint,
|
22
22
|
getPublicKeyFromPrivateKey: () => getPublicKeyFromPrivateKey,
|
23
23
|
hexToArray: () => hexToArray,
|
24
|
+
initRNGPool: () => initRNGPool,
|
24
25
|
leftPad: () => leftPad2,
|
25
26
|
utf8ToHex: () => utf8ToHex,
|
26
27
|
verifyPublicKey: () => verifyPublicKey
|
@@ -331,11 +332,14 @@ function sm32(input, options) {
|
|
331
332
|
}
|
332
333
|
|
333
334
|
// src/sm2/ec.ts
|
334
|
-
var DEFAULT_PRNG_POOL_SIZE =
|
335
|
-
var prngPool = new Uint8Array(
|
336
|
-
|
337
|
-
|
335
|
+
var DEFAULT_PRNG_POOL_SIZE = 16384;
|
336
|
+
var prngPool = new Uint8Array(0);
|
337
|
+
var _syncCrypto;
|
338
|
+
async function initRNGPool() {
|
339
|
+
if ("crypto" in globalThis) {
|
340
|
+
_syncCrypto = globalThis.crypto;
|
338
341
|
return;
|
342
|
+
}
|
339
343
|
if (prngPool.length > DEFAULT_PRNG_POOL_SIZE / 2)
|
340
344
|
return;
|
341
345
|
if ("wx" in globalThis) {
|
@@ -353,31 +357,33 @@ async function FillPRNGPoolIfNeeded() {
|
|
353
357
|
/* webpackIgnore: true */
|
354
358
|
"crypto"
|
355
359
|
);
|
360
|
+
_syncCrypto = crypto.webcrypto;
|
356
361
|
const array = new Uint8Array(DEFAULT_PRNG_POOL_SIZE);
|
357
|
-
|
362
|
+
_syncCrypto.getRandomValues(array);
|
358
363
|
prngPool = array;
|
359
364
|
} catch (error) {
|
360
365
|
throw new Error("no available csprng, abort.");
|
361
366
|
}
|
362
367
|
}
|
363
368
|
}
|
364
|
-
|
369
|
+
initRNGPool();
|
365
370
|
function consumePool(length) {
|
366
371
|
if (prngPool.length > length) {
|
367
372
|
const prng = prngPool.slice(0, length);
|
368
373
|
prngPool = prngPool.slice(length);
|
369
|
-
|
374
|
+
initRNGPool();
|
370
375
|
return prng;
|
371
376
|
} else {
|
372
|
-
throw new Error("random number pool is insufficient, prevent getting too long random values or too often.");
|
377
|
+
throw new Error("random number pool is not ready or insufficient, prevent getting too long random values or too often.");
|
373
378
|
}
|
374
379
|
}
|
375
380
|
function randomBytes(length = 0) {
|
376
381
|
const array = new Uint8Array(length);
|
377
|
-
if (
|
378
|
-
return
|
382
|
+
if (_syncCrypto) {
|
383
|
+
return _syncCrypto.getRandomValues(array);
|
379
384
|
} else {
|
380
|
-
|
385
|
+
const result = consumePool(length);
|
386
|
+
return result;
|
381
387
|
}
|
382
388
|
}
|
383
389
|
function createHash() {
|
@@ -403,8 +409,8 @@ var sm2Curve = weierstrass({
|
|
403
409
|
|
404
410
|
// src/sm2/utils.ts
|
405
411
|
import { mod } from "@noble/curves/abstract/modular";
|
406
|
-
function generateKeyPairHex() {
|
407
|
-
const privateKey = sm2Curve.utils.randomPrivateKey();
|
412
|
+
function generateKeyPairHex(str) {
|
413
|
+
const privateKey = str ? utils2.numberToBytesBE(mod(BigInt(str), ONE) + ONE, 32) : sm2Curve.utils.randomPrivateKey();
|
408
414
|
const publicKey = sm2Curve.getPublicKey(privateKey, false);
|
409
415
|
const privPad = leftPad2(utils2.bytesToHex(privateKey), 64);
|
410
416
|
const pubPad = leftPad2(utils2.bytesToHex(publicKey), 64);
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "sm-crypto-v2",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.3.0",
|
4
4
|
"description": "sm-crypto-v2",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"module": "dist/index.mjs",
|
@@ -30,8 +30,7 @@
|
|
30
30
|
"author": "june_01",
|
31
31
|
"license": "MIT",
|
32
32
|
"dependencies": {
|
33
|
-
"@noble/curves": "^1.1.0"
|
34
|
-
"@types/jsbn": "^1.2.30"
|
33
|
+
"@noble/curves": "^1.1.0"
|
35
34
|
},
|
36
35
|
"devDependencies": {
|
37
36
|
"@swc/core": "^1.3.62",
|
package/pnpm-lock.yaml
CHANGED
@@ -4,9 +4,6 @@ dependencies:
|
|
4
4
|
'@noble/curves':
|
5
5
|
specifier: ^1.1.0
|
6
6
|
version: 1.1.0
|
7
|
-
'@types/jsbn':
|
8
|
-
specifier: ^1.2.30
|
9
|
-
version: 1.2.30
|
10
7
|
|
11
8
|
devDependencies:
|
12
9
|
'@swc/core':
|
@@ -743,10 +740,6 @@ packages:
|
|
743
740
|
resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
|
744
741
|
dev: true
|
745
742
|
|
746
|
-
/@types/jsbn@1.2.30:
|
747
|
-
resolution: {integrity: sha512-VZouplBofjq3YOIHLNRBDxILs/nAArdTZ2QP1ooflyhS+yPExWsFE+i2paBIBb7OI3NJShfcde/nogqk4SPB/Q==}
|
748
|
-
dev: false
|
749
|
-
|
750
743
|
/@types/json-schema@7.0.12:
|
751
744
|
resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
|
752
745
|
dev: true
|
package/src/sm2/ec.ts
CHANGED
@@ -19,11 +19,14 @@ declare module wx {
|
|
19
19
|
}): void;
|
20
20
|
}
|
21
21
|
|
22
|
-
const DEFAULT_PRNG_POOL_SIZE =
|
23
|
-
let prngPool = new Uint8Array(
|
24
|
-
|
25
|
-
async function
|
26
|
-
if ('crypto' in globalThis)
|
22
|
+
const DEFAULT_PRNG_POOL_SIZE = 16384
|
23
|
+
let prngPool = new Uint8Array(0)
|
24
|
+
let _syncCrypto: typeof import('crypto')['webcrypto']
|
25
|
+
export async function initRNGPool() {
|
26
|
+
if ('crypto' in globalThis) {
|
27
|
+
_syncCrypto = globalThis.crypto
|
28
|
+
return // no need to use pooling
|
29
|
+
}
|
27
30
|
if (prngPool.length > DEFAULT_PRNG_POOL_SIZE / 2) return // there is sufficient number
|
28
31
|
// we always populate full pool size
|
29
32
|
// since numbers may be consumed during micro tasks.
|
@@ -40,8 +43,9 @@ async function FillPRNGPoolIfNeeded() {
|
|
40
43
|
// check if node, use webcrypto if available
|
41
44
|
try {
|
42
45
|
const crypto = await import(/* webpackIgnore: true */ 'crypto');
|
46
|
+
_syncCrypto = crypto.webcrypto
|
43
47
|
const array = new Uint8Array(DEFAULT_PRNG_POOL_SIZE);
|
44
|
-
|
48
|
+
_syncCrypto.getRandomValues(array);
|
45
49
|
prngPool = array;
|
46
50
|
} catch (error) {
|
47
51
|
throw new Error('no available csprng, abort.');
|
@@ -49,25 +53,27 @@ async function FillPRNGPoolIfNeeded() {
|
|
49
53
|
}
|
50
54
|
}
|
51
55
|
|
52
|
-
|
56
|
+
initRNGPool()
|
53
57
|
|
54
58
|
function consumePool(length: number): Uint8Array {
|
55
59
|
if (prngPool.length > length) {
|
56
60
|
const prng = prngPool.slice(0, length)
|
57
61
|
prngPool = prngPool.slice(length)
|
58
|
-
|
62
|
+
initRNGPool()
|
59
63
|
return prng
|
60
64
|
} else {
|
61
|
-
throw new Error('random number pool is insufficient, prevent getting too long random values or too often.')
|
65
|
+
throw new Error('random number pool is not ready or insufficient, prevent getting too long random values or too often.')
|
62
66
|
}
|
63
67
|
}
|
64
68
|
|
65
69
|
export function randomBytes(length = 0): Uint8Array {
|
66
70
|
const array = new Uint8Array(length);
|
67
|
-
if (
|
68
|
-
return
|
71
|
+
if (_syncCrypto) {
|
72
|
+
return _syncCrypto.getRandomValues(array);
|
69
73
|
} else {
|
70
|
-
|
74
|
+
// no sync crypto available, use async pool
|
75
|
+
const result = consumePool(length)
|
76
|
+
return result
|
71
77
|
}
|
72
78
|
}
|
73
79
|
|
package/src/sm2/index.ts
CHANGED
@@ -2,12 +2,14 @@
|
|
2
2
|
import { encodeDer, decodeDer } from './asn1'
|
3
3
|
import { arrayToHex, arrayToUtf8, concatArray, generateKeyPairHex, hexToArray, leftPad, utf8ToHex } from './utils'
|
4
4
|
import { sm3 } from './sm3'
|
5
|
-
export * from './utils'
|
6
5
|
import * as mod from '@noble/curves/abstract/modular';
|
7
6
|
import * as utils from '@noble/curves/abstract/utils';
|
8
7
|
import { sm2Curve } from './ec';
|
9
8
|
import { ONE, ZERO } from './bn';
|
10
9
|
|
10
|
+
export * from './utils'
|
11
|
+
export { initRNGPool } from './ec'
|
12
|
+
|
11
13
|
// const { G, curve, n } = generateEcparam()
|
12
14
|
const C1C2C3 = 0
|
13
15
|
|
package/src/sm2/utils.ts
CHANGED
@@ -3,12 +3,13 @@ import * as utils from '@noble/curves/abstract/utils';
|
|
3
3
|
|
4
4
|
import { sm2Curve, sm2Fp } from './ec';
|
5
5
|
import { mod } from '@noble/curves/abstract/modular';
|
6
|
-
import { TWO, ZERO } from './bn';
|
6
|
+
import { ONE, TWO, ZERO } from './bn';
|
7
7
|
|
8
8
|
/**
|
9
9
|
* 生成密钥对:publicKey = privateKey * G
|
10
10
|
*/
|
11
|
-
export function generateKeyPairHex() {
|
11
|
+
export function generateKeyPairHex(str?: string) {
|
12
|
+
const privateKey = str ? utils.numberToBytesBE((mod(BigInt(str), ONE) + ONE), 32) : sm2Curve.utils.randomPrivateKey()
|
12
13
|
// const random = typeof a === 'string' ? new BigInteger(a, b) :
|
13
14
|
// a ? new BigInteger(a, b!, c!) : new BigInteger(n.bitLength(), rng)
|
14
15
|
// const d = random.mod(n.subtract(BigInteger.ONE)).add(BigInteger.ONE) // 随机数
|
@@ -18,7 +19,6 @@ export function generateKeyPairHex() {
|
|
18
19
|
// const Px = leftPad(P.getX().toBigInteger().toString(16), 64)
|
19
20
|
// const Py = leftPad(P.getY().toBigInteger().toString(16), 64)
|
20
21
|
// const publicKey = '04' + Px + Py
|
21
|
-
const privateKey = sm2Curve.utils.randomPrivateKey();
|
22
22
|
const publicKey = sm2Curve.getPublicKey(privateKey, false);
|
23
23
|
const privPad = leftPad(utils.bytesToHex(privateKey), 64)
|
24
24
|
const pubPad = leftPad(utils.bytesToHex(publicKey), 64)
|