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 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: 'string';
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: 'string';
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: 'string';
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: 'string';
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
- input = decodeURIComponent(encodeURIComponent(input));
640
- const length = input.length;
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
- input = decodeURIComponent(encodeURIComponent(input));
608
- const length = input.length;
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: 'string';
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: 'string';
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
- input = decodeURIComponent(encodeURIComponent(input));
2919
- var length = input.length;
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.9.2",
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
  }