sm-crypto-v2 1.3.0 → 1.5.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 +50 -28
- package/benchmark/index.js +14 -14
- package/benchmark/pnpm-lock.yaml +5 -1
- package/dist/index.d.ts +52 -61
- package/dist/index.js +458 -268
- package/dist/index.mjs +454 -264
- package/package.json +1 -1
- package/pnpm-lock.yaml +5 -1
- package/src/index.ts +2 -2
- package/src/sm2/ec.ts +8 -85
- package/src/sm2/hmac.ts +76 -0
- package/src/sm2/index.ts +32 -59
- package/src/sm2/kx.ts +80 -0
- package/src/sm2/rng.ts +71 -0
- package/src/sm2/sm3.ts +187 -120
- package/src/sm2/utils.ts +7 -24
- package/src/sm3/index.ts +7 -4
- package/src/sm3/utils.ts +117 -0
- package/src/sm4/index.ts +10 -12
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.5.0](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.4.0...v1.5.0) (2023-06-11)
|
6
|
+
|
7
|
+
|
8
|
+
### Features
|
9
|
+
|
10
|
+
* add benchmark ([81736dd](https://github.com/Cubelrti/sm-crypto-v2/commit/81736dd3acc05131a81fcbee61ffc247c4e2f21c))
|
11
|
+
* add benchmark result ([a8a45b2](https://github.com/Cubelrti/sm-crypto-v2/commit/a8a45b2ce234ebcd8ebc4c245325a0866f3399e5))
|
12
|
+
* **sm3:** optimize sm3 ([096bd95](https://github.com/Cubelrti/sm-crypto-v2/commit/096bd9568b451ac52a9a01bc1bdd711cfeb595c6))
|
13
|
+
|
14
|
+
## [1.4.0](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.3.0...v1.4.0) (2023-06-09)
|
15
|
+
|
16
|
+
|
17
|
+
### Features
|
18
|
+
|
19
|
+
* **sm2:** add experimental key agreement ([cdd00b4](https://github.com/Cubelrti/sm-crypto-v2/commit/cdd00b4e42bb5072e1dcb6e0301b6a2f18f53614))
|
20
|
+
|
5
21
|
## [1.3.0](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.2.2...v1.3.0) (2023-06-07)
|
6
22
|
|
7
23
|
|
package/README.md
CHANGED
@@ -1,19 +1,23 @@
|
|
1
1
|
# sm-crypto-v2
|
2
2
|
|
3
|
-
[](https://
|
3
|
+
[](https://www.npmjs.com/package/sm-crypto-v2)
|
4
4
|
[](https://github.com/cubelrti/sm-crypto-v2/actions)
|
5
5
|
[](https://github.com/cubelrti/sm-crypto-v2/actions)
|
6
6
|
|
7
|
+
国密算法 sm2、sm3 和 sm4 的 JavaScript 实现。
|
7
8
|
|
8
|
-
|
9
|
+
参数支持 TypedArray,导出 esm/cjs。
|
9
10
|
|
10
11
|
## 特性
|
11
12
|
|
12
|
-
-
|
13
|
-
-
|
14
|
-
- 移除原有 `jsbn` 依赖,改用原生 BigInt
|
15
|
-
-
|
16
|
-
-
|
13
|
+
- ⚡ 基于 [`noble-curves` Abstract API](https://github.com/paulmillr/noble-curves#abstract-api) 重构 SM2,性能提升近4倍。详见 [noble-curves 文档](https://paulmillr.com/posts/noble-secp256k1-fast-ecc/)
|
14
|
+
- 📘 使用 TypeScript 实现,提供全面的类型支持
|
15
|
+
- 🔄 移除原有 `jsbn` 依赖,改用原生 BigInt
|
16
|
+
- ✔️ 通过全部历史单元测试,包括 SM2、SM3 和 SM4
|
17
|
+
- 🎲 自动选择最优的安全随机数实现,避免使用 `Math.random()` 和 `Date.now()` 进行模拟
|
18
|
+
- 📚 同时导出 ES Module 和 CommonJS 两种格式,可按需使用
|
19
|
+
- 🔑 新增密钥交换 API(实验性)
|
20
|
+
- 🎒 未压缩大小 34kb,压缩后 17kb
|
17
21
|
|
18
22
|
## 安装
|
19
23
|
|
@@ -163,6 +167,24 @@ let decryptData = sm4.decrypt(encryptData, key, {padding: 'none', output: 'array
|
|
163
167
|
let decryptData = sm4.decrypt(encryptData, key, {mode: 'cbc', iv: 'fedcba98765432100123456789abcdef'}) // 解密,cbc 模式
|
164
168
|
```
|
165
169
|
|
170
|
+
### 密钥交换(实验性)
|
171
|
+
|
172
|
+
```js
|
173
|
+
import { sm2 } from 'sm-crypto-v2'
|
174
|
+
|
175
|
+
const keyPairA = sm2.generateKeyPairHex() // A 的秘钥对
|
176
|
+
const keyPairB = sm2.generateKeyPairHex() // B 的秘钥对
|
177
|
+
const ephemeralKeypairA = sm2.generateKeyPairHex() // A 的临时秘钥对
|
178
|
+
const ephemeralKeypairB = sm2.generateKeyPairHex() // B 的临时秘钥对
|
179
|
+
|
180
|
+
// A 所需参数:A 的秘钥对,A 的临时秘钥对,B 的公钥,B 的临时秘钥公钥,AB 的身份ID,长度
|
181
|
+
const sharedKeyFromA = sm2.calculateSharedKey(keyPairA, ephemeralKeypairA, keyPairB.publicKey, ephemeralKeypairB.publicKey, 'alice@yahoo.com', 'bob@yahoo.com', 233)
|
182
|
+
// B 所需参数:B 的秘钥对,B 的临时秘钥对,A 的公钥,A 的临时秘钥公钥,AB 的身份ID,长度
|
183
|
+
const sharedKeyFromB = sm2.calculateSharedKey(keyPairB, ephemeralKeypairB, keyPairA.publicKey, ephemeralKeypairA.publicKey, 'alice@yahoo.com', 'bob@yahoo.com', 233)
|
184
|
+
|
185
|
+
// expect(sharedKeyFromA).toEqual(sharedKeyFromB) => true
|
186
|
+
```
|
187
|
+
|
166
188
|
## 其他实现
|
167
189
|
|
168
190
|
* 原 js 版本:[https://github.com/JuneAndGreen/sm-crypto](https://github.com/JuneAndGreen/sm-crypto)
|
@@ -172,27 +194,27 @@ let decryptData = sm4.decrypt(encryptData, key, {mode: 'cbc', iv: 'fedcba9876543
|
|
172
194
|
|
173
195
|
## 性能
|
174
196
|
|
175
|
-
CPU: Apple
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
197
|
+
CPU: Apple M2
|
198
|
+
|
199
|
+
| Operation | sm-crypto | sm-crypto-v2 | Difference (in times) |
|
200
|
+
|--------------------|--------------|--------------|-----------------------|
|
201
|
+
| sm2 generateKeyPair| 148 ops/sec | 3,452 ops/sec| 23.3x |
|
202
|
+
| sm2 encrypt | 76 ops/sec | 304 ops/sec | 4x |
|
203
|
+
| sm2 sign | 150 ops/sec | 3,829 ops/sec| 25.5x |
|
204
|
+
| sm2 verify | 76 ops/sec | 306 ops/sec | 4x |
|
205
|
+
| sm3 hash | 322 ops/sec | 519 ops/sec | 1.6x |
|
206
|
+
| sm3 hmac | 244 ops/sec | 518 ops/sec | 2.1x |
|
207
|
+
| sm4 encrypt | 102,009 ops/sec | 102,124 ops/sec | 1x |
|
208
|
+
| sm4 decrypt | 143,430 ops/sec | 237,247 ops/sec | 1.7x |
|
209
|
+
|
210
|
+
内存:
|
211
|
+
|
212
|
+
| Metric | sm-crypto | sm-crypto-v2 | Difference |
|
213
|
+
|--------------------|--------------|--------------|-----------------------|
|
214
|
+
| RAM (rss) | 57.9mb | 57.7mb | -0.2mb |
|
215
|
+
| RAM (heap) | 16.6mb | 16.6mb | 0mb |
|
216
|
+
| RAM (used) | 10.4mb | 10.5mb | +0.1mb |
|
217
|
+
| RAM (end - start) | 83.1mb | 71.8mb | -11.3mb |
|
196
218
|
|
197
219
|
## 协议
|
198
220
|
|
package/benchmark/index.js
CHANGED
@@ -3,27 +3,27 @@ import * as sm from 'sm-crypto'
|
|
3
3
|
import * as smV2 from 'sm-crypto-v2'
|
4
4
|
|
5
5
|
const msg = 'Hello world~!'
|
6
|
-
|
6
|
+
const longMsg = msg.repeat(10000)
|
7
7
|
const keypair = smV2.sm2.generateKeyPairHex('12345678901234567890')
|
8
8
|
|
9
9
|
run(async () => {
|
10
10
|
await smV2.sm2.initRNGPool()
|
11
11
|
const sig = smV2.sm2.doSignature(msg, keypair.privateKey, { publicKey: keypair.publicKey})
|
12
12
|
|
13
|
-
const RAM =
|
13
|
+
const RAM = !!process.env.RAM
|
14
|
+
|
15
|
+
const backend = process.env.V2 ? smV2 : sm;
|
14
16
|
console.log();
|
15
17
|
if (RAM) utils.logMem();
|
16
|
-
console.log(
|
17
|
-
await mark('sm2 generateKeyPair', 100, () =>
|
18
|
-
await mark('sm2 encrypt', 500, () =>
|
19
|
-
await mark('sm2 sign', 500, () =>
|
20
|
-
await mark('sm2 verify', 500, () =>
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
await mark('
|
25
|
-
|
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));
|
18
|
+
console.log(`=== sm-crypto${process.env.V2 ? '-v2' : ''} ===`)
|
19
|
+
await mark('sm2 generateKeyPair', 100, () => backend.sm2.generateKeyPairHex())
|
20
|
+
await mark('sm2 encrypt', 500, () => backend.sm2.doEncrypt(msg, keypair.publicKey));
|
21
|
+
await mark('sm2 sign', 500, () => backend.sm2.doSignature(msg, keypair.privateKey, { publicKey: keypair.publicKey}));
|
22
|
+
await mark('sm2 verify', 500, () => backend.sm2.doVerifySignature(msg, sig, keypair.publicKey));
|
23
|
+
await mark('sm3 hash', 1000, () => backend.default.sm3(longMsg))
|
24
|
+
await mark('sm3 hmac', 1000, () => backend.default.sm3(longMsg, { key: 'asdfgh' }))
|
25
|
+
await mark('sm4 encrypt', 1000, () => backend.default.sm4.encrypt('hello world! 我是 juneandgreen.', '0123456789abcdeffedcba9876543210'))
|
26
|
+
await mark('sm4 decrypt', 1000, () => backend.default.sm4.encrypt('681edf34d206965e86b3e94f536e4246002a8a4efa863ccad024ac0300bb40d2', '0123456789abcdeffedcba9876543210'))
|
27
|
+
|
28
28
|
if (RAM) utils.logMem();
|
29
29
|
});
|
package/benchmark/pnpm-lock.yaml
CHANGED
package/dist/index.d.ts
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
interface KeyPair {
|
2
|
+
privateKey: string;
|
3
|
+
publicKey: string;
|
4
|
+
}
|
1
5
|
/**
|
2
6
|
* 生成密钥对:publicKey = privateKey * G
|
3
7
|
*/
|
4
|
-
declare function generateKeyPairHex(str?: string):
|
5
|
-
privateKey: string;
|
6
|
-
publicKey: string;
|
7
|
-
};
|
8
|
+
declare function generateKeyPairHex(str?: string): KeyPair;
|
8
9
|
/**
|
9
10
|
* 生成压缩公钥
|
10
11
|
*/
|
@@ -37,10 +38,12 @@ declare function verifyPublicKey(publicKey: string): boolean;
|
|
37
38
|
* 验证公钥是否等价,等价返回true
|
38
39
|
*/
|
39
40
|
declare function comparePublicKeyHex(publicKey1: string, publicKey2: string): boolean;
|
40
|
-
declare function concatArray(...arrays: Uint8Array[]): Uint8Array;
|
41
41
|
|
42
42
|
declare function initRNGPool(): Promise<void>;
|
43
43
|
|
44
|
+
declare function calculateSharedKey(keypairA: KeyPair, ephemeralKeypairA: KeyPair, publicKeyB: string, ephemeralPublicKeyB: string, idA: string | undefined, idB: string | undefined, sharedKeyLength: number): Uint8Array;
|
45
|
+
|
46
|
+
declare const EmptyArray: Uint8Array;
|
44
47
|
/**
|
45
48
|
* 加密
|
46
49
|
*/
|
@@ -94,70 +97,58 @@ declare function getPoint(): {
|
|
94
97
|
publicKey: string;
|
95
98
|
};
|
96
99
|
|
97
|
-
declare const index$
|
98
|
-
declare const index$
|
99
|
-
|
100
|
-
|
101
|
-
declare const index$
|
102
|
-
declare const index$
|
103
|
-
declare const index$
|
104
|
-
declare const index$
|
105
|
-
declare const index$
|
106
|
-
declare const index$
|
107
|
-
declare const index$
|
108
|
-
|
109
|
-
declare const index$
|
110
|
-
declare const index$
|
111
|
-
declare const index$
|
112
|
-
declare const index$
|
113
|
-
declare const index$
|
114
|
-
declare const index$
|
115
|
-
declare const index$
|
116
|
-
declare
|
100
|
+
declare const index$1_EmptyArray: typeof EmptyArray;
|
101
|
+
declare const index$1_doEncrypt: typeof doEncrypt;
|
102
|
+
declare const index$1_doDecrypt: typeof doDecrypt;
|
103
|
+
type index$1_SignaturePoint = SignaturePoint;
|
104
|
+
declare const index$1_doSignature: typeof doSignature;
|
105
|
+
declare const index$1_doVerifySignature: typeof doVerifySignature;
|
106
|
+
declare const index$1_getHash: typeof getHash;
|
107
|
+
declare const index$1_getPublicKeyFromPrivateKey: typeof getPublicKeyFromPrivateKey;
|
108
|
+
declare const index$1_getPoint: typeof getPoint;
|
109
|
+
declare const index$1_initRNGPool: typeof initRNGPool;
|
110
|
+
declare const index$1_calculateSharedKey: typeof calculateSharedKey;
|
111
|
+
type index$1_KeyPair = KeyPair;
|
112
|
+
declare const index$1_generateKeyPairHex: typeof generateKeyPairHex;
|
113
|
+
declare const index$1_compressPublicKeyHex: typeof compressPublicKeyHex;
|
114
|
+
declare const index$1_utf8ToHex: typeof utf8ToHex;
|
115
|
+
declare const index$1_leftPad: typeof leftPad;
|
116
|
+
declare const index$1_arrayToHex: typeof arrayToHex;
|
117
|
+
declare const index$1_arrayToUtf8: typeof arrayToUtf8;
|
118
|
+
declare const index$1_hexToArray: typeof hexToArray;
|
119
|
+
declare const index$1_verifyPublicKey: typeof verifyPublicKey;
|
120
|
+
declare const index$1_comparePublicKeyHex: typeof comparePublicKeyHex;
|
121
|
+
declare namespace index$1 {
|
117
122
|
export {
|
118
|
-
index$
|
119
|
-
index$
|
120
|
-
index$
|
121
|
-
index$
|
122
|
-
index$
|
123
|
-
index$
|
124
|
-
index$
|
125
|
-
index$
|
126
|
-
index$
|
127
|
-
index$
|
128
|
-
index$
|
129
|
-
index$
|
130
|
-
index$
|
131
|
-
index$
|
132
|
-
index$
|
133
|
-
index$
|
134
|
-
index$
|
135
|
-
index$
|
136
|
-
index$
|
123
|
+
index$1_EmptyArray as EmptyArray,
|
124
|
+
index$1_doEncrypt as doEncrypt,
|
125
|
+
index$1_doDecrypt as doDecrypt,
|
126
|
+
index$1_SignaturePoint as SignaturePoint,
|
127
|
+
index$1_doSignature as doSignature,
|
128
|
+
index$1_doVerifySignature as doVerifySignature,
|
129
|
+
index$1_getHash as getHash,
|
130
|
+
index$1_getPublicKeyFromPrivateKey as getPublicKeyFromPrivateKey,
|
131
|
+
index$1_getPoint as getPoint,
|
132
|
+
index$1_initRNGPool as initRNGPool,
|
133
|
+
index$1_calculateSharedKey as calculateSharedKey,
|
134
|
+
index$1_KeyPair as KeyPair,
|
135
|
+
index$1_generateKeyPairHex as generateKeyPairHex,
|
136
|
+
index$1_compressPublicKeyHex as compressPublicKeyHex,
|
137
|
+
index$1_utf8ToHex as utf8ToHex,
|
138
|
+
index$1_leftPad as leftPad,
|
139
|
+
index$1_arrayToHex as arrayToHex,
|
140
|
+
index$1_arrayToUtf8 as arrayToUtf8,
|
141
|
+
index$1_hexToArray as hexToArray,
|
142
|
+
index$1_verifyPublicKey as verifyPublicKey,
|
143
|
+
index$1_comparePublicKeyHex as comparePublicKeyHex,
|
137
144
|
};
|
138
145
|
}
|
139
146
|
|
140
|
-
/**
|
141
|
-
* 补全16进制字符串
|
142
|
-
*/
|
143
|
-
/**
|
144
|
-
* utf8 串转字节数组
|
145
|
-
*/
|
146
|
-
declare function utf8ToArray(str: string): Uint8Array;
|
147
147
|
declare function sm3(input: string | Uint8Array, options?: {
|
148
148
|
key: Uint8Array | string;
|
149
149
|
mode?: 'hmac' | 'mac';
|
150
150
|
}): string;
|
151
151
|
|
152
|
-
declare const index$1_utf8ToArray: typeof utf8ToArray;
|
153
|
-
declare const index$1_sm3: typeof sm3;
|
154
|
-
declare namespace index$1 {
|
155
|
-
export {
|
156
|
-
index$1_utf8ToArray as utf8ToArray,
|
157
|
-
index$1_sm3 as sm3,
|
158
|
-
};
|
159
|
-
}
|
160
|
-
|
161
152
|
interface SM4Options {
|
162
153
|
padding?: 'pkcs#7' | 'pkcs#5' | 'none' | null;
|
163
154
|
mode?: 'cbc' | 'ecb';
|
@@ -191,4 +182,4 @@ declare namespace index {
|
|
191
182
|
};
|
192
183
|
}
|
193
184
|
|
194
|
-
export { index$
|
185
|
+
export { index$1 as sm2, sm3, index as sm4 };
|