sm-crypto-v2 1.9.2 → 1.10.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 +14 -0
- package/dist/index.d.mts +27 -5
- package/dist/index.d.ts +27 -5
- package/dist/index.js +139 -14
- package/dist/index.mjs +139 -14
- package/miniprogram_dist/index.d.ts +27 -5
- package/miniprogram_dist/index.js +146 -14
- package/package.json +6 -1
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,20 @@
|
|
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.10.0](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.9.3...v1.10.0) (2025-04-14)
|
6
|
+
|
7
|
+
|
8
|
+
### Features
|
9
|
+
|
10
|
+
* **sm4:** support gcm mode for `sm4` ([2c6a0df](https://github.com/Cubelrti/sm-crypto-v2/commit/2c6a0df8d591d802fd4816c6b1824e20e0b23e31))
|
11
|
+
|
12
|
+
### [1.9.3](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.9.2...v1.9.3) (2024-10-10)
|
13
|
+
|
14
|
+
|
15
|
+
### Bug Fixes
|
16
|
+
|
17
|
+
* **sm2:** utf8 to hex [#15](https://github.com/Cubelrti/sm-crypto-v2/issues/15) ([16a714a](https://github.com/Cubelrti/sm-crypto-v2/commit/16a714ad8775381c21b814fab6b1d57c263b3c65))
|
18
|
+
|
5
19
|
### [1.9.2](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.9.1...v1.9.2) (2024-08-16)
|
6
20
|
|
7
21
|
|
package/dist/index.d.mts
CHANGED
@@ -146,30 +146,52 @@ declare function sm3(input: string | Uint8Array, options?: {
|
|
146
146
|
|
147
147
|
interface SM4Options {
|
148
148
|
padding?: 'pkcs#7' | 'pkcs#5' | 'none' | null;
|
149
|
-
mode?: 'cbc' | 'ecb';
|
149
|
+
mode?: 'cbc' | 'ecb' | 'gcm';
|
150
150
|
iv?: Uint8Array | string;
|
151
151
|
output?: 'string' | 'array';
|
152
|
+
associatedData?: Uint8Array | string;
|
153
|
+
outputTag?: boolean;
|
154
|
+
tag?: Uint8Array | string;
|
152
155
|
}
|
153
|
-
declare function sm4(inArray: Uint8Array | string, key: Uint8Array | string, cryptFlag: 0 | 1, options?: SM4Options): string | Uint8Array
|
156
|
+
declare function sm4(inArray: Uint8Array | string, key: Uint8Array | string, cryptFlag: 0 | 1, options?: SM4Options): string | Uint8Array | {
|
157
|
+
output: Uint8Array;
|
158
|
+
tag?: Uint8Array | undefined;
|
159
|
+
} | {
|
160
|
+
output: string;
|
161
|
+
tag: string | undefined;
|
162
|
+
};
|
163
|
+
interface GCMResult<T = Uint8Array | string> {
|
164
|
+
output: T;
|
165
|
+
tag?: T;
|
166
|
+
}
|
167
|
+
declare function encrypt(inArray: Uint8Array | string, key: Uint8Array | string, options: {
|
168
|
+
mode: 'gcm';
|
169
|
+
output: 'array';
|
170
|
+
} & SM4Options): GCMResult<Uint8Array>;
|
171
|
+
declare function encrypt(inArray: Uint8Array | string, key: Uint8Array | string, options: {
|
172
|
+
mode: 'gcm';
|
173
|
+
output?: 'string';
|
174
|
+
} & SM4Options): GCMResult<string>;
|
154
175
|
declare function encrypt(inArray: Uint8Array | string, key: Uint8Array | string, options?: {
|
155
176
|
output: 'array';
|
156
177
|
} & SM4Options): Uint8Array;
|
157
178
|
declare function encrypt(inArray: Uint8Array | string, key: Uint8Array | string, options?: {
|
158
|
-
output
|
179
|
+
output?: 'string';
|
159
180
|
} & SM4Options): string;
|
160
181
|
declare function decrypt(inArray: Uint8Array | string, key: Uint8Array | string, options?: {
|
161
182
|
output: 'array';
|
162
183
|
} & SM4Options): Uint8Array;
|
163
184
|
declare function decrypt(inArray: Uint8Array | string, key: Uint8Array | string, options?: {
|
164
|
-
output
|
185
|
+
output?: 'string';
|
165
186
|
} & SM4Options): string;
|
166
187
|
|
188
|
+
type index_GCMResult<T = Uint8Array | string> = GCMResult<T>;
|
167
189
|
type index_SM4Options = SM4Options;
|
168
190
|
declare const index_decrypt: typeof decrypt;
|
169
191
|
declare const index_encrypt: typeof encrypt;
|
170
192
|
declare const index_sm4: typeof sm4;
|
171
193
|
declare namespace index {
|
172
|
-
export { type index_SM4Options as SM4Options, index_decrypt as decrypt, index_encrypt as encrypt, index_sm4 as sm4 };
|
194
|
+
export { type index_GCMResult as GCMResult, type index_SM4Options as SM4Options, index_decrypt as decrypt, index_encrypt as encrypt, index_sm4 as sm4 };
|
173
195
|
}
|
174
196
|
|
175
197
|
export { index$1 as sm2, sm3, index as sm4 };
|
package/dist/index.d.ts
CHANGED
@@ -146,30 +146,52 @@ declare function sm3(input: string | Uint8Array, options?: {
|
|
146
146
|
|
147
147
|
interface SM4Options {
|
148
148
|
padding?: 'pkcs#7' | 'pkcs#5' | 'none' | null;
|
149
|
-
mode?: 'cbc' | 'ecb';
|
149
|
+
mode?: 'cbc' | 'ecb' | 'gcm';
|
150
150
|
iv?: Uint8Array | string;
|
151
151
|
output?: 'string' | 'array';
|
152
|
+
associatedData?: Uint8Array | string;
|
153
|
+
outputTag?: boolean;
|
154
|
+
tag?: Uint8Array | string;
|
152
155
|
}
|
153
|
-
declare function sm4(inArray: Uint8Array | string, key: Uint8Array | string, cryptFlag: 0 | 1, options?: SM4Options): string | Uint8Array
|
156
|
+
declare function sm4(inArray: Uint8Array | string, key: Uint8Array | string, cryptFlag: 0 | 1, options?: SM4Options): string | Uint8Array | {
|
157
|
+
output: Uint8Array;
|
158
|
+
tag?: Uint8Array | undefined;
|
159
|
+
} | {
|
160
|
+
output: string;
|
161
|
+
tag: string | undefined;
|
162
|
+
};
|
163
|
+
interface GCMResult<T = Uint8Array | string> {
|
164
|
+
output: T;
|
165
|
+
tag?: T;
|
166
|
+
}
|
167
|
+
declare function encrypt(inArray: Uint8Array | string, key: Uint8Array | string, options: {
|
168
|
+
mode: 'gcm';
|
169
|
+
output: 'array';
|
170
|
+
} & SM4Options): GCMResult<Uint8Array>;
|
171
|
+
declare function encrypt(inArray: Uint8Array | string, key: Uint8Array | string, options: {
|
172
|
+
mode: 'gcm';
|
173
|
+
output?: 'string';
|
174
|
+
} & SM4Options): GCMResult<string>;
|
154
175
|
declare function encrypt(inArray: Uint8Array | string, key: Uint8Array | string, options?: {
|
155
176
|
output: 'array';
|
156
177
|
} & SM4Options): Uint8Array;
|
157
178
|
declare function encrypt(inArray: Uint8Array | string, key: Uint8Array | string, options?: {
|
158
|
-
output
|
179
|
+
output?: 'string';
|
159
180
|
} & SM4Options): string;
|
160
181
|
declare function decrypt(inArray: Uint8Array | string, key: Uint8Array | string, options?: {
|
161
182
|
output: 'array';
|
162
183
|
} & SM4Options): Uint8Array;
|
163
184
|
declare function decrypt(inArray: Uint8Array | string, key: Uint8Array | string, options?: {
|
164
|
-
output
|
185
|
+
output?: 'string';
|
165
186
|
} & SM4Options): string;
|
166
187
|
|
188
|
+
type index_GCMResult<T = Uint8Array | string> = GCMResult<T>;
|
167
189
|
type index_SM4Options = SM4Options;
|
168
190
|
declare const index_decrypt: typeof decrypt;
|
169
191
|
declare const index_encrypt: typeof encrypt;
|
170
192
|
declare const index_sm4: typeof sm4;
|
171
193
|
declare namespace index {
|
172
|
-
export { type index_SM4Options as SM4Options, index_decrypt as decrypt, index_encrypt as encrypt, index_sm4 as sm4 };
|
194
|
+
export { type index_GCMResult as GCMResult, type index_SM4Options as SM4Options, index_decrypt as decrypt, index_encrypt as encrypt, index_sm4 as sm4 };
|
173
195
|
}
|
174
196
|
|
175
197
|
export { index$1 as sm2, sm3, index as sm4 };
|
package/dist/index.js
CHANGED
@@ -636,19 +636,8 @@ function compressPublicKeyHex(s) {
|
|
636
636
|
return prefix + xHex;
|
637
637
|
}
|
638
638
|
function utf8ToHex(input) {
|
639
|
-
|
640
|
-
|
641
|
-
const words = new Uint32Array((length >>> 2) + 1);
|
642
|
-
for (let i = 0; i < length; i++) {
|
643
|
-
words[i >>> 2] |= (input.charCodeAt(i) & 255) << 24 - i % 4 * 8;
|
644
|
-
}
|
645
|
-
const hexChars = [];
|
646
|
-
for (let i = 0; i < length; i++) {
|
647
|
-
const bite = words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
|
648
|
-
hexChars.push((bite >>> 4).toString(16));
|
649
|
-
hexChars.push((bite & 15).toString(16));
|
650
|
-
}
|
651
|
-
return hexChars.join("");
|
639
|
+
const bytes = utils2.utf8ToBytes(input);
|
640
|
+
return utils2.bytesToHex(bytes);
|
652
641
|
}
|
653
642
|
function leftPad(input, num) {
|
654
643
|
if (input.length >= num)
|
@@ -1009,6 +998,8 @@ __export(sm4_exports, {
|
|
1009
998
|
encrypt: () => encrypt,
|
1010
999
|
sm4: () => sm4
|
1011
1000
|
});
|
1001
|
+
var import_polyval = require("@noble/ciphers/_polyval");
|
1002
|
+
var import_utils11 = require("@noble/ciphers/utils");
|
1012
1003
|
var DECRYPT = 0;
|
1013
1004
|
var ROUND = 32;
|
1014
1005
|
var BLOCK = 16;
|
@@ -1396,14 +1387,148 @@ function sms4KeyExt(key, roundKey, cryptFlag) {
|
|
1396
1387
|
}
|
1397
1388
|
}
|
1398
1389
|
}
|
1390
|
+
function incrementCounter(counter) {
|
1391
|
+
for (let i = counter.length - 1; i >= 0; i--) {
|
1392
|
+
counter[i]++;
|
1393
|
+
if (counter[i] !== 0)
|
1394
|
+
break;
|
1395
|
+
}
|
1396
|
+
}
|
1397
|
+
function sm4Gcm(inArray, key, ivArray, aadArray, cryptFlag, tagArray) {
|
1398
|
+
const tagLength = 16;
|
1399
|
+
function deriveKeys() {
|
1400
|
+
const roundKey2 = new Uint32Array(ROUND);
|
1401
|
+
sms4KeyExt(key, roundKey2, 1);
|
1402
|
+
const authKey = new Uint8Array(16).fill(0);
|
1403
|
+
const h2 = new Uint8Array(16);
|
1404
|
+
sms4Crypt(authKey, h2, roundKey2);
|
1405
|
+
let j02;
|
1406
|
+
if (ivArray.length === 12) {
|
1407
|
+
j02 = new Uint8Array(16);
|
1408
|
+
j02.set(ivArray, 0);
|
1409
|
+
j02[15] = 1;
|
1410
|
+
} else {
|
1411
|
+
const g = import_polyval.ghash.create(h2);
|
1412
|
+
g.update(ivArray);
|
1413
|
+
const lenIv = new Uint8Array(16);
|
1414
|
+
const view = (0, import_utils11.createView)(lenIv);
|
1415
|
+
(0, import_utils11.setBigUint64)(view, 8, BigInt(ivArray.length * 8), false);
|
1416
|
+
g.update(lenIv);
|
1417
|
+
j02 = g.digest();
|
1418
|
+
}
|
1419
|
+
const counter2 = new Uint8Array(j02);
|
1420
|
+
incrementCounter(counter2);
|
1421
|
+
const tagMask2 = new Uint8Array(16);
|
1422
|
+
sms4Crypt(j02, tagMask2, roundKey2);
|
1423
|
+
return { roundKey: roundKey2, h: h2, j0: j02, counter: counter2, tagMask: tagMask2 };
|
1424
|
+
}
|
1425
|
+
function computeTag(h2, data) {
|
1426
|
+
const aadLength = aadArray.length;
|
1427
|
+
const dataLength = data.length;
|
1428
|
+
const g = import_polyval.ghash.create(h2);
|
1429
|
+
if (aadLength > 0) {
|
1430
|
+
g.update(aadArray);
|
1431
|
+
}
|
1432
|
+
g.update(data);
|
1433
|
+
const lenBlock = new Uint8Array(16);
|
1434
|
+
const view = (0, import_utils11.createView)(lenBlock);
|
1435
|
+
(0, import_utils11.setBigUint64)(view, 0, BigInt(aadLength * 8), false);
|
1436
|
+
(0, import_utils11.setBigUint64)(view, 8, BigInt(dataLength * 8), false);
|
1437
|
+
g.update(lenBlock);
|
1438
|
+
return g.digest();
|
1439
|
+
}
|
1440
|
+
const { roundKey, h, j0, counter, tagMask } = deriveKeys();
|
1441
|
+
if (cryptFlag === DECRYPT && tagArray) {
|
1442
|
+
const calculatedTag = computeTag(h, inArray);
|
1443
|
+
for (let i = 0; i < 16; i++) {
|
1444
|
+
calculatedTag[i] ^= tagMask[i];
|
1445
|
+
}
|
1446
|
+
let tagMatch = 0;
|
1447
|
+
for (let i = 0; i < 16; i++) {
|
1448
|
+
tagMatch |= calculatedTag[i] ^ tagArray[i];
|
1449
|
+
}
|
1450
|
+
if (tagMatch !== 0) {
|
1451
|
+
throw new Error("authentication tag mismatch");
|
1452
|
+
}
|
1453
|
+
}
|
1454
|
+
const outArray = new Uint8Array(inArray.length);
|
1455
|
+
let point = 0;
|
1456
|
+
let restLen = inArray.length;
|
1457
|
+
while (restLen >= BLOCK) {
|
1458
|
+
const blockOut = new Uint8Array(BLOCK);
|
1459
|
+
sms4Crypt(counter, blockOut, roundKey);
|
1460
|
+
for (let i = 0; i < BLOCK && i < restLen; i++) {
|
1461
|
+
outArray[point + i] = inArray[point + i] ^ blockOut[i];
|
1462
|
+
}
|
1463
|
+
incrementCounter(counter);
|
1464
|
+
point += BLOCK;
|
1465
|
+
restLen -= BLOCK;
|
1466
|
+
}
|
1467
|
+
if (restLen > 0) {
|
1468
|
+
const blockOut = new Uint8Array(BLOCK);
|
1469
|
+
sms4Crypt(counter, blockOut, roundKey);
|
1470
|
+
for (let i = 0; i < restLen; i++) {
|
1471
|
+
outArray[point + i] = inArray[point + i] ^ blockOut[i];
|
1472
|
+
}
|
1473
|
+
}
|
1474
|
+
if (cryptFlag !== DECRYPT) {
|
1475
|
+
const calculatedTag = computeTag(h, outArray);
|
1476
|
+
for (let i = 0; i < 16; i++) {
|
1477
|
+
calculatedTag[i] ^= tagMask[i];
|
1478
|
+
}
|
1479
|
+
return { output: outArray, tag: calculatedTag };
|
1480
|
+
}
|
1481
|
+
return { output: outArray };
|
1482
|
+
}
|
1399
1483
|
var blockOutput = new Uint8Array(16);
|
1400
1484
|
function sm4(inArray, key, cryptFlag, options = {}) {
|
1401
1485
|
let {
|
1402
1486
|
padding = "pkcs#7",
|
1403
1487
|
mode,
|
1404
1488
|
iv = new Uint8Array(16),
|
1405
|
-
output
|
1489
|
+
output,
|
1490
|
+
associatedData,
|
1491
|
+
outputTag,
|
1492
|
+
tag
|
1406
1493
|
} = options;
|
1494
|
+
if (mode === "gcm") {
|
1495
|
+
const keyArray = typeof key === "string" ? hexToArray(key) : Uint8Array.from(key);
|
1496
|
+
const ivArray = typeof iv === "string" ? hexToArray(iv) : Uint8Array.from(iv);
|
1497
|
+
const aadArray = associatedData ? typeof associatedData === "string" ? hexToArray(associatedData) : Uint8Array.from(associatedData) : new Uint8Array(0);
|
1498
|
+
let inputArray;
|
1499
|
+
if (typeof inArray === "string") {
|
1500
|
+
if (cryptFlag !== DECRYPT) {
|
1501
|
+
inputArray = utf8ToArray(inArray);
|
1502
|
+
} else {
|
1503
|
+
inputArray = hexToArray(inArray);
|
1504
|
+
}
|
1505
|
+
} else {
|
1506
|
+
inputArray = Uint8Array.from(inArray);
|
1507
|
+
}
|
1508
|
+
const tagArray = tag ? typeof tag === "string" ? hexToArray(tag) : Uint8Array.from(tag) : void 0;
|
1509
|
+
const result = sm4Gcm(inputArray, keyArray, ivArray, aadArray, cryptFlag, tagArray);
|
1510
|
+
if (output === "array") {
|
1511
|
+
if (outputTag && cryptFlag !== DECRYPT) {
|
1512
|
+
return result;
|
1513
|
+
}
|
1514
|
+
return result.output;
|
1515
|
+
} else {
|
1516
|
+
if (outputTag && cryptFlag !== DECRYPT) {
|
1517
|
+
return {
|
1518
|
+
output: bytesToHex(result.output),
|
1519
|
+
tag: result.tag ? bytesToHex(result.tag) : void 0
|
1520
|
+
};
|
1521
|
+
}
|
1522
|
+
if (cryptFlag !== DECRYPT) {
|
1523
|
+
return {
|
1524
|
+
output: bytesToHex(result.output),
|
1525
|
+
tag: result.tag ? bytesToHex(result.tag) : void 0
|
1526
|
+
};
|
1527
|
+
} else {
|
1528
|
+
return arrayToUtf8(result.output);
|
1529
|
+
}
|
1530
|
+
}
|
1531
|
+
}
|
1407
1532
|
if (mode === "cbc") {
|
1408
1533
|
if (typeof iv === "string")
|
1409
1534
|
iv = hexToArray(iv);
|
package/dist/index.mjs
CHANGED
@@ -604,19 +604,8 @@ function compressPublicKeyHex(s) {
|
|
604
604
|
return prefix + xHex;
|
605
605
|
}
|
606
606
|
function utf8ToHex(input) {
|
607
|
-
|
608
|
-
|
609
|
-
const words = new Uint32Array((length >>> 2) + 1);
|
610
|
-
for (let i = 0; i < length; i++) {
|
611
|
-
words[i >>> 2] |= (input.charCodeAt(i) & 255) << 24 - i % 4 * 8;
|
612
|
-
}
|
613
|
-
const hexChars = [];
|
614
|
-
for (let i = 0; i < length; i++) {
|
615
|
-
const bite = words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
|
616
|
-
hexChars.push((bite >>> 4).toString(16));
|
617
|
-
hexChars.push((bite & 15).toString(16));
|
618
|
-
}
|
619
|
-
return hexChars.join("");
|
607
|
+
const bytes = utils2.utf8ToBytes(input);
|
608
|
+
return utils2.bytesToHex(bytes);
|
620
609
|
}
|
621
610
|
function leftPad(input, num) {
|
622
611
|
if (input.length >= num)
|
@@ -977,6 +966,8 @@ __export(sm4_exports, {
|
|
977
966
|
encrypt: () => encrypt,
|
978
967
|
sm4: () => sm4
|
979
968
|
});
|
969
|
+
import { ghash } from "@noble/ciphers/_polyval";
|
970
|
+
import { createView as createView2, setBigUint64 as setBigUint642 } from "@noble/ciphers/utils";
|
980
971
|
var DECRYPT = 0;
|
981
972
|
var ROUND = 32;
|
982
973
|
var BLOCK = 16;
|
@@ -1364,14 +1355,148 @@ function sms4KeyExt(key, roundKey, cryptFlag) {
|
|
1364
1355
|
}
|
1365
1356
|
}
|
1366
1357
|
}
|
1358
|
+
function incrementCounter(counter) {
|
1359
|
+
for (let i = counter.length - 1; i >= 0; i--) {
|
1360
|
+
counter[i]++;
|
1361
|
+
if (counter[i] !== 0)
|
1362
|
+
break;
|
1363
|
+
}
|
1364
|
+
}
|
1365
|
+
function sm4Gcm(inArray, key, ivArray, aadArray, cryptFlag, tagArray) {
|
1366
|
+
const tagLength = 16;
|
1367
|
+
function deriveKeys() {
|
1368
|
+
const roundKey2 = new Uint32Array(ROUND);
|
1369
|
+
sms4KeyExt(key, roundKey2, 1);
|
1370
|
+
const authKey = new Uint8Array(16).fill(0);
|
1371
|
+
const h2 = new Uint8Array(16);
|
1372
|
+
sms4Crypt(authKey, h2, roundKey2);
|
1373
|
+
let j02;
|
1374
|
+
if (ivArray.length === 12) {
|
1375
|
+
j02 = new Uint8Array(16);
|
1376
|
+
j02.set(ivArray, 0);
|
1377
|
+
j02[15] = 1;
|
1378
|
+
} else {
|
1379
|
+
const g = ghash.create(h2);
|
1380
|
+
g.update(ivArray);
|
1381
|
+
const lenIv = new Uint8Array(16);
|
1382
|
+
const view = createView2(lenIv);
|
1383
|
+
setBigUint642(view, 8, BigInt(ivArray.length * 8), false);
|
1384
|
+
g.update(lenIv);
|
1385
|
+
j02 = g.digest();
|
1386
|
+
}
|
1387
|
+
const counter2 = new Uint8Array(j02);
|
1388
|
+
incrementCounter(counter2);
|
1389
|
+
const tagMask2 = new Uint8Array(16);
|
1390
|
+
sms4Crypt(j02, tagMask2, roundKey2);
|
1391
|
+
return { roundKey: roundKey2, h: h2, j0: j02, counter: counter2, tagMask: tagMask2 };
|
1392
|
+
}
|
1393
|
+
function computeTag(h2, data) {
|
1394
|
+
const aadLength = aadArray.length;
|
1395
|
+
const dataLength = data.length;
|
1396
|
+
const g = ghash.create(h2);
|
1397
|
+
if (aadLength > 0) {
|
1398
|
+
g.update(aadArray);
|
1399
|
+
}
|
1400
|
+
g.update(data);
|
1401
|
+
const lenBlock = new Uint8Array(16);
|
1402
|
+
const view = createView2(lenBlock);
|
1403
|
+
setBigUint642(view, 0, BigInt(aadLength * 8), false);
|
1404
|
+
setBigUint642(view, 8, BigInt(dataLength * 8), false);
|
1405
|
+
g.update(lenBlock);
|
1406
|
+
return g.digest();
|
1407
|
+
}
|
1408
|
+
const { roundKey, h, j0, counter, tagMask } = deriveKeys();
|
1409
|
+
if (cryptFlag === DECRYPT && tagArray) {
|
1410
|
+
const calculatedTag = computeTag(h, inArray);
|
1411
|
+
for (let i = 0; i < 16; i++) {
|
1412
|
+
calculatedTag[i] ^= tagMask[i];
|
1413
|
+
}
|
1414
|
+
let tagMatch = 0;
|
1415
|
+
for (let i = 0; i < 16; i++) {
|
1416
|
+
tagMatch |= calculatedTag[i] ^ tagArray[i];
|
1417
|
+
}
|
1418
|
+
if (tagMatch !== 0) {
|
1419
|
+
throw new Error("authentication tag mismatch");
|
1420
|
+
}
|
1421
|
+
}
|
1422
|
+
const outArray = new Uint8Array(inArray.length);
|
1423
|
+
let point = 0;
|
1424
|
+
let restLen = inArray.length;
|
1425
|
+
while (restLen >= BLOCK) {
|
1426
|
+
const blockOut = new Uint8Array(BLOCK);
|
1427
|
+
sms4Crypt(counter, blockOut, roundKey);
|
1428
|
+
for (let i = 0; i < BLOCK && i < restLen; i++) {
|
1429
|
+
outArray[point + i] = inArray[point + i] ^ blockOut[i];
|
1430
|
+
}
|
1431
|
+
incrementCounter(counter);
|
1432
|
+
point += BLOCK;
|
1433
|
+
restLen -= BLOCK;
|
1434
|
+
}
|
1435
|
+
if (restLen > 0) {
|
1436
|
+
const blockOut = new Uint8Array(BLOCK);
|
1437
|
+
sms4Crypt(counter, blockOut, roundKey);
|
1438
|
+
for (let i = 0; i < restLen; i++) {
|
1439
|
+
outArray[point + i] = inArray[point + i] ^ blockOut[i];
|
1440
|
+
}
|
1441
|
+
}
|
1442
|
+
if (cryptFlag !== DECRYPT) {
|
1443
|
+
const calculatedTag = computeTag(h, outArray);
|
1444
|
+
for (let i = 0; i < 16; i++) {
|
1445
|
+
calculatedTag[i] ^= tagMask[i];
|
1446
|
+
}
|
1447
|
+
return { output: outArray, tag: calculatedTag };
|
1448
|
+
}
|
1449
|
+
return { output: outArray };
|
1450
|
+
}
|
1367
1451
|
var blockOutput = new Uint8Array(16);
|
1368
1452
|
function sm4(inArray, key, cryptFlag, options = {}) {
|
1369
1453
|
let {
|
1370
1454
|
padding = "pkcs#7",
|
1371
1455
|
mode,
|
1372
1456
|
iv = new Uint8Array(16),
|
1373
|
-
output
|
1457
|
+
output,
|
1458
|
+
associatedData,
|
1459
|
+
outputTag,
|
1460
|
+
tag
|
1374
1461
|
} = options;
|
1462
|
+
if (mode === "gcm") {
|
1463
|
+
const keyArray = typeof key === "string" ? hexToArray(key) : Uint8Array.from(key);
|
1464
|
+
const ivArray = typeof iv === "string" ? hexToArray(iv) : Uint8Array.from(iv);
|
1465
|
+
const aadArray = associatedData ? typeof associatedData === "string" ? hexToArray(associatedData) : Uint8Array.from(associatedData) : new Uint8Array(0);
|
1466
|
+
let inputArray;
|
1467
|
+
if (typeof inArray === "string") {
|
1468
|
+
if (cryptFlag !== DECRYPT) {
|
1469
|
+
inputArray = utf8ToArray(inArray);
|
1470
|
+
} else {
|
1471
|
+
inputArray = hexToArray(inArray);
|
1472
|
+
}
|
1473
|
+
} else {
|
1474
|
+
inputArray = Uint8Array.from(inArray);
|
1475
|
+
}
|
1476
|
+
const tagArray = tag ? typeof tag === "string" ? hexToArray(tag) : Uint8Array.from(tag) : void 0;
|
1477
|
+
const result = sm4Gcm(inputArray, keyArray, ivArray, aadArray, cryptFlag, tagArray);
|
1478
|
+
if (output === "array") {
|
1479
|
+
if (outputTag && cryptFlag !== DECRYPT) {
|
1480
|
+
return result;
|
1481
|
+
}
|
1482
|
+
return result.output;
|
1483
|
+
} else {
|
1484
|
+
if (outputTag && cryptFlag !== DECRYPT) {
|
1485
|
+
return {
|
1486
|
+
output: bytesToHex(result.output),
|
1487
|
+
tag: result.tag ? bytesToHex(result.tag) : void 0
|
1488
|
+
};
|
1489
|
+
}
|
1490
|
+
if (cryptFlag !== DECRYPT) {
|
1491
|
+
return {
|
1492
|
+
output: bytesToHex(result.output),
|
1493
|
+
tag: result.tag ? bytesToHex(result.tag) : void 0
|
1494
|
+
};
|
1495
|
+
} else {
|
1496
|
+
return arrayToUtf8(result.output);
|
1497
|
+
}
|
1498
|
+
}
|
1499
|
+
}
|
1375
1500
|
if (mode === "cbc") {
|
1376
1501
|
if (typeof iv === "string")
|
1377
1502
|
iv = hexToArray(iv);
|
@@ -146,30 +146,52 @@ declare function sm3(input: string | Uint8Array, options?: {
|
|
146
146
|
|
147
147
|
interface SM4Options {
|
148
148
|
padding?: 'pkcs#7' | 'pkcs#5' | 'none' | null;
|
149
|
-
mode?: 'cbc' | 'ecb';
|
149
|
+
mode?: 'cbc' | 'ecb' | 'gcm';
|
150
150
|
iv?: Uint8Array | string;
|
151
151
|
output?: 'string' | 'array';
|
152
|
+
associatedData?: Uint8Array | string;
|
153
|
+
outputTag?: boolean;
|
154
|
+
tag?: Uint8Array | string;
|
152
155
|
}
|
153
|
-
declare function sm4(inArray: Uint8Array | string, key: Uint8Array | string, cryptFlag: 0 | 1, options?: SM4Options): string | Uint8Array
|
156
|
+
declare function sm4(inArray: Uint8Array | string, key: Uint8Array | string, cryptFlag: 0 | 1, options?: SM4Options): string | Uint8Array | {
|
157
|
+
output: Uint8Array;
|
158
|
+
tag?: Uint8Array | undefined;
|
159
|
+
} | {
|
160
|
+
output: string;
|
161
|
+
tag: string | undefined;
|
162
|
+
};
|
163
|
+
interface GCMResult<T = Uint8Array | string> {
|
164
|
+
output: T;
|
165
|
+
tag?: T;
|
166
|
+
}
|
167
|
+
declare function encrypt(inArray: Uint8Array | string, key: Uint8Array | string, options: {
|
168
|
+
mode: 'gcm';
|
169
|
+
output: 'array';
|
170
|
+
} & SM4Options): GCMResult<Uint8Array>;
|
171
|
+
declare function encrypt(inArray: Uint8Array | string, key: Uint8Array | string, options: {
|
172
|
+
mode: 'gcm';
|
173
|
+
output?: 'string';
|
174
|
+
} & SM4Options): GCMResult<string>;
|
154
175
|
declare function encrypt(inArray: Uint8Array | string, key: Uint8Array | string, options?: {
|
155
176
|
output: 'array';
|
156
177
|
} & SM4Options): Uint8Array;
|
157
178
|
declare function encrypt(inArray: Uint8Array | string, key: Uint8Array | string, options?: {
|
158
|
-
output
|
179
|
+
output?: 'string';
|
159
180
|
} & SM4Options): string;
|
160
181
|
declare function decrypt(inArray: Uint8Array | string, key: Uint8Array | string, options?: {
|
161
182
|
output: 'array';
|
162
183
|
} & SM4Options): Uint8Array;
|
163
184
|
declare function decrypt(inArray: Uint8Array | string, key: Uint8Array | string, options?: {
|
164
|
-
output
|
185
|
+
output?: 'string';
|
165
186
|
} & SM4Options): string;
|
166
187
|
|
188
|
+
type index_GCMResult<T = Uint8Array | string> = GCMResult<T>;
|
167
189
|
type index_SM4Options = SM4Options;
|
168
190
|
declare const index_decrypt: typeof decrypt;
|
169
191
|
declare const index_encrypt: typeof encrypt;
|
170
192
|
declare const index_sm4: typeof sm4;
|
171
193
|
declare namespace index {
|
172
|
-
export { type index_SM4Options as SM4Options, index_decrypt as decrypt, index_encrypt as encrypt, index_sm4 as sm4 };
|
194
|
+
export { type index_GCMResult as GCMResult, type index_SM4Options as SM4Options, index_decrypt as decrypt, index_encrypt as encrypt, index_sm4 as sm4 };
|
173
195
|
}
|
174
196
|
|
175
197
|
export { index$1 as sm2, sm3, index as sm4 };
|
@@ -2915,19 +2915,8 @@ function compressPublicKeyHex(s) {
|
|
2915
2915
|
return prefix + xHex;
|
2916
2916
|
}
|
2917
2917
|
function utf8ToHex(input) {
|
2918
|
-
|
2919
|
-
|
2920
|
-
var words = new Uint32Array((length >>> 2) + 1);
|
2921
|
-
for(var i = 0; i < length; i++){
|
2922
|
-
words[i >>> 2] |= (input.charCodeAt(i) & 255) << 24 - i % 4 * 8;
|
2923
|
-
}
|
2924
|
-
var hexChars = [];
|
2925
|
-
for(var i1 = 0; i1 < length; i1++){
|
2926
|
-
var bite = words[i1 >>> 2] >>> 24 - i1 % 4 * 8 & 255;
|
2927
|
-
hexChars.push((bite >>> 4).toString(16));
|
2928
|
-
hexChars.push((bite & 15).toString(16));
|
2929
|
-
}
|
2930
|
-
return hexChars.join("");
|
2918
|
+
var bytes = utf8ToBytes(input);
|
2919
|
+
return bytesToHex(bytes);
|
2931
2920
|
}
|
2932
2921
|
function leftPad(input, num) {
|
2933
2922
|
if (input.length >= num) return input;
|
@@ -3282,6 +3271,8 @@ __export(sm4_exports, {
|
|
3282
3271
|
return sm4;
|
3283
3272
|
}
|
3284
3273
|
});
|
3274
|
+
var import_polyval = require("@noble/ciphers/_polyval");
|
3275
|
+
var import_utils14 = require("@noble/ciphers/utils");
|
3285
3276
|
var DECRYPT = 0;
|
3286
3277
|
var ROUND = 32;
|
3287
3278
|
var BLOCK = 16;
|
@@ -3673,10 +3664,151 @@ function sms4KeyExt(key, roundKey, cryptFlag) {
|
|
3673
3664
|
}
|
3674
3665
|
}
|
3675
3666
|
}
|
3667
|
+
function incrementCounter(counter) {
|
3668
|
+
for(var i = counter.length - 1; i >= 0; i--){
|
3669
|
+
counter[i]++;
|
3670
|
+
if (counter[i] !== 0) break;
|
3671
|
+
}
|
3672
|
+
}
|
3673
|
+
function sm4Gcm(inArray, key, ivArray, aadArray, cryptFlag, tagArray) {
|
3674
|
+
var deriveKeys = function deriveKeys() {
|
3675
|
+
var roundKey2 = new Uint32Array(ROUND);
|
3676
|
+
sms4KeyExt(key, roundKey2, 1);
|
3677
|
+
var authKey = new Uint8Array(16).fill(0);
|
3678
|
+
var h2 = new Uint8Array(16);
|
3679
|
+
sms4Crypt(authKey, h2, roundKey2);
|
3680
|
+
var j02;
|
3681
|
+
if (ivArray.length === 12) {
|
3682
|
+
j02 = new Uint8Array(16);
|
3683
|
+
j02.set(ivArray, 0);
|
3684
|
+
j02[15] = 1;
|
3685
|
+
} else {
|
3686
|
+
var g = import_polyval.ghash.create(h2);
|
3687
|
+
g.update(ivArray);
|
3688
|
+
var lenIv = new Uint8Array(16);
|
3689
|
+
var view = (0, import_utils14.createView)(lenIv);
|
3690
|
+
(0, import_utils14.setBigUint64)(view, 8, BigInt(ivArray.length * 8), false);
|
3691
|
+
g.update(lenIv);
|
3692
|
+
j02 = g.digest();
|
3693
|
+
}
|
3694
|
+
var counter2 = new Uint8Array(j02);
|
3695
|
+
incrementCounter(counter2);
|
3696
|
+
var tagMask2 = new Uint8Array(16);
|
3697
|
+
sms4Crypt(j02, tagMask2, roundKey2);
|
3698
|
+
return {
|
3699
|
+
roundKey: roundKey2,
|
3700
|
+
h: h2,
|
3701
|
+
j0: j02,
|
3702
|
+
counter: counter2,
|
3703
|
+
tagMask: tagMask2
|
3704
|
+
};
|
3705
|
+
};
|
3706
|
+
var computeTag = function computeTag(h2, data) {
|
3707
|
+
var aadLength = aadArray.length;
|
3708
|
+
var dataLength = data.length;
|
3709
|
+
var g = import_polyval.ghash.create(h2);
|
3710
|
+
if (aadLength > 0) {
|
3711
|
+
g.update(aadArray);
|
3712
|
+
}
|
3713
|
+
g.update(data);
|
3714
|
+
var lenBlock = new Uint8Array(16);
|
3715
|
+
var view = (0, import_utils14.createView)(lenBlock);
|
3716
|
+
(0, import_utils14.setBigUint64)(view, 0, BigInt(aadLength * 8), false);
|
3717
|
+
(0, import_utils14.setBigUint64)(view, 8, BigInt(dataLength * 8), false);
|
3718
|
+
g.update(lenBlock);
|
3719
|
+
return g.digest();
|
3720
|
+
};
|
3721
|
+
var tagLength = 16;
|
3722
|
+
var _deriveKeys = deriveKeys(), roundKey = _deriveKeys.roundKey, h = _deriveKeys.h, j0 = _deriveKeys.j0, counter = _deriveKeys.counter, tagMask = _deriveKeys.tagMask;
|
3723
|
+
if (cryptFlag === DECRYPT && tagArray) {
|
3724
|
+
var calculatedTag = computeTag(h, inArray);
|
3725
|
+
for(var i = 0; i < 16; i++){
|
3726
|
+
calculatedTag[i] ^= tagMask[i];
|
3727
|
+
}
|
3728
|
+
var tagMatch = 0;
|
3729
|
+
for(var i1 = 0; i1 < 16; i1++){
|
3730
|
+
tagMatch |= calculatedTag[i1] ^ tagArray[i1];
|
3731
|
+
}
|
3732
|
+
if (tagMatch !== 0) {
|
3733
|
+
throw new Error("authentication tag mismatch");
|
3734
|
+
}
|
3735
|
+
}
|
3736
|
+
var outArray = new Uint8Array(inArray.length);
|
3737
|
+
var point = 0;
|
3738
|
+
var restLen = inArray.length;
|
3739
|
+
while(restLen >= BLOCK){
|
3740
|
+
var blockOut = new Uint8Array(BLOCK);
|
3741
|
+
sms4Crypt(counter, blockOut, roundKey);
|
3742
|
+
for(var i2 = 0; i2 < BLOCK && i2 < restLen; i2++){
|
3743
|
+
outArray[point + i2] = inArray[point + i2] ^ blockOut[i2];
|
3744
|
+
}
|
3745
|
+
incrementCounter(counter);
|
3746
|
+
point += BLOCK;
|
3747
|
+
restLen -= BLOCK;
|
3748
|
+
}
|
3749
|
+
if (restLen > 0) {
|
3750
|
+
var blockOut1 = new Uint8Array(BLOCK);
|
3751
|
+
sms4Crypt(counter, blockOut1, roundKey);
|
3752
|
+
for(var i3 = 0; i3 < restLen; i3++){
|
3753
|
+
outArray[point + i3] = inArray[point + i3] ^ blockOut1[i3];
|
3754
|
+
}
|
3755
|
+
}
|
3756
|
+
if (cryptFlag !== DECRYPT) {
|
3757
|
+
var calculatedTag1 = computeTag(h, outArray);
|
3758
|
+
for(var i4 = 0; i4 < 16; i4++){
|
3759
|
+
calculatedTag1[i4] ^= tagMask[i4];
|
3760
|
+
}
|
3761
|
+
return {
|
3762
|
+
output: outArray,
|
3763
|
+
tag: calculatedTag1
|
3764
|
+
};
|
3765
|
+
}
|
3766
|
+
return {
|
3767
|
+
output: outArray
|
3768
|
+
};
|
3769
|
+
}
|
3676
3770
|
var blockOutput = new Uint8Array(16);
|
3677
3771
|
function sm4(inArray, key, cryptFlag) {
|
3678
3772
|
var options = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : {};
|
3679
|
-
var _options_padding = options.padding, padding = _options_padding === void 0 ? "pkcs#7" : _options_padding, mode = options.mode, _options_iv = options.iv, iv = _options_iv === void 0 ? new Uint8Array(16) : _options_iv, output = options.output;
|
3773
|
+
var _options_padding = options.padding, padding = _options_padding === void 0 ? "pkcs#7" : _options_padding, mode = options.mode, _options_iv = options.iv, iv = _options_iv === void 0 ? new Uint8Array(16) : _options_iv, output = options.output, associatedData = options.associatedData, outputTag = options.outputTag, tag = options.tag;
|
3774
|
+
if (mode === "gcm") {
|
3775
|
+
var keyArray = typeof key === "string" ? hexToArray(key) : Uint8Array.from(key);
|
3776
|
+
var ivArray = typeof iv === "string" ? hexToArray(iv) : Uint8Array.from(iv);
|
3777
|
+
var aadArray = associatedData ? typeof associatedData === "string" ? hexToArray(associatedData) : Uint8Array.from(associatedData) : new Uint8Array(0);
|
3778
|
+
var inputArray;
|
3779
|
+
if (typeof inArray === "string") {
|
3780
|
+
if (cryptFlag !== DECRYPT) {
|
3781
|
+
inputArray = utf8ToArray(inArray);
|
3782
|
+
} else {
|
3783
|
+
inputArray = hexToArray(inArray);
|
3784
|
+
}
|
3785
|
+
} else {
|
3786
|
+
inputArray = Uint8Array.from(inArray);
|
3787
|
+
}
|
3788
|
+
var tagArray = tag ? typeof tag === "string" ? hexToArray(tag) : Uint8Array.from(tag) : void 0;
|
3789
|
+
var result = sm4Gcm(inputArray, keyArray, ivArray, aadArray, cryptFlag, tagArray);
|
3790
|
+
if (output === "array") {
|
3791
|
+
if (outputTag && cryptFlag !== DECRYPT) {
|
3792
|
+
return result;
|
3793
|
+
}
|
3794
|
+
return result.output;
|
3795
|
+
} else {
|
3796
|
+
if (outputTag && cryptFlag !== DECRYPT) {
|
3797
|
+
return {
|
3798
|
+
output: bytesToHex2(result.output),
|
3799
|
+
tag: result.tag ? bytesToHex2(result.tag) : void 0
|
3800
|
+
};
|
3801
|
+
}
|
3802
|
+
if (cryptFlag !== DECRYPT) {
|
3803
|
+
return {
|
3804
|
+
output: bytesToHex2(result.output),
|
3805
|
+
tag: result.tag ? bytesToHex2(result.tag) : void 0
|
3806
|
+
};
|
3807
|
+
} else {
|
3808
|
+
return arrayToUtf8(result.output);
|
3809
|
+
}
|
3810
|
+
}
|
3811
|
+
}
|
3680
3812
|
if (mode === "cbc") {
|
3681
3813
|
if (typeof iv === "string") iv = hexToArray(iv);
|
3682
3814
|
if (iv.length !== 128 / 8) {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "sm-crypto-v2",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.10.0",
|
4
4
|
"description": "sm-crypto-v2",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"module": "dist/index.mjs",
|
@@ -33,6 +33,7 @@
|
|
33
33
|
"author": "june_01",
|
34
34
|
"license": "MIT",
|
35
35
|
"dependencies": {
|
36
|
+
"@noble/ciphers": "^1.2.1",
|
36
37
|
"@noble/curves": "^1.1.0"
|
37
38
|
},
|
38
39
|
"devDependencies": {
|
@@ -57,5 +58,9 @@
|
|
57
58
|
"typescript": "^4.7.2",
|
58
59
|
"vite": "^4.3.9",
|
59
60
|
"vitest": "^0.31.0"
|
61
|
+
},
|
62
|
+
"publishConfig": {
|
63
|
+
"registry": "https://registry.npmjs.org/",
|
64
|
+
"access": "public"
|
60
65
|
}
|
61
66
|
}
|