sm-crypto-v2 1.9.3 → 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 +7 -0
- package/dist/index.d.mts +27 -5
- package/dist/index.d.ts +27 -5
- package/dist/index.js +137 -1
- package/dist/index.mjs +137 -1
- package/miniprogram_dist/index.d.ts +27 -5
- package/miniprogram_dist/index.js +144 -1
- package/package.json +6 -1
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,13 @@
|
|
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
|
+
|
5
12
|
### [1.9.3](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.9.2...v1.9.3) (2024-10-10)
|
6
13
|
|
7
14
|
|
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
@@ -998,6 +998,8 @@ __export(sm4_exports, {
|
|
998
998
|
encrypt: () => encrypt,
|
999
999
|
sm4: () => sm4
|
1000
1000
|
});
|
1001
|
+
var import_polyval = require("@noble/ciphers/_polyval");
|
1002
|
+
var import_utils11 = require("@noble/ciphers/utils");
|
1001
1003
|
var DECRYPT = 0;
|
1002
1004
|
var ROUND = 32;
|
1003
1005
|
var BLOCK = 16;
|
@@ -1385,14 +1387,148 @@ function sms4KeyExt(key, roundKey, cryptFlag) {
|
|
1385
1387
|
}
|
1386
1388
|
}
|
1387
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
|
+
}
|
1388
1483
|
var blockOutput = new Uint8Array(16);
|
1389
1484
|
function sm4(inArray, key, cryptFlag, options = {}) {
|
1390
1485
|
let {
|
1391
1486
|
padding = "pkcs#7",
|
1392
1487
|
mode,
|
1393
1488
|
iv = new Uint8Array(16),
|
1394
|
-
output
|
1489
|
+
output,
|
1490
|
+
associatedData,
|
1491
|
+
outputTag,
|
1492
|
+
tag
|
1395
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
|
+
}
|
1396
1532
|
if (mode === "cbc") {
|
1397
1533
|
if (typeof iv === "string")
|
1398
1534
|
iv = hexToArray(iv);
|
package/dist/index.mjs
CHANGED
@@ -966,6 +966,8 @@ __export(sm4_exports, {
|
|
966
966
|
encrypt: () => encrypt,
|
967
967
|
sm4: () => sm4
|
968
968
|
});
|
969
|
+
import { ghash } from "@noble/ciphers/_polyval";
|
970
|
+
import { createView as createView2, setBigUint64 as setBigUint642 } from "@noble/ciphers/utils";
|
969
971
|
var DECRYPT = 0;
|
970
972
|
var ROUND = 32;
|
971
973
|
var BLOCK = 16;
|
@@ -1353,14 +1355,148 @@ function sms4KeyExt(key, roundKey, cryptFlag) {
|
|
1353
1355
|
}
|
1354
1356
|
}
|
1355
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
|
+
}
|
1356
1451
|
var blockOutput = new Uint8Array(16);
|
1357
1452
|
function sm4(inArray, key, cryptFlag, options = {}) {
|
1358
1453
|
let {
|
1359
1454
|
padding = "pkcs#7",
|
1360
1455
|
mode,
|
1361
1456
|
iv = new Uint8Array(16),
|
1362
|
-
output
|
1457
|
+
output,
|
1458
|
+
associatedData,
|
1459
|
+
outputTag,
|
1460
|
+
tag
|
1363
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
|
+
}
|
1364
1500
|
if (mode === "cbc") {
|
1365
1501
|
if (typeof iv === "string")
|
1366
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 };
|
@@ -3271,6 +3271,8 @@ __export(sm4_exports, {
|
|
3271
3271
|
return sm4;
|
3272
3272
|
}
|
3273
3273
|
});
|
3274
|
+
var import_polyval = require("@noble/ciphers/_polyval");
|
3275
|
+
var import_utils14 = require("@noble/ciphers/utils");
|
3274
3276
|
var DECRYPT = 0;
|
3275
3277
|
var ROUND = 32;
|
3276
3278
|
var BLOCK = 16;
|
@@ -3662,10 +3664,151 @@ function sms4KeyExt(key, roundKey, cryptFlag) {
|
|
3662
3664
|
}
|
3663
3665
|
}
|
3664
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
|
+
}
|
3665
3770
|
var blockOutput = new Uint8Array(16);
|
3666
3771
|
function sm4(inArray, key, cryptFlag) {
|
3667
3772
|
var options = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : {};
|
3668
|
-
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
|
+
}
|
3669
3812
|
if (mode === "cbc") {
|
3670
3813
|
if (typeof iv === "string") iv = hexToArray(iv);
|
3671
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
|
}
|