sm-crypto-v2 0.3.13 → 1.2.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 +23 -0
- package/README.md +8 -0
- package/dist/index.d.ts +5 -224
- package/dist/index.js +304 -435
- package/dist/index.mjs +297 -434
- package/package.json +5 -5
- package/pnpm-lock.yaml +14 -7
- package/src/sm2/asn1.ts +15 -12
- package/src/sm2/bn.ts +4 -0
- package/src/sm2/ec.ts +79 -317
- package/src/sm2/index.ts +83 -54
- package/src/sm2/utils.ts +29 -57
package/src/sm2/index.ts
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
/* eslint-disable no-use-before-define */
|
2
|
-
import { BigInteger } from 'jsbn'
|
3
2
|
import { encodeDer, decodeDer } from './asn1'
|
4
|
-
import { arrayToHex, arrayToUtf8, concatArray,
|
3
|
+
import { arrayToHex, arrayToUtf8, concatArray, generateKeyPairHex, hexToArray, leftPad, utf8ToHex } from './utils'
|
5
4
|
import { sm3 } from './sm3'
|
6
5
|
export * from './utils'
|
7
|
-
|
6
|
+
import * as mod from '@noble/curves/abstract/modular';
|
7
|
+
import * as utils from '@noble/curves/abstract/utils';
|
8
|
+
import { sm2Curve } from './ec';
|
9
|
+
import { ONE, ZERO } from './bn';
|
10
|
+
|
11
|
+
// const { G, curve, n } = generateEcparam()
|
8
12
|
const C1C2C3 = 0
|
9
13
|
|
10
14
|
/**
|
@@ -13,19 +17,21 @@ const C1C2C3 = 0
|
|
13
17
|
export function doEncrypt(msg: string | Uint8Array, publicKey: string, cipherMode = 1) {
|
14
18
|
|
15
19
|
const msgArr = typeof msg === 'string' ? hexToArray(utf8ToHex(msg)) : Uint8Array.from(msg)
|
16
|
-
const publicKeyPoint =
|
20
|
+
const publicKeyPoint = sm2Curve.ProjectivePoint.fromHex(publicKey)
|
21
|
+
// const publicKeyPoint = getGlobalCurve().decodePointHex(publicKey) // 先将公钥转成点
|
17
22
|
|
18
23
|
const keypair = generateKeyPairHex()
|
19
|
-
const k =
|
24
|
+
const k = utils.hexToNumber(keypair.privateKey)
|
25
|
+
// const k = new BigInteger(keypair.privateKey, 16) // 随机数 k
|
20
26
|
|
21
27
|
// c1 = k * G
|
22
28
|
let c1 = keypair.publicKey
|
23
29
|
if (c1.length > 128) c1 = c1.substring(c1.length - 128)
|
24
|
-
|
25
|
-
// (x2, y2) = k * publicKey
|
26
30
|
const p = publicKeyPoint!.multiply(k)
|
27
|
-
|
28
|
-
|
31
|
+
|
32
|
+
// (x2, y2) = k * publicKey
|
33
|
+
const x2 = hexToArray(leftPad(utils.numberToHexUnpadded(p.x), 64))
|
34
|
+
const y2 = hexToArray(leftPad(utils.numberToHexUnpadded(p.y), 64))
|
29
35
|
|
30
36
|
// c3 = hash(x2 || msg || y2)
|
31
37
|
const c3 = arrayToHex(Array.from(sm3(concatArray(x2, msgArr, y2))));
|
@@ -67,7 +73,8 @@ export function doDecrypt(encryptData: string, privateKey: string, cipherMode?:
|
|
67
73
|
export function doDecrypt(encryptData: string, privateKey: string, cipherMode = 1, {
|
68
74
|
output = 'string',
|
69
75
|
} = {}) {
|
70
|
-
const privateKeyInteger = new BigInteger(privateKey, 16)
|
76
|
+
// const privateKeyInteger = new BigInteger(privateKey, 16)
|
77
|
+
const privateKeyInteger = utils.hexToNumber(privateKey)
|
71
78
|
|
72
79
|
let c3 = encryptData.substring(128, 128 + 64)
|
73
80
|
let c2 = encryptData.substring(128 + 64)
|
@@ -78,11 +85,14 @@ export function doDecrypt(encryptData: string, privateKey: string, cipherMode =
|
|
78
85
|
}
|
79
86
|
|
80
87
|
const msg = hexToArray(c2)
|
81
|
-
const c1 = getGlobalCurve().decodePointHex('04' + encryptData.substring(0, 128))!
|
88
|
+
// const c1 = getGlobalCurve().decodePointHex('04' + encryptData.substring(0, 128))!
|
89
|
+
const c1 = sm2Curve.ProjectivePoint.fromHex('04' + encryptData.substring(0, 128))!
|
82
90
|
|
83
91
|
const p = c1.multiply(privateKeyInteger)
|
84
|
-
const x2 = hexToArray(leftPad(p.getX().toBigInteger().toRadix(16), 64))
|
85
|
-
const y2 = hexToArray(leftPad(p.getY().toBigInteger().toRadix(16), 64))
|
92
|
+
// const x2 = hexToArray(leftPad(p.getX().toBigInteger().toRadix(16), 64))
|
93
|
+
// const y2 = hexToArray(leftPad(p.getY().toBigInteger().toRadix(16), 64))
|
94
|
+
const x2 = hexToArray(leftPad(utils.numberToHexUnpadded(p.x), 64))
|
95
|
+
const y2 = hexToArray(leftPad(utils.numberToHexUnpadded(p.y), 64))
|
86
96
|
let ct = 1
|
87
97
|
let offset = 0
|
88
98
|
let t = new Uint8Array() // 256 位
|
@@ -114,8 +124,8 @@ export function doDecrypt(encryptData: string, privateKey: string, cipherMode =
|
|
114
124
|
}
|
115
125
|
|
116
126
|
export interface SignaturePoint {
|
117
|
-
k:
|
118
|
-
x1:
|
127
|
+
k: bigint
|
128
|
+
x1: bigint
|
119
129
|
}
|
120
130
|
|
121
131
|
/**
|
@@ -135,13 +145,13 @@ export function doSignature(msg: Uint8Array | string, privateKey: string, option
|
|
135
145
|
hashHex = getHash(hashHex, publicKey, userId)
|
136
146
|
}
|
137
147
|
|
138
|
-
const dA =
|
139
|
-
const e =
|
148
|
+
const dA = utils.hexToNumber(privateKey)
|
149
|
+
const e = utils.hexToNumber(hashHex)
|
140
150
|
|
141
151
|
// k
|
142
|
-
let k:
|
143
|
-
let r:
|
144
|
-
let s:
|
152
|
+
let k: bigint | null = null
|
153
|
+
let r: bigint | null = null
|
154
|
+
let s: bigint | null = null
|
145
155
|
|
146
156
|
do {
|
147
157
|
do {
|
@@ -154,16 +164,16 @@ export function doSignature(msg: Uint8Array | string, privateKey: string, option
|
|
154
164
|
k = point.k
|
155
165
|
|
156
166
|
// r = (e + x1) mod n
|
157
|
-
r = e.add(point.x1).mod(n)
|
158
|
-
|
167
|
+
// r = e.add(point.x1).mod(n)
|
168
|
+
r = mod.mod(e + point.x1, sm2Curve.CURVE.n)
|
169
|
+
} while (r === ZERO || (r + k) === sm2Curve.CURVE.n)
|
159
170
|
|
160
171
|
// s = ((1 + dA)^-1 * (k - r * dA)) mod n
|
161
|
-
s = dA.add(BigInteger.ONE).modInverse(n).multiply(k.subtract(r.multiply(dA))).mod(n)
|
162
|
-
|
163
|
-
|
172
|
+
// s = dA.add(BigInteger.ONE).modInverse(n).multiply(k.subtract(r.multiply(dA))).mod(n)
|
173
|
+
s = mod.mod(mod.invert(dA + ONE, sm2Curve.CURVE.n) * (k - r * dA), sm2Curve.CURVE.n)
|
174
|
+
} while (s === ZERO)
|
164
175
|
if (der) return encodeDer(r, s) // asn.1 der 编码
|
165
|
-
|
166
|
-
return leftPad(r.toString(16), 64) + leftPad(s.toString(16), 64)
|
176
|
+
return leftPad(utils.numberToHexUnpadded(r), 64) + leftPad(utils.numberToHexUnpadded(s), 64)
|
167
177
|
}
|
168
178
|
|
169
179
|
/**
|
@@ -183,32 +193,40 @@ export function doVerifySignature(msg: string | Uint8Array, signHex: string, pub
|
|
183
193
|
hashHex = typeof msg === 'string' ? utf8ToHex(msg) : arrayToHex(Array.from(msg))
|
184
194
|
}
|
185
195
|
|
186
|
-
let r:
|
187
|
-
let s:
|
196
|
+
let r: bigint;
|
197
|
+
let s: bigint;
|
188
198
|
if (der) {
|
189
199
|
const decodeDerObj = decodeDer(signHex) // asn.1 der 解码
|
190
200
|
r = decodeDerObj.r
|
191
201
|
s = decodeDerObj.s
|
192
202
|
} else {
|
193
|
-
r = new BigInteger(signHex.substring(0, 64), 16)
|
194
|
-
s = new BigInteger(signHex.substring(64), 16)
|
203
|
+
// r = new BigInteger(signHex.substring(0, 64), 16)
|
204
|
+
// s = new BigInteger(signHex.substring(64), 16)
|
205
|
+
r = utils.hexToNumber(signHex.substring(0, 64))
|
206
|
+
s = utils.hexToNumber(signHex.substring(64))
|
195
207
|
}
|
196
|
-
|
197
|
-
const PA = curve.decodePointHex(publicKey)!
|
198
|
-
const
|
199
|
-
|
208
|
+
|
209
|
+
// const PA = curve.decodePointHex(publicKey)!
|
210
|
+
const PA = sm2Curve.ProjectivePoint.fromHex(publicKey)!
|
211
|
+
// const e = new BigInteger(hashHex, 16)
|
212
|
+
const e = utils.hexToNumber(hashHex)
|
213
|
+
|
200
214
|
// t = (r + s) mod n
|
201
|
-
const t = r.add(s).mod(n)
|
215
|
+
// const t = r.add(s).mod(n)
|
216
|
+
const t = mod.mod(r + s, sm2Curve.CURVE.n)
|
202
217
|
|
203
|
-
if (t
|
218
|
+
if (t === ZERO) return false
|
204
219
|
|
205
220
|
// x1y1 = s * G + t * PA
|
206
|
-
const x1y1 = G.multiply(s).add(PA.multiply(t))
|
221
|
+
// const x1y1 = G.multiply(s).add(PA.multiply(t))
|
222
|
+
const x1y1 = sm2Curve.ProjectivePoint.BASE.multiply(s).add(PA.multiply(t))
|
207
223
|
|
208
224
|
// R = (e + x1) mod n
|
209
|
-
const R = e.add(x1y1.getX().toBigInteger()).mod(n)
|
225
|
+
// const R = e.add(x1y1.getX().toBigInteger()).mod(n)
|
226
|
+
const R = mod.mod(e + x1y1.x, sm2Curve.CURVE.n)
|
210
227
|
|
211
|
-
return r.equals(R)
|
228
|
+
// return r.equals(R)
|
229
|
+
return r === R
|
212
230
|
}
|
213
231
|
|
214
232
|
/**
|
@@ -217,19 +235,25 @@ export function doVerifySignature(msg: string | Uint8Array, signHex: string, pub
|
|
217
235
|
export function getHash(hashHex: string | Uint8Array, publicKey: string, userId = '1234567812345678') {
|
218
236
|
// z = hash(entl || userId || a || b || gx || gy || px || py)
|
219
237
|
userId = utf8ToHex(userId)
|
220
|
-
const a = leftPad(
|
221
|
-
const b = leftPad(G.curve.b.toBigInteger().toRadix(16), 64)
|
222
|
-
const
|
223
|
-
const
|
238
|
+
const a = leftPad(utils.numberToHexUnpadded(sm2Curve.CURVE.a), 64)
|
239
|
+
// const b = leftPad(G.curve.b.toBigInteger().toRadix(16), 64)
|
240
|
+
const b = leftPad(utils.numberToHexUnpadded(sm2Curve.CURVE.b), 64)
|
241
|
+
// const gx = leftPad(G.getX().toBigInteger().toRadix(16), 64)
|
242
|
+
const gx = leftPad(utils.numberToHexUnpadded(sm2Curve.ProjectivePoint.BASE.x), 64)
|
243
|
+
// const gy = leftPad(G.getY().toBigInteger().toRadix(16), 64)
|
244
|
+
const gy = leftPad(utils.numberToHexUnpadded(sm2Curve.ProjectivePoint.BASE.y), 64)
|
224
245
|
let px: string
|
225
246
|
let py: string
|
226
247
|
if (publicKey.length === 128) {
|
227
248
|
px = publicKey.substring(0, 64)
|
228
249
|
py = publicKey.substring(64, 128)
|
229
250
|
} else {
|
230
|
-
const point = G.curve.decodePointHex(publicKey)!
|
231
|
-
|
232
|
-
|
251
|
+
// const point = G.curve.decodePointHex(publicKey)!
|
252
|
+
const point = sm2Curve.ProjectivePoint.fromHex(publicKey)!
|
253
|
+
// px = leftPad(point.getX().toBigInteger().toRadix(16), 64)
|
254
|
+
px = leftPad(utils.numberToHexUnpadded(point.x), 64)
|
255
|
+
// py = leftPad(point.getY().toBigInteger().toRadix(16), 64)
|
256
|
+
py = leftPad(utils.numberToHexUnpadded(point.y), 64)
|
233
257
|
}
|
234
258
|
const data = hexToArray(userId + a + b + gx + gy + px + py)
|
235
259
|
|
@@ -245,10 +269,13 @@ export function getHash(hashHex: string | Uint8Array, publicKey: string, userId
|
|
245
269
|
* 计算公钥
|
246
270
|
*/
|
247
271
|
export function getPublicKeyFromPrivateKey(privateKey: string) {
|
248
|
-
const
|
249
|
-
const
|
250
|
-
|
251
|
-
|
272
|
+
const pubKey = sm2Curve.getPublicKey(privateKey, false)
|
273
|
+
const pubPad = leftPad(utils.bytesToHex(pubKey), 64)
|
274
|
+
return pubPad
|
275
|
+
// const PA = G.multiply(new BigInteger(privateKey, 16))
|
276
|
+
// const x = leftPad(PA.getX().toBigInteger().toString(16), 64)
|
277
|
+
// const y = leftPad(PA.getY().toBigInteger().toString(16), 64)
|
278
|
+
// return '04' + x + y
|
252
279
|
}
|
253
280
|
|
254
281
|
/**
|
@@ -256,12 +283,14 @@ export function getPublicKeyFromPrivateKey(privateKey: string) {
|
|
256
283
|
*/
|
257
284
|
export function getPoint() {
|
258
285
|
const keypair = generateKeyPairHex()
|
259
|
-
const PA = curve.decodePointHex(keypair.publicKey)
|
286
|
+
// const PA = curve.decodePointHex(keypair.publicKey)
|
287
|
+
const PA = sm2Curve.ProjectivePoint.fromHex(keypair.publicKey)
|
288
|
+
const k = utils.hexToNumber(keypair.privateKey)
|
260
289
|
|
261
290
|
return {
|
262
291
|
...keypair,
|
263
|
-
k
|
264
|
-
x1: PA!.
|
292
|
+
k,
|
293
|
+
x1: PA!.x,
|
265
294
|
}
|
266
295
|
}
|
267
296
|
|
package/src/sm2/utils.ts
CHANGED
@@ -1,57 +1,28 @@
|
|
1
1
|
/* eslint-disable no-bitwise, no-mixed-operators, no-use-before-define, max-len */
|
2
|
-
import
|
3
|
-
import { ECCurveFp } from './ec'
|
2
|
+
import * as utils from '@noble/curves/abstract/utils';
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
}
|
9
|
-
}
|
10
|
-
|
11
|
-
const rng = new SecureRandom()
|
12
|
-
const {curve, G, n} = generateEcparam()
|
13
|
-
|
14
|
-
/**
|
15
|
-
* 获取公共椭圆曲线
|
16
|
-
*/
|
17
|
-
export function getGlobalCurve() {
|
18
|
-
return curve
|
19
|
-
}
|
20
|
-
|
21
|
-
/**
|
22
|
-
* 生成ecparam
|
23
|
-
*/
|
24
|
-
export function generateEcparam() {
|
25
|
-
// 椭圆曲线
|
26
|
-
const p = new BigInteger('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF', 16)
|
27
|
-
const a = new BigInteger('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC', 16)
|
28
|
-
const b = new BigInteger('28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', 16)
|
29
|
-
const curve = new ECCurveFp(p, a, b)
|
30
|
-
|
31
|
-
// 基点
|
32
|
-
const gxHex = '32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7'
|
33
|
-
const gyHex = 'BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0'
|
34
|
-
const G = curve.decodePointHex('04' + gxHex + gyHex)!
|
35
|
-
|
36
|
-
const n = new BigInteger('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123', 16)
|
37
|
-
|
38
|
-
return {curve, G, n}
|
39
|
-
}
|
4
|
+
import { sm2Curve, sm2Fp } from './ec';
|
5
|
+
import { mod } from '@noble/curves/abstract/modular';
|
6
|
+
import { TWO, ZERO } from './bn';
|
40
7
|
|
41
8
|
/**
|
42
9
|
* 生成密钥对:publicKey = privateKey * G
|
43
10
|
*/
|
44
|
-
export function generateKeyPairHex(
|
45
|
-
const random = typeof a === 'string' ? new BigInteger(a, b) :
|
46
|
-
|
47
|
-
const d = random.mod(n.subtract(BigInteger.ONE)).add(BigInteger.ONE) // 随机数
|
48
|
-
const privateKey = leftPad(d.toString(16), 64)
|
49
|
-
|
50
|
-
const P = G!.multiply(d) // P = dG,p 为公钥,d 为私钥
|
51
|
-
const Px = leftPad(P.getX().toBigInteger().toString(16), 64)
|
52
|
-
const Py = leftPad(P.getY().toBigInteger().toString(16), 64)
|
53
|
-
const publicKey = '04' + Px + Py
|
54
|
-
|
11
|
+
export function generateKeyPairHex() {
|
12
|
+
// const random = typeof a === 'string' ? new BigInteger(a, b) :
|
13
|
+
// a ? new BigInteger(a, b!, c!) : new BigInteger(n.bitLength(), rng)
|
14
|
+
// const d = random.mod(n.subtract(BigInteger.ONE)).add(BigInteger.ONE) // 随机数
|
15
|
+
// const privateKey = leftPad(d.toString(16), 64)
|
16
|
+
|
17
|
+
// const P = G!.multiply(d) // P = dG,p 为公钥,d 为私钥
|
18
|
+
// const Px = leftPad(P.getX().toBigInteger().toString(16), 64)
|
19
|
+
// const Py = leftPad(P.getY().toBigInteger().toString(16), 64)
|
20
|
+
// const publicKey = '04' + Px + Py
|
21
|
+
const privateKey = sm2Curve.utils.randomPrivateKey();
|
22
|
+
const publicKey = sm2Curve.getPublicKey(privateKey, false);
|
23
|
+
const privPad = leftPad(utils.bytesToHex(privateKey), 64)
|
24
|
+
const pubPad = leftPad(utils.bytesToHex(publicKey), 64)
|
25
|
+
return {privateKey: privPad, publicKey: pubPad}
|
55
26
|
}
|
56
27
|
|
57
28
|
/**
|
@@ -62,10 +33,10 @@ export function compressPublicKeyHex(s: string) {
|
|
62
33
|
|
63
34
|
const len = (s.length - 2) / 2
|
64
35
|
const xHex = s.substring(2, 2 + len)
|
65
|
-
const y =
|
36
|
+
const y = utils.hexToNumber(s.substring(len + 2, len + len + 2))
|
66
37
|
|
67
38
|
let prefix = '03'
|
68
|
-
if (
|
39
|
+
if (mod(y, TWO) === ZERO) prefix = '02'
|
69
40
|
return prefix + xHex
|
70
41
|
}
|
71
42
|
|
@@ -164,24 +135,25 @@ export function hexToArray(hexStr: string) {
|
|
164
135
|
* 验证公钥是否为椭圆曲线上的点
|
165
136
|
*/
|
166
137
|
export function verifyPublicKey(publicKey: string) {
|
167
|
-
const point =
|
138
|
+
const point = sm2Curve.ProjectivePoint.fromHex(publicKey)
|
168
139
|
if (!point) return false
|
169
140
|
|
170
|
-
const x = point.
|
171
|
-
const y = point.
|
172
|
-
|
141
|
+
const x = point.x
|
142
|
+
const y = point.y
|
173
143
|
// 验证 y^2 是否等于 x^3 + ax + b
|
174
|
-
return y.square().equals(x.multiply(x.square()).add(x.multiply(curve.a)).add(curve.b))
|
144
|
+
// return y.square().equals(x.multiply(x.square()).add(x.multiply(curve.a)).add(curve.b))
|
145
|
+
return sm2Fp.sqr(y) === sm2Fp.add(sm2Fp.add(sm2Fp.mul(x, sm2Fp.sqr(x)), sm2Fp.mul(x, sm2Curve.CURVE.a)), sm2Curve.CURVE.b)
|
146
|
+
// return y ** 2n === (x ** 3n + sm2Curve.CURVE.a * x + sm2Curve.CURVE.b)
|
175
147
|
}
|
176
148
|
|
177
149
|
/**
|
178
150
|
* 验证公钥是否等价,等价返回true
|
179
151
|
*/
|
180
152
|
export function comparePublicKeyHex(publicKey1: string, publicKey2: string) {
|
181
|
-
const point1 =
|
153
|
+
const point1 = sm2Curve.ProjectivePoint.fromHex(publicKey1)
|
182
154
|
if (!point1) return false
|
183
155
|
|
184
|
-
const point2 =
|
156
|
+
const point2 = sm2Curve.ProjectivePoint.fromHex(publicKey2)
|
185
157
|
if (!point2) return false
|
186
158
|
|
187
159
|
return point1.equals(point2)
|