@li0ard/gost 0.1.4 → 0.1.6
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/gost3410/const.d.ts +12 -0
- package/gost3410/const.js +12 -0
- package/gost3410/conversion.d.ts +1 -4
- package/gost3410/conversion.js +1 -4
- package/gost3410/index.d.ts +5 -3
- package/gost3410/index.js +9 -8
- package/gost3410/vko.d.ts +5 -5
- package/gost3410/vko.js +5 -5
- package/gost341194/index.d.ts +1 -1
- package/gost341194/index.js +22 -118
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/kuznyechik/const.js +1 -1
- package/kuznyechik/index.js +44 -128
- package/magma/index.js +8 -13
- package/modes/_keytransform.js +2 -5
- package/oids/index.d.ts +6 -0
- package/oids/index.js +16 -0
- package/package.json +4 -1
- package/streebog/index.js +39 -152
- package/types.d.ts +1 -0
package/gost3410/const.d.ts
CHANGED
|
@@ -45,3 +45,15 @@ export declare const ID_GOSTR3410_2012_512_PARAM_SET_A: Readonly<GostCurveParame
|
|
|
45
45
|
export declare const ID_GOSTR3410_2012_512_PARAM_SET_B: Readonly<GostCurveParameters>;
|
|
46
46
|
/** GOST R 34.10-2012 512 bit `C` param set */
|
|
47
47
|
export declare const ID_GOSTR3410_2012_512_PARAM_SET_C: Readonly<GostCurveParameters>;
|
|
48
|
+
export declare const CURVES: {
|
|
49
|
+
ID_GOSTR3410_2001_PARAM_SET_CC: Readonly<GostCurveParameters>;
|
|
50
|
+
ID_GOSTR3410_2001_TEST_PARAM_SET: Readonly<GostCurveParameters>;
|
|
51
|
+
ID_GOSTR3410_2012_256_PARAM_SET_A: Readonly<GostCurveParameters>;
|
|
52
|
+
ID_GOSTR3410_2012_256_PARAM_SET_B: Readonly<GostCurveParameters>;
|
|
53
|
+
ID_GOSTR3410_2012_256_PARAM_SET_C: Readonly<GostCurveParameters>;
|
|
54
|
+
ID_GOSTR3410_2012_256_PARAM_SET_D: Readonly<GostCurveParameters>;
|
|
55
|
+
ID_GOSTR3410_2012_512_TEST_PARAM_SET: Readonly<GostCurveParameters>;
|
|
56
|
+
ID_GOSTR3410_2012_512_PARAM_SET_A: Readonly<GostCurveParameters>;
|
|
57
|
+
ID_GOSTR3410_2012_512_PARAM_SET_B: Readonly<GostCurveParameters>;
|
|
58
|
+
ID_GOSTR3410_2012_512_PARAM_SET_C: Readonly<GostCurveParameters>;
|
|
59
|
+
};
|
package/gost3410/const.js
CHANGED
|
@@ -124,3 +124,15 @@ export const ID_GOSTR3410_2012_512_PARAM_SET_C = ({
|
|
|
124
124
|
st: [0x186c289cffa09c983b168c30c829006c952ff4aaf99c73850875d7e77bebef18d653187d6ba8fe533ec74c6f061872585b97cc0f50f57752cd73f4913304621en, 0x9a628f975594ecefd89ba28a2539ffb79c8ab238aeed0851fa5c1abb02b80b44c6734501b83a011dd625cd0b5145091a6d9acd4b1f5c5b1e21b2b249ddfd1271n],
|
|
125
125
|
oids: ["1.2.643.7.1.2.1.2.3"]
|
|
126
126
|
});
|
|
127
|
+
export const CURVES = {
|
|
128
|
+
ID_GOSTR3410_2001_PARAM_SET_CC,
|
|
129
|
+
ID_GOSTR3410_2001_TEST_PARAM_SET,
|
|
130
|
+
ID_GOSTR3410_2012_256_PARAM_SET_A,
|
|
131
|
+
ID_GOSTR3410_2012_256_PARAM_SET_B,
|
|
132
|
+
ID_GOSTR3410_2012_256_PARAM_SET_C,
|
|
133
|
+
ID_GOSTR3410_2012_256_PARAM_SET_D,
|
|
134
|
+
ID_GOSTR3410_2012_512_TEST_PARAM_SET,
|
|
135
|
+
ID_GOSTR3410_2012_512_PARAM_SET_A,
|
|
136
|
+
ID_GOSTR3410_2012_512_PARAM_SET_B,
|
|
137
|
+
ID_GOSTR3410_2012_512_PARAM_SET_C
|
|
138
|
+
};
|
package/gost3410/conversion.d.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import type { AffinePoint } from "@noble/curves/abstract/curve.js";
|
|
2
2
|
import type { GostCurveParameters } from "./const.js";
|
|
3
|
-
/**
|
|
4
|
-
* Compute parameters (`s`, `t`) for conversion
|
|
5
|
-
* @param curve Curve to use
|
|
6
|
-
*/
|
|
3
|
+
/** Compute parameters (`s`, `t`) for conversion */
|
|
7
4
|
export declare const computeST: (curve: GostCurveParameters) => bigint[];
|
|
8
5
|
/**
|
|
9
6
|
* Convert Twisted Edwards point (`u`, `v`) to Weierstrass (`x`, `y`)
|
package/gost3410/conversion.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { Field } from "@noble/curves/abstract/modular.js";
|
|
2
|
-
/**
|
|
3
|
-
* Compute parameters (`s`, `t`) for conversion
|
|
4
|
-
* @param curve Curve to use
|
|
5
|
-
*/
|
|
2
|
+
/** Compute parameters (`s`, `t`) for conversion */
|
|
6
3
|
export const computeST = (curve) => {
|
|
7
4
|
if (!curve.e || !curve.d)
|
|
8
5
|
throw new Error("No Twisted Edwards parameters");
|
package/gost3410/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type TArg, type TRet } from "@noble/curves/utils.js";
|
|
2
|
-
import {
|
|
2
|
+
import type { GostCurveParameters } from "./const.js";
|
|
3
3
|
/**
|
|
4
4
|
* Generate public key from private.
|
|
5
5
|
* @param parameters Curve parameters
|
|
@@ -13,7 +13,7 @@ export declare const getPublicKey: (parameters: GostCurveParameters, prv: TArg<U
|
|
|
13
13
|
* @param prv Private key
|
|
14
14
|
* @param digest Digest to sign
|
|
15
15
|
* @param rand Optional. Predefined random data for `r` and `k` generation
|
|
16
|
-
* @returns {TRet<Uint8Array>} Concated `r` and `s`
|
|
16
|
+
* @returns {TRet<Uint8Array>} Concated `r` and `s` (in BE order)
|
|
17
17
|
*/
|
|
18
18
|
export declare const sign: (parameters: GostCurveParameters, prv: TArg<Uint8Array>, digest: TArg<Uint8Array>, rand?: TArg<Uint8Array>) => TRet<Uint8Array>;
|
|
19
19
|
/**
|
|
@@ -21,9 +21,11 @@ export declare const sign: (parameters: GostCurveParameters, prv: TArg<Uint8Arra
|
|
|
21
21
|
* @param parameters Curve parameters
|
|
22
22
|
* @param pub Public key
|
|
23
23
|
* @param digest Digest to verify
|
|
24
|
-
* @param signature Signature (Concated `r` and `s`)
|
|
24
|
+
* @param signature Signature (Concated `r` and `s`) (in BE order)
|
|
25
25
|
*/
|
|
26
26
|
export declare const verify: (parameters: GostCurveParameters, pub: TArg<Uint8Array>, digest: TArg<Uint8Array>, signature: TArg<Uint8Array>) => boolean;
|
|
27
|
+
/** Swap `r` and `s` in signature */
|
|
28
|
+
export declare const swapPoint: (curve: GostCurveParameters, point: TArg<Uint8Array>) => TRet<Uint8Array>;
|
|
27
29
|
export * from "./const.js";
|
|
28
30
|
export * from "./vko.js";
|
|
29
31
|
export * from "./conversion.js";
|
package/gost3410/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { bytesToNumberBE, concatBytes, numberToBytesBE, randomBytes } from "@noble/curves/utils.js";
|
|
2
|
-
import {} from "./const.js";
|
|
3
2
|
import { mod } from "@noble/curves/abstract/modular.js";
|
|
4
3
|
import { weierstrass } from "@noble/curves/abstract/weierstrass.js";
|
|
5
4
|
/**
|
|
@@ -15,16 +14,16 @@ export const getPublicKey = (parameters, prv) => weierstrass(parameters).BASE.mu
|
|
|
15
14
|
* @param prv Private key
|
|
16
15
|
* @param digest Digest to sign
|
|
17
16
|
* @param rand Optional. Predefined random data for `r` and `k` generation
|
|
18
|
-
* @returns {TRet<Uint8Array>} Concated `r` and `s`
|
|
17
|
+
* @returns {TRet<Uint8Array>} Concated `r` and `s` (in BE order)
|
|
19
18
|
*/
|
|
20
19
|
export const sign = (parameters, prv, digest, rand) => {
|
|
21
20
|
const size = parameters.length;
|
|
22
21
|
const curve = weierstrass(parameters);
|
|
23
22
|
const Fn = curve.Fn;
|
|
24
|
-
let e = Fn.fromBytes(digest);
|
|
23
|
+
let e = mod(bytesToNumberBE(digest), Fn.ORDER); //Fn.fromBytes(digest);
|
|
25
24
|
if (e === 0n)
|
|
26
25
|
e = 1n;
|
|
27
|
-
const prvNum = Fn.fromBytes(prv);
|
|
26
|
+
const prvNum = mod(bytesToNumberBE(prv), Fn.ORDER); //Fn.fromBytes(prv);
|
|
28
27
|
while (true) {
|
|
29
28
|
rand ||= randomBytes(size);
|
|
30
29
|
const k = mod(bytesToNumberBE(rand), parameters.n);
|
|
@@ -52,7 +51,7 @@ export const sign = (parameters, prv, digest, rand) => {
|
|
|
52
51
|
* @param parameters Curve parameters
|
|
53
52
|
* @param pub Public key
|
|
54
53
|
* @param digest Digest to verify
|
|
55
|
-
* @param signature Signature (Concated `r` and `s`)
|
|
54
|
+
* @param signature Signature (Concated `r` and `s`) (in BE order)
|
|
56
55
|
*/
|
|
57
56
|
export const verify = (parameters, pub, digest, signature) => {
|
|
58
57
|
const size = parameters.length;
|
|
@@ -60,11 +59,11 @@ export const verify = (parameters, pub, digest, signature) => {
|
|
|
60
59
|
const Fn = curve.Fn;
|
|
61
60
|
if (signature.length != size * 2)
|
|
62
61
|
throw new Error("Invalid signature");
|
|
63
|
-
const r = bytesToNumberBE(signature.
|
|
64
|
-
const s = bytesToNumberBE(signature.
|
|
62
|
+
const r = bytesToNumberBE(signature.subarray(0, size));
|
|
63
|
+
const s = bytesToNumberBE(signature.subarray(size));
|
|
65
64
|
if (r <= 0 || r >= parameters.n || s <= 0 || s >= parameters.n)
|
|
66
65
|
return false;
|
|
67
|
-
let e = Fn.fromBytes(digest);
|
|
66
|
+
let e = mod(bytesToNumberBE(digest), Fn.ORDER); //Fn.fromBytes(digest);
|
|
68
67
|
if (e === 0n)
|
|
69
68
|
e = 1n;
|
|
70
69
|
const v = Fn.inv(e);
|
|
@@ -79,6 +78,8 @@ export const verify = (parameters, pub, digest, signature) => {
|
|
|
79
78
|
}
|
|
80
79
|
return Fn.create(P.add(Q).x) === r;
|
|
81
80
|
};
|
|
81
|
+
/** Swap `r` and `s` in signature */
|
|
82
|
+
export const swapPoint = (curve, point) => concatBytes(point.subarray(curve.length), point.subarray(0, curve.length));
|
|
82
83
|
export * from "./const.js";
|
|
83
84
|
export * from "./vko.js";
|
|
84
85
|
export * from "./conversion.js";
|
package/gost3410/vko.d.ts
CHANGED
|
@@ -5,8 +5,8 @@ import { type TArg, type TRet } from "@noble/curves/utils.js";
|
|
|
5
5
|
* @param parameters Curve parameters
|
|
6
6
|
* @param prv Private key
|
|
7
7
|
* @param pub Public key
|
|
8
|
-
* @param ukm User keying material (aka salt)
|
|
9
|
-
* @returns {TRet<Uint8Array>} Shared key
|
|
8
|
+
* @param ukm User keying material (aka salt, VKO-factor)
|
|
9
|
+
* @returns {TRet<Uint8Array>} Shared key (Not hashed)
|
|
10
10
|
*/
|
|
11
11
|
export declare const kek: (parameters: GostCurveParameters, prv: TArg<Uint8Array>, pub: TArg<Uint8Array>, ukm: TArg<Uint8Array>) => TRet<Uint8Array>;
|
|
12
12
|
/**
|
|
@@ -14,7 +14,7 @@ export declare const kek: (parameters: GostCurveParameters, prv: TArg<Uint8Array
|
|
|
14
14
|
* @param parameters Curve parameters
|
|
15
15
|
* @param prv Private key
|
|
16
16
|
* @param pub Public key
|
|
17
|
-
* @param ukm User keying material (aka salt)
|
|
17
|
+
* @param ukm User keying material (aka salt, VKO-factor)
|
|
18
18
|
* @returns {TRet<Uint8Array>} Shared key
|
|
19
19
|
*/
|
|
20
20
|
export declare const kek_34102001: (parameters: GostCurveParameters, prv: TArg<Uint8Array>, pub: TArg<Uint8Array>, ukm: TArg<Uint8Array>) => TRet<Uint8Array>;
|
|
@@ -23,7 +23,7 @@ export declare const kek_34102001: (parameters: GostCurveParameters, prv: TArg<U
|
|
|
23
23
|
* @param parameters Curve parameters
|
|
24
24
|
* @param prv Private key
|
|
25
25
|
* @param pub Public key
|
|
26
|
-
* @param ukm User keying material (aka salt)
|
|
26
|
+
* @param ukm User keying material (aka salt, VKO-factor)
|
|
27
27
|
* @returns {TRet<Uint8Array>} Shared key
|
|
28
28
|
*/
|
|
29
29
|
export declare const kek_34102012256: (parameters: GostCurveParameters, prv: TArg<Uint8Array>, pub: TArg<Uint8Array>, ukm: TArg<Uint8Array>) => TRet<Uint8Array>;
|
|
@@ -32,7 +32,7 @@ export declare const kek_34102012256: (parameters: GostCurveParameters, prv: TAr
|
|
|
32
32
|
* @param parameters Curve parameters
|
|
33
33
|
* @param prv Private key
|
|
34
34
|
* @param pub Public key
|
|
35
|
-
* @param ukm User keying material (aka salt)
|
|
35
|
+
* @param ukm User keying material (aka salt, VKO-factor)
|
|
36
36
|
* @returns {TRet<Uint8Array>} Shared key
|
|
37
37
|
*/
|
|
38
38
|
export declare const kek_34102012512: (parameters: GostCurveParameters, prv: TArg<Uint8Array>, pub: TArg<Uint8Array>, ukm: TArg<Uint8Array>) => TRet<Uint8Array>;
|
package/gost3410/vko.js
CHANGED
|
@@ -8,8 +8,8 @@ import { bytesToNumberBE, concatBytes, numberToBytesLE } from "@noble/curves/uti
|
|
|
8
8
|
* @param parameters Curve parameters
|
|
9
9
|
* @param prv Private key
|
|
10
10
|
* @param pub Public key
|
|
11
|
-
* @param ukm User keying material (aka salt)
|
|
12
|
-
* @returns {TRet<Uint8Array>} Shared key
|
|
11
|
+
* @param ukm User keying material (aka salt, VKO-factor)
|
|
12
|
+
* @returns {TRet<Uint8Array>} Shared key (Not hashed)
|
|
13
13
|
*/
|
|
14
14
|
export const kek = (parameters, prv, pub, ukm) => {
|
|
15
15
|
const Fn = Field(parameters.n);
|
|
@@ -23,7 +23,7 @@ export const kek = (parameters, prv, pub, ukm) => {
|
|
|
23
23
|
* @param parameters Curve parameters
|
|
24
24
|
* @param prv Private key
|
|
25
25
|
* @param pub Public key
|
|
26
|
-
* @param ukm User keying material (aka salt)
|
|
26
|
+
* @param ukm User keying material (aka salt, VKO-factor)
|
|
27
27
|
* @returns {TRet<Uint8Array>} Shared key
|
|
28
28
|
*/
|
|
29
29
|
export const kek_34102001 = (parameters, prv, pub, ukm) => gost341194(kek(parameters, prv, pub, ukm));
|
|
@@ -32,7 +32,7 @@ export const kek_34102001 = (parameters, prv, pub, ukm) => gost341194(kek(parame
|
|
|
32
32
|
* @param parameters Curve parameters
|
|
33
33
|
* @param prv Private key
|
|
34
34
|
* @param pub Public key
|
|
35
|
-
* @param ukm User keying material (aka salt)
|
|
35
|
+
* @param ukm User keying material (aka salt, VKO-factor)
|
|
36
36
|
* @returns {TRet<Uint8Array>} Shared key
|
|
37
37
|
*/
|
|
38
38
|
export const kek_34102012256 = (parameters, prv, pub, ukm) => streebog256(kek(parameters, prv, pub, ukm));
|
|
@@ -41,7 +41,7 @@ export const kek_34102012256 = (parameters, prv, pub, ukm) => streebog256(kek(pa
|
|
|
41
41
|
* @param parameters Curve parameters
|
|
42
42
|
* @param prv Private key
|
|
43
43
|
* @param pub Public key
|
|
44
|
-
* @param ukm User keying material (aka salt)
|
|
44
|
+
* @param ukm User keying material (aka salt, VKO-factor)
|
|
45
45
|
* @returns {TRet<Uint8Array>} Shared key
|
|
46
46
|
*/
|
|
47
47
|
export const kek_34102012512 = (parameters, prv, pub, ukm) => streebog512(kek(parameters, prv, pub, ukm));
|
package/gost341194/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type Hash, type TArg, type TRet } from "@noble/hashes/utils.js";
|
|
|
3
3
|
export declare class Gost341194 implements Hash<Gost341194> {
|
|
4
4
|
private data;
|
|
5
5
|
private sbox;
|
|
6
|
-
readonly blockLen
|
|
6
|
+
readonly blockLen = 32;
|
|
7
7
|
readonly outputLen = 32;
|
|
8
8
|
readonly canXOF = false;
|
|
9
9
|
/** GOST R 34.11-94 hash function */
|
package/gost341194/index.js
CHANGED
|
@@ -3,146 +3,50 @@ import { Magma } from "../magma/index.js";
|
|
|
3
3
|
import { DSSZZI_UA_DKE_1, ID_GOSTR_3411_94_CRYPTOPRO_PARAM_SET } from "../magma/const.js";
|
|
4
4
|
import { bytesToNumberBE, numberToBytesBE } from "@noble/curves/utils.js";
|
|
5
5
|
import { xorBytes } from "../utils.js";
|
|
6
|
-
const BLOCKSIZE = 32;
|
|
7
6
|
const r = (1n << 256n) - 1n;
|
|
8
|
-
const C2 = new Uint8Array(32);
|
|
9
7
|
const C3 = new Uint8Array([
|
|
10
8
|
0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff,
|
|
11
9
|
0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00,
|
|
12
10
|
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
|
|
13
11
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00
|
|
14
12
|
]);
|
|
15
|
-
const
|
|
16
|
-
const A = (x) => {
|
|
17
|
-
const x2 = x.subarray(16, 24);
|
|
18
|
-
return concatBytes(xorBytes(x.subarray(24, 32), x2), x.subarray(0, 8), x.subarray(8, 16), x2);
|
|
19
|
-
};
|
|
13
|
+
const A = (x) => concatBytes(xorBytes(x.subarray(24, 32), x.subarray(16, 24)), x.subarray(0, 8), x.subarray(8, 16), x.subarray(16, 24));
|
|
20
14
|
const P = (x) => new Uint8Array([
|
|
21
15
|
x[0], x[8], x[16], x[24], x[1], x[9], x[17], x[25],
|
|
22
16
|
x[2], x[10], x[18], x[26], x[3], x[11], x[19], x[27],
|
|
23
17
|
x[4], x[12], x[20], x[28], x[5], x[13], x[21], x[29],
|
|
24
18
|
x[6], x[14], x[22], x[30], x[7], x[15], x[23], x[31]
|
|
25
19
|
]);
|
|
26
|
-
/*const chi = (Y: TArg<Uint8Array>): TRet<Uint8Array> => {
|
|
27
|
-
const byx = new Uint8Array(2);
|
|
28
|
-
byx[0] = Y[30] ^ Y[28] ^ Y[26] ^ Y[24] ^ Y[6] ^ Y[0];
|
|
29
|
-
byx[1] = Y[31] ^ Y[29] ^ Y[27] ^ Y[25] ^ Y[7] ^ Y[1];
|
|
30
|
-
|
|
31
|
-
const result = new Uint8Array(BLOCKSIZE);
|
|
32
|
-
result.set(byx, 0);
|
|
33
|
-
result.set(Y.slice(0,30), 2);
|
|
34
|
-
|
|
35
|
-
return result;
|
|
36
|
-
}*/
|
|
37
20
|
const chi = (Y) => new Uint8Array([
|
|
38
21
|
Y[30] ^ Y[28] ^ Y[26] ^ Y[24] ^ Y[6] ^ Y[0],
|
|
39
22
|
Y[31] ^ Y[29] ^ Y[27] ^ Y[25] ^ Y[7] ^ Y[1],
|
|
40
23
|
...Y.subarray(0, 30)
|
|
41
24
|
]);
|
|
25
|
+
const _getMagma = (u, v, sbox) => new Magma(P(xorBytes(u, v)).reverse(), sbox, true);
|
|
42
26
|
const _step = (hin, m, sbox) => {
|
|
43
|
-
|
|
44
|
-
let
|
|
45
|
-
let
|
|
46
|
-
const
|
|
47
|
-
u = xorBytes(A(u), C2);
|
|
48
|
-
v = A(A(v));
|
|
49
|
-
w = xorBytes(u, v);
|
|
50
|
-
const k2 = new Magma(P(w).reverse(), sbox, true);
|
|
27
|
+
const k1 = _getMagma(hin, m, sbox);
|
|
28
|
+
let u = A(hin);
|
|
29
|
+
let v = A(A(m));
|
|
30
|
+
const k2 = _getMagma(u, v, sbox);
|
|
51
31
|
u = xorBytes(A(u), C3);
|
|
52
32
|
v = A(A(v));
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
u = xorBytes(A(u), C4);
|
|
33
|
+
const k3 = _getMagma(u, v, sbox);
|
|
34
|
+
u = A(u);
|
|
56
35
|
v = A(A(v));
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
let
|
|
63
|
-
|
|
64
|
-
x = chi(x);
|
|
65
|
-
x = chi(x);
|
|
66
|
-
x = chi(x);
|
|
67
|
-
x = chi(x);
|
|
68
|
-
x = chi(x);
|
|
69
|
-
x = chi(x);
|
|
70
|
-
x = chi(x);
|
|
71
|
-
x = chi(x);
|
|
72
|
-
x = chi(x);
|
|
73
|
-
x = chi(x);
|
|
74
|
-
x = xorBytes(x, m);
|
|
75
|
-
x = chi(x);
|
|
76
|
-
x = xorBytes(hin, x);
|
|
77
|
-
//for(let i = 0; i < 61; i++) x = chi(x);
|
|
78
|
-
x = chi(x);
|
|
79
|
-
x = chi(x);
|
|
80
|
-
x = chi(x);
|
|
81
|
-
x = chi(x);
|
|
82
|
-
x = chi(x);
|
|
83
|
-
x = chi(x);
|
|
84
|
-
x = chi(x);
|
|
85
|
-
x = chi(x);
|
|
86
|
-
x = chi(x);
|
|
87
|
-
x = chi(x);
|
|
88
|
-
x = chi(x);
|
|
89
|
-
x = chi(x);
|
|
90
|
-
x = chi(x);
|
|
91
|
-
x = chi(x);
|
|
92
|
-
x = chi(x);
|
|
93
|
-
x = chi(x);
|
|
94
|
-
x = chi(x);
|
|
95
|
-
x = chi(x);
|
|
96
|
-
x = chi(x);
|
|
97
|
-
x = chi(x);
|
|
98
|
-
x = chi(x);
|
|
99
|
-
x = chi(x);
|
|
100
|
-
x = chi(x);
|
|
101
|
-
x = chi(x);
|
|
102
|
-
x = chi(x);
|
|
103
|
-
x = chi(x);
|
|
104
|
-
x = chi(x);
|
|
105
|
-
x = chi(x);
|
|
106
|
-
x = chi(x);
|
|
107
|
-
x = chi(x);
|
|
108
|
-
x = chi(x);
|
|
109
|
-
x = chi(x);
|
|
110
|
-
x = chi(x);
|
|
111
|
-
x = chi(x);
|
|
112
|
-
x = chi(x);
|
|
113
|
-
x = chi(x);
|
|
114
|
-
x = chi(x);
|
|
115
|
-
x = chi(x);
|
|
116
|
-
x = chi(x);
|
|
117
|
-
x = chi(x);
|
|
118
|
-
x = chi(x);
|
|
119
|
-
x = chi(x);
|
|
120
|
-
x = chi(x);
|
|
121
|
-
x = chi(x);
|
|
122
|
-
x = chi(x);
|
|
123
|
-
x = chi(x);
|
|
124
|
-
x = chi(x);
|
|
125
|
-
x = chi(x);
|
|
126
|
-
x = chi(x);
|
|
127
|
-
x = chi(x);
|
|
128
|
-
x = chi(x);
|
|
129
|
-
x = chi(x);
|
|
130
|
-
x = chi(x);
|
|
131
|
-
x = chi(x);
|
|
132
|
-
x = chi(x);
|
|
133
|
-
x = chi(x);
|
|
134
|
-
x = chi(x);
|
|
135
|
-
x = chi(x);
|
|
136
|
-
x = chi(x);
|
|
137
|
-
x = chi(x);
|
|
138
|
-
x = chi(x);
|
|
36
|
+
const k4 = _getMagma(u, v, sbox);
|
|
37
|
+
const x = concatBytes(k4.encrypt(hin.slice(0, 8).reverse()).reverse(), k3.encrypt(hin.slice(8, 16).reverse()).reverse(), k2.encrypt(hin.slice(16, 24).reverse()).reverse(), k1.encrypt(hin.slice(24, 32).reverse()).reverse());
|
|
38
|
+
for (let i = 0; i < 12; i++)
|
|
39
|
+
x.set(chi(x));
|
|
40
|
+
x.set(xorBytes(hin, chi(xorBytes(x, m))));
|
|
41
|
+
for (let i = 0; i < 61; i++)
|
|
42
|
+
x.set(chi(x));
|
|
139
43
|
return x;
|
|
140
44
|
};
|
|
141
45
|
/** GOST R 34.11-94 hash function */
|
|
142
46
|
export class Gost341194 {
|
|
143
47
|
data;
|
|
144
48
|
sbox;
|
|
145
|
-
blockLen =
|
|
49
|
+
blockLen = 32;
|
|
146
50
|
outputLen = 32;
|
|
147
51
|
canXOF = false;
|
|
148
52
|
/** GOST R 34.11-94 hash function */
|
|
@@ -167,17 +71,17 @@ export class Gost341194 {
|
|
|
167
71
|
digestInto(buf) {
|
|
168
72
|
let len = 0n;
|
|
169
73
|
let checksum = 0n;
|
|
170
|
-
const h = new Uint8Array(
|
|
74
|
+
const h = new Uint8Array(this.blockLen);
|
|
171
75
|
const m = new Uint8Array(this.data);
|
|
172
|
-
for (let i = 0; i < m.length; i +=
|
|
173
|
-
let part = m.slice(i, i +
|
|
76
|
+
for (let i = 0; i < m.length; i += this.blockLen) {
|
|
77
|
+
let part = m.slice(i, i + this.blockLen).reverse();
|
|
174
78
|
len += BigInt(part.length) * 8n;
|
|
175
79
|
checksum = (checksum + bytesToNumberBE(part)) & r;
|
|
176
|
-
if (part.length <
|
|
177
|
-
part = numberToBytesBE(bytesToNumberBE(part),
|
|
80
|
+
if (part.length < this.blockLen)
|
|
81
|
+
part = numberToBytesBE(bytesToNumberBE(part), this.blockLen);
|
|
178
82
|
h.set(_step(h, part, this.sbox));
|
|
179
83
|
}
|
|
180
|
-
h.set(_step(_step(h, numberToBytesBE(len,
|
|
84
|
+
h.set(_step(_step(h, numberToBytesBE(len, this.blockLen), this.sbox), numberToBytesBE(checksum, this.blockLen), this.sbox));
|
|
181
85
|
buf.set(h.reverse());
|
|
182
86
|
this.destroy();
|
|
183
87
|
}
|
package/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from "./gost341194/index.js";
|
|
|
3
3
|
export * from "./kuznyechik/index.js";
|
|
4
4
|
export * from "./magma/index.js";
|
|
5
5
|
export * from "./modes/index.js";
|
|
6
|
+
export * from "./oids/index.js";
|
|
6
7
|
export * from "./streebog/index.js";
|
|
7
8
|
export * from "./hmac.js";
|
|
8
9
|
export * from "./kdf.js";
|
package/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export * from "./gost341194/index.js";
|
|
|
3
3
|
export * from "./kuznyechik/index.js";
|
|
4
4
|
export * from "./magma/index.js";
|
|
5
5
|
export * from "./modes/index.js";
|
|
6
|
+
export * from "./oids/index.js";
|
|
6
7
|
export * from "./streebog/index.js";
|
|
7
8
|
export * from "./hmac.js";
|
|
8
9
|
export * from "./kdf.js";
|
package/kuznyechik/const.js
CHANGED
|
@@ -37,7 +37,7 @@ export const PI_REV = new Uint8Array([
|
|
|
37
37
|
export const L = new Uint8Array([
|
|
38
38
|
0x01, 0x94, 0x20, 0x85, 0x10, 0xc2, 0xc0, 0x01, 0xfb, 0x01, 0xc0, 0xc2, 0x10, 0x85, 0x20, 0x94,
|
|
39
39
|
]);
|
|
40
|
-
/*const ITER: Uint8Array[] = Array(32).fill(null).map(() => new Uint8Array(16)
|
|
40
|
+
/*const ITER: Uint8Array[] = Array(32).fill(null).map(() => new Uint8Array(16));
|
|
41
41
|
for(let i = 0; i < 32; i++) {
|
|
42
42
|
ITER[i][15] = i + 1;
|
|
43
43
|
ITER[i] = LL(ITER[i]);
|
package/kuznyechik/index.js
CHANGED
|
@@ -1,146 +1,64 @@
|
|
|
1
1
|
import { copyBytes } from "@noble/curves/utils.js";
|
|
2
2
|
import { ITER, L, PI, PI_REV } from "./const.js";
|
|
3
3
|
import { xorBytes } from "../utils.js";
|
|
4
|
-
const BLOCKSIZE = 16, KEYSIZE = 32;
|
|
5
|
-
const S = (input, pi = PI) => {
|
|
6
|
-
const result = new Uint8Array(BLOCKSIZE);
|
|
7
|
-
//for(let i = 0; i < BLOCKSIZE; i++) result[i] = pi[input[i]];
|
|
8
|
-
result[0] = pi[input[0]];
|
|
9
|
-
result[1] = pi[input[1]];
|
|
10
|
-
result[2] = pi[input[2]];
|
|
11
|
-
result[3] = pi[input[3]];
|
|
12
|
-
result[4] = pi[input[4]];
|
|
13
|
-
result[5] = pi[input[5]];
|
|
14
|
-
result[6] = pi[input[6]];
|
|
15
|
-
result[7] = pi[input[7]];
|
|
16
|
-
result[8] = pi[input[8]];
|
|
17
|
-
result[9] = pi[input[9]];
|
|
18
|
-
result[10] = pi[input[10]];
|
|
19
|
-
result[11] = pi[input[11]];
|
|
20
|
-
result[12] = pi[input[12]];
|
|
21
|
-
result[13] = pi[input[13]];
|
|
22
|
-
result[14] = pi[input[14]];
|
|
23
|
-
result[15] = pi[input[15]];
|
|
24
|
-
return result;
|
|
25
|
-
};
|
|
26
4
|
const gfMultiply = (a, b) => {
|
|
27
|
-
let result = 0;
|
|
28
|
-
let
|
|
29
|
-
|
|
30
|
-
if ((b & 0b00000001) === 0b00000001)
|
|
5
|
+
let result = 0, high_bit;
|
|
6
|
+
for (let _ = 0; _ < 8; _++) {
|
|
7
|
+
if ((b & 1) === 1)
|
|
31
8
|
result ^= a;
|
|
32
|
-
high_bit = a &
|
|
9
|
+
high_bit = a & 0x80;
|
|
33
10
|
a <<= 1;
|
|
34
|
-
if (high_bit ==
|
|
35
|
-
a ^=
|
|
11
|
+
if (high_bit == 0x80)
|
|
12
|
+
a ^= 0xC3;
|
|
36
13
|
b >>= 1;
|
|
37
14
|
}
|
|
38
15
|
return result & 0xFF;
|
|
39
16
|
};
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
temp ^= gfMultiply(input[3], L[3]);
|
|
73
|
-
temp ^= gfMultiply(input[4], L[4]);
|
|
74
|
-
temp ^= gfMultiply(input[5], L[5]);
|
|
75
|
-
temp ^= gfMultiply(input[6], L[6]);
|
|
76
|
-
temp ^= gfMultiply(input[7], L[7]);
|
|
77
|
-
temp ^= gfMultiply(input[8], L[8]);
|
|
78
|
-
temp ^= gfMultiply(input[9], L[9]);
|
|
79
|
-
temp ^= gfMultiply(input[10], L[10]);
|
|
80
|
-
temp ^= gfMultiply(input[11], L[11]);
|
|
81
|
-
temp ^= gfMultiply(input[12], L[12]);
|
|
82
|
-
temp ^= gfMultiply(input[13], L[13]);
|
|
83
|
-
temp ^= gfMultiply(input[14], L[14]);
|
|
84
|
-
temp ^= gfMultiply(input[15], L[15]);
|
|
85
|
-
result.set(input.slice(1));
|
|
86
|
-
result[15] = temp;
|
|
87
|
-
return result;
|
|
88
|
-
};
|
|
89
|
-
const LL = (input) => {
|
|
90
|
-
//let result = copyBytes(input);
|
|
91
|
-
//for(let i = 0; i < BLOCKSIZE; i++) result = R(result);
|
|
92
|
-
let result = R(copyBytes(input));
|
|
93
|
-
result = R(result);
|
|
94
|
-
result = R(result);
|
|
95
|
-
result = R(result);
|
|
96
|
-
result = R(result);
|
|
97
|
-
result = R(result);
|
|
98
|
-
result = R(result);
|
|
99
|
-
result = R(result);
|
|
100
|
-
result = R(result);
|
|
101
|
-
result = R(result);
|
|
102
|
-
result = R(result);
|
|
103
|
-
result = R(result);
|
|
104
|
-
result = R(result);
|
|
105
|
-
result = R(result);
|
|
106
|
-
result = R(result);
|
|
107
|
-
result = R(result);
|
|
108
|
-
return result;
|
|
109
|
-
};
|
|
110
|
-
const LLr = (input) => {
|
|
111
|
-
//let result = copyBytes(input);
|
|
112
|
-
//for(let i = 0; i < BLOCKSIZE; i++) result = Rr(result);
|
|
113
|
-
let result = Rr(copyBytes(input));
|
|
114
|
-
result = Rr(result);
|
|
115
|
-
result = Rr(result);
|
|
116
|
-
result = Rr(result);
|
|
117
|
-
result = Rr(result);
|
|
118
|
-
result = Rr(result);
|
|
119
|
-
result = Rr(result);
|
|
120
|
-
result = Rr(result);
|
|
121
|
-
result = Rr(result);
|
|
122
|
-
result = Rr(result);
|
|
123
|
-
result = Rr(result);
|
|
124
|
-
result = Rr(result);
|
|
125
|
-
result = Rr(result);
|
|
126
|
-
result = Rr(result);
|
|
127
|
-
result = Rr(result);
|
|
128
|
-
result = Rr(result);
|
|
129
|
-
return result;
|
|
130
|
-
};
|
|
17
|
+
const S = (input, pi = PI) => new Uint8Array([
|
|
18
|
+
pi[input[0]], pi[input[1]], pi[input[2]], pi[input[3]],
|
|
19
|
+
pi[input[4]], pi[input[5]], pi[input[6]], pi[input[7]],
|
|
20
|
+
pi[input[8]], pi[input[9]], pi[input[10]], pi[input[11]],
|
|
21
|
+
pi[input[12]], pi[input[13]], pi[input[14]], pi[input[15]]
|
|
22
|
+
]);
|
|
23
|
+
const R = (input) => new Uint8Array([
|
|
24
|
+
gfMultiply(input[15], L[0]) ^ gfMultiply(input[0], L[1]) ^
|
|
25
|
+
gfMultiply(input[1], L[2]) ^ gfMultiply(input[2], L[3]) ^
|
|
26
|
+
gfMultiply(input[3], L[4]) ^ gfMultiply(input[4], L[5]) ^
|
|
27
|
+
gfMultiply(input[5], L[6]) ^ gfMultiply(input[6], L[7]) ^
|
|
28
|
+
gfMultiply(input[7], L[8]) ^ gfMultiply(input[8], L[9]) ^
|
|
29
|
+
gfMultiply(input[9], L[10]) ^ gfMultiply(input[10], L[11]) ^
|
|
30
|
+
gfMultiply(input[11], L[12]) ^ gfMultiply(input[12], L[13]) ^
|
|
31
|
+
gfMultiply(input[13], L[14]) ^ gfMultiply(input[14], L[15]),
|
|
32
|
+
...input.subarray(0, 15)
|
|
33
|
+
]);
|
|
34
|
+
const Rr = (input) => new Uint8Array([
|
|
35
|
+
...input.subarray(1, 16),
|
|
36
|
+
gfMultiply(input[0], L[0]) ^ gfMultiply(input[1], L[1]) ^
|
|
37
|
+
gfMultiply(input[2], L[2]) ^ gfMultiply(input[3], L[3]) ^
|
|
38
|
+
gfMultiply(input[4], L[4]) ^ gfMultiply(input[5], L[5]) ^
|
|
39
|
+
gfMultiply(input[6], L[6]) ^ gfMultiply(input[7], L[7]) ^
|
|
40
|
+
gfMultiply(input[8], L[8]) ^ gfMultiply(input[9], L[9]) ^
|
|
41
|
+
gfMultiply(input[10], L[10]) ^ gfMultiply(input[11], L[11]) ^
|
|
42
|
+
gfMultiply(input[12], L[12]) ^ gfMultiply(input[13], L[13]) ^
|
|
43
|
+
gfMultiply(input[14], L[14]) ^ gfMultiply(input[15], L[15])
|
|
44
|
+
]);
|
|
45
|
+
// Call `R` 16x times
|
|
46
|
+
const LL = (input) => R(R(R(R(R(R(R(R(R(R(R(R(R(R(R(R(input))))))))))))))));
|
|
47
|
+
// Call `Rr` 16x times
|
|
48
|
+
const LLr = (input) => Rr(Rr(Rr(Rr(Rr(Rr(Rr(Rr(Rr(Rr(Rr(Rr(Rr(Rr(Rr(Rr(input))))))))))))))));
|
|
131
49
|
const LLS = (block) => LL(S(block));
|
|
132
50
|
const SLLr = (block) => S(LLr(block), PI_REV);
|
|
133
|
-
const F = (
|
|
51
|
+
const F = (inKey, inKey2, iter) => xorBytes(LLS(xorBytes(inKey, iter)), inKey2);
|
|
134
52
|
/** Kuznyechik (GOST R 34.12-2015) cipher */
|
|
135
53
|
export class Kuznyechik {
|
|
136
|
-
keySize =
|
|
137
|
-
blockSize =
|
|
54
|
+
keySize = 32;
|
|
55
|
+
blockSize = 16;
|
|
138
56
|
roundKeys;
|
|
139
57
|
/** Kuznyechik (GOST R 34.12-2015) cipher */
|
|
140
58
|
constructor(key) {
|
|
141
59
|
if (key.length !== this.keySize)
|
|
142
60
|
throw new Error("Invalid key length");
|
|
143
|
-
const roundKeys = Array(10)
|
|
61
|
+
const roundKeys = Array(10);
|
|
144
62
|
roundKeys[0] = key.slice(0, this.blockSize);
|
|
145
63
|
roundKeys[1] = key.slice(this.blockSize);
|
|
146
64
|
let temp1 = copyBytes(roundKeys[0]);
|
|
@@ -184,8 +102,7 @@ export class Kuznyechik {
|
|
|
184
102
|
currentBlock = LLS(xorBytes(this.roundKeys[6], currentBlock));
|
|
185
103
|
currentBlock = LLS(xorBytes(this.roundKeys[7], currentBlock));
|
|
186
104
|
currentBlock = LLS(xorBytes(this.roundKeys[8], currentBlock));
|
|
187
|
-
|
|
188
|
-
return currentBlock;
|
|
105
|
+
return xorBytes(this.roundKeys[9], currentBlock);
|
|
189
106
|
}
|
|
190
107
|
decrypt(ciphertext) {
|
|
191
108
|
if (ciphertext.length !== this.blockSize)
|
|
@@ -201,7 +118,6 @@ export class Kuznyechik {
|
|
|
201
118
|
currentBlock = xorBytes(this.roundKeys[3], SLLr(currentBlock));
|
|
202
119
|
currentBlock = xorBytes(this.roundKeys[2], SLLr(currentBlock));
|
|
203
120
|
currentBlock = xorBytes(this.roundKeys[1], SLLr(currentBlock));
|
|
204
|
-
|
|
205
|
-
return currentBlock;
|
|
121
|
+
return xorBytes(this.roundKeys[0], SLLr(currentBlock));
|
|
206
122
|
}
|
|
207
123
|
}
|
package/magma/index.js
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
import { bytesToNumberBE, concatBytes, copyBytes, numberToBytesBE } from "@noble/curves/utils.js";
|
|
2
2
|
import { ID_TC26_GOST_28147_PARAM_Z, magmaKeySequences } from "./const.js";
|
|
3
3
|
const BLOCKSIZE = 8, KEYSIZE = 32;
|
|
4
|
-
const T = (value, sbox) =>
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
result |= sbox[5][(value >> 20) & 0x0f] << 20;
|
|
13
|
-
result |= sbox[6][(value >> 24) & 0x0f] << 24;
|
|
14
|
-
result |= sbox[7][(value >> 28) & 0x0f] << 28;
|
|
15
|
-
return result >>> 0;
|
|
16
|
-
};
|
|
4
|
+
const T = (value, sbox) => ((sbox[0][(value >> 0) & 0x0f] << 0) |
|
|
5
|
+
(sbox[1][(value >> 4) & 0x0f] << 4) |
|
|
6
|
+
(sbox[2][(value >> 8) & 0x0f] << 8) |
|
|
7
|
+
(sbox[3][(value >> 12) & 0x0f] << 12) |
|
|
8
|
+
(sbox[4][(value >> 16) & 0x0f] << 16) |
|
|
9
|
+
(sbox[5][(value >> 20) & 0x0f] << 20) |
|
|
10
|
+
(sbox[6][(value >> 24) & 0x0f] << 24) |
|
|
11
|
+
(sbox[7][(value >> 28) & 0x0f] << 28)) >>> 0;
|
|
17
12
|
const G = (a, k, sbox) => {
|
|
18
13
|
const substituted = T((a + k) >>> 0, sbox);
|
|
19
14
|
return ((substituted << 11) | (substituted >>> 21)) >>> 0;
|
package/modes/_keytransform.js
CHANGED
|
@@ -3,22 +3,19 @@ import { Magma } from "../magma/index.js";
|
|
|
3
3
|
import { ID_GOST_28147_89_CRYPTO_PRO_A_PARAM_SET } from "../magma/const.js";
|
|
4
4
|
import { cfb } from "./cfb.js";
|
|
5
5
|
import { ctr } from "./ctr.js";
|
|
6
|
-
import { hexToBytes } from "@noble/hashes/utils.js";
|
|
7
|
-
import { ecb } from "./ecb.js";
|
|
8
6
|
export const cp_kek_diversify = (kek, ukm, sbox = ID_GOST_28147_89_CRYPTO_PRO_A_PARAM_SET) => {
|
|
9
7
|
let out = copyBytes(kek);
|
|
10
8
|
for (let i = 0; i < 8; i++) {
|
|
11
9
|
let s1 = 0, s2 = 0;
|
|
12
10
|
for (let j = 0; j < 8; j++) {
|
|
13
|
-
const k = Number(bytesToNumberLE(out.subarray(j * 4, j * 4 + 4)));
|
|
11
|
+
const k = Number(bytesToNumberLE(out.subarray(j * 4, j * 4 + 4)));
|
|
14
12
|
if ((ukm[i] >> j) & 1)
|
|
15
13
|
s1 += k;
|
|
16
14
|
else
|
|
17
15
|
s2 += k;
|
|
18
16
|
}
|
|
19
17
|
const iv = concatBytes(numberToBytesLE(s1 >>> 0, 4), numberToBytesLE(s2 >>> 0, 4));
|
|
20
|
-
|
|
21
|
-
out = cfb(cipher, iv).encrypt(out);
|
|
18
|
+
out = cfb(new Magma(out, sbox, true), iv).encrypt(out);
|
|
22
19
|
}
|
|
23
20
|
return out;
|
|
24
21
|
};
|
package/oids/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type GostCurveParameters } from "../gost3410/const.js";
|
|
2
|
+
import type { HashFunctionWrapper } from "../types.js";
|
|
3
|
+
/** Get curve parameters by OID */
|
|
4
|
+
export declare const getCurveByOid: (oid: string) => GostCurveParameters | undefined;
|
|
5
|
+
/** Get hash function by OID */
|
|
6
|
+
export declare const getHashByOid: (oid: string) => HashFunctionWrapper | undefined;
|
package/oids/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CURVES } from "../gost3410/const.js";
|
|
2
|
+
import { gost341194 } from "../gost341194/index.js";
|
|
3
|
+
import { streebog256, streebog512 } from "../streebog/index.js";
|
|
4
|
+
const HASHES_OID = {
|
|
5
|
+
"1.2.643.7.1.1.2.1": gost341194,
|
|
6
|
+
"1.2.643.7.1.1.2.2": streebog256,
|
|
7
|
+
"1.2.643.7.1.1.2.3": streebog512
|
|
8
|
+
};
|
|
9
|
+
/** Get curve parameters by OID */
|
|
10
|
+
export const getCurveByOid = (oid) => {
|
|
11
|
+
for (const [_, params] of Object.entries(CURVES))
|
|
12
|
+
if (params.oids?.includes(oid))
|
|
13
|
+
return params;
|
|
14
|
+
};
|
|
15
|
+
/** Get hash function by OID */
|
|
16
|
+
export const getHashByOid = (oid) => HASHES_OID[oid];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@li0ard/gost",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"./kuznyechik.js": "./kuznyechik/index.js",
|
|
12
12
|
"./magma.js": "./magma/index.js",
|
|
13
13
|
"./modes.js": "./modes/index.js",
|
|
14
|
+
"./oids.js": "./oids/index.js",
|
|
14
15
|
"./streebog.js": "./streebog/index.js",
|
|
15
16
|
"./hmac.js": "./hmac.js",
|
|
16
17
|
"./kdf.js": "./kdf.js",
|
|
@@ -33,6 +34,8 @@
|
|
|
33
34
|
"docs": "typedoc --options .config/typedoc/config.cjs"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
37
|
+
"@peculiar/asn1-schema": "^2.7.0",
|
|
38
|
+
"@peculiar/asn1-x509": "^2.7.0",
|
|
36
39
|
"@types/bun": "latest",
|
|
37
40
|
"typedoc": "^0.28.19"
|
|
38
41
|
},
|
package/streebog/index.js
CHANGED
|
@@ -20,144 +20,32 @@ const add512 = (a, b) => {
|
|
|
20
20
|
}
|
|
21
21
|
return c;
|
|
22
22
|
};
|
|
23
|
-
const S = (input) =>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
result[23] = PI[input[23]];
|
|
50
|
-
result[24] = PI[input[24]];
|
|
51
|
-
result[25] = PI[input[25]];
|
|
52
|
-
result[26] = PI[input[26]];
|
|
53
|
-
result[27] = PI[input[27]];
|
|
54
|
-
result[28] = PI[input[28]];
|
|
55
|
-
result[29] = PI[input[29]];
|
|
56
|
-
result[30] = PI[input[30]];
|
|
57
|
-
result[31] = PI[input[31]];
|
|
58
|
-
result[32] = PI[input[32]];
|
|
59
|
-
result[33] = PI[input[33]];
|
|
60
|
-
result[34] = PI[input[34]];
|
|
61
|
-
result[35] = PI[input[35]];
|
|
62
|
-
result[36] = PI[input[36]];
|
|
63
|
-
result[37] = PI[input[37]];
|
|
64
|
-
result[38] = PI[input[38]];
|
|
65
|
-
result[39] = PI[input[39]];
|
|
66
|
-
result[40] = PI[input[40]];
|
|
67
|
-
result[41] = PI[input[41]];
|
|
68
|
-
result[42] = PI[input[42]];
|
|
69
|
-
result[43] = PI[input[43]];
|
|
70
|
-
result[44] = PI[input[44]];
|
|
71
|
-
result[45] = PI[input[45]];
|
|
72
|
-
result[46] = PI[input[46]];
|
|
73
|
-
result[47] = PI[input[47]];
|
|
74
|
-
result[48] = PI[input[48]];
|
|
75
|
-
result[49] = PI[input[49]];
|
|
76
|
-
result[50] = PI[input[50]];
|
|
77
|
-
result[51] = PI[input[51]];
|
|
78
|
-
result[52] = PI[input[52]];
|
|
79
|
-
result[53] = PI[input[53]];
|
|
80
|
-
result[54] = PI[input[54]];
|
|
81
|
-
result[55] = PI[input[55]];
|
|
82
|
-
result[56] = PI[input[56]];
|
|
83
|
-
result[57] = PI[input[57]];
|
|
84
|
-
result[58] = PI[input[58]];
|
|
85
|
-
result[59] = PI[input[59]];
|
|
86
|
-
result[60] = PI[input[60]];
|
|
87
|
-
result[61] = PI[input[61]];
|
|
88
|
-
result[62] = PI[input[62]];
|
|
89
|
-
result[63] = PI[input[63]];
|
|
90
|
-
return result;
|
|
91
|
-
};
|
|
92
|
-
const P = (input) => {
|
|
93
|
-
const result = new Uint8Array(BLOCKSIZE);
|
|
94
|
-
//for (let i = 0; i < BLOCKSIZE; i++) result[i] = input[TAU[i]];
|
|
95
|
-
result[0] = input[TAU[0]];
|
|
96
|
-
result[1] = input[TAU[1]];
|
|
97
|
-
result[2] = input[TAU[2]];
|
|
98
|
-
result[3] = input[TAU[3]];
|
|
99
|
-
result[4] = input[TAU[4]];
|
|
100
|
-
result[5] = input[TAU[5]];
|
|
101
|
-
result[6] = input[TAU[6]];
|
|
102
|
-
result[7] = input[TAU[7]];
|
|
103
|
-
result[8] = input[TAU[8]];
|
|
104
|
-
result[9] = input[TAU[9]];
|
|
105
|
-
result[10] = input[TAU[10]];
|
|
106
|
-
result[11] = input[TAU[11]];
|
|
107
|
-
result[12] = input[TAU[12]];
|
|
108
|
-
result[13] = input[TAU[13]];
|
|
109
|
-
result[14] = input[TAU[14]];
|
|
110
|
-
result[15] = input[TAU[15]];
|
|
111
|
-
result[16] = input[TAU[16]];
|
|
112
|
-
result[17] = input[TAU[17]];
|
|
113
|
-
result[18] = input[TAU[18]];
|
|
114
|
-
result[19] = input[TAU[19]];
|
|
115
|
-
result[20] = input[TAU[20]];
|
|
116
|
-
result[21] = input[TAU[21]];
|
|
117
|
-
result[22] = input[TAU[22]];
|
|
118
|
-
result[23] = input[TAU[23]];
|
|
119
|
-
result[24] = input[TAU[24]];
|
|
120
|
-
result[25] = input[TAU[25]];
|
|
121
|
-
result[26] = input[TAU[26]];
|
|
122
|
-
result[27] = input[TAU[27]];
|
|
123
|
-
result[28] = input[TAU[28]];
|
|
124
|
-
result[29] = input[TAU[29]];
|
|
125
|
-
result[30] = input[TAU[30]];
|
|
126
|
-
result[31] = input[TAU[31]];
|
|
127
|
-
result[32] = input[TAU[32]];
|
|
128
|
-
result[33] = input[TAU[33]];
|
|
129
|
-
result[34] = input[TAU[34]];
|
|
130
|
-
result[35] = input[TAU[35]];
|
|
131
|
-
result[36] = input[TAU[36]];
|
|
132
|
-
result[37] = input[TAU[37]];
|
|
133
|
-
result[38] = input[TAU[38]];
|
|
134
|
-
result[39] = input[TAU[39]];
|
|
135
|
-
result[40] = input[TAU[40]];
|
|
136
|
-
result[41] = input[TAU[41]];
|
|
137
|
-
result[42] = input[TAU[42]];
|
|
138
|
-
result[43] = input[TAU[43]];
|
|
139
|
-
result[44] = input[TAU[44]];
|
|
140
|
-
result[45] = input[TAU[45]];
|
|
141
|
-
result[46] = input[TAU[46]];
|
|
142
|
-
result[47] = input[TAU[47]];
|
|
143
|
-
result[48] = input[TAU[48]];
|
|
144
|
-
result[49] = input[TAU[49]];
|
|
145
|
-
result[50] = input[TAU[50]];
|
|
146
|
-
result[51] = input[TAU[51]];
|
|
147
|
-
result[52] = input[TAU[52]];
|
|
148
|
-
result[53] = input[TAU[53]];
|
|
149
|
-
result[54] = input[TAU[54]];
|
|
150
|
-
result[55] = input[TAU[55]];
|
|
151
|
-
result[56] = input[TAU[56]];
|
|
152
|
-
result[57] = input[TAU[57]];
|
|
153
|
-
result[58] = input[TAU[58]];
|
|
154
|
-
result[59] = input[TAU[59]];
|
|
155
|
-
result[60] = input[TAU[60]];
|
|
156
|
-
result[61] = input[TAU[61]];
|
|
157
|
-
result[62] = input[TAU[62]];
|
|
158
|
-
result[63] = input[TAU[63]];
|
|
159
|
-
return result;
|
|
160
|
-
};
|
|
23
|
+
const S = (input) => new Uint8Array([
|
|
24
|
+
PI[input[0]], PI[input[1]], PI[input[2]], PI[input[3]], PI[input[4]], PI[input[5]],
|
|
25
|
+
PI[input[6]], PI[input[7]], PI[input[8]], PI[input[9]], PI[input[10]], PI[input[11]],
|
|
26
|
+
PI[input[12]], PI[input[13]], PI[input[14]], PI[input[15]], PI[input[16]], PI[input[17]],
|
|
27
|
+
PI[input[18]], PI[input[19]], PI[input[20]], PI[input[21]], PI[input[22]], PI[input[23]],
|
|
28
|
+
PI[input[24]], PI[input[25]], PI[input[26]], PI[input[27]], PI[input[28]], PI[input[29]],
|
|
29
|
+
PI[input[30]], PI[input[31]], PI[input[32]], PI[input[33]], PI[input[34]], PI[input[35]],
|
|
30
|
+
PI[input[36]], PI[input[37]], PI[input[38]], PI[input[39]], PI[input[40]], PI[input[41]],
|
|
31
|
+
PI[input[42]], PI[input[43]], PI[input[44]], PI[input[45]], PI[input[46]], PI[input[47]],
|
|
32
|
+
PI[input[48]], PI[input[49]], PI[input[50]], PI[input[51]], PI[input[52]], PI[input[53]],
|
|
33
|
+
PI[input[54]], PI[input[55]], PI[input[56]], PI[input[57]], PI[input[58]], PI[input[59]],
|
|
34
|
+
PI[input[60]], PI[input[61]], PI[input[62]], PI[input[63]]
|
|
35
|
+
]);
|
|
36
|
+
const P = (input) => new Uint8Array([
|
|
37
|
+
input[TAU[0]], input[TAU[1]], input[TAU[2]], input[TAU[3]], input[TAU[4]], input[TAU[5]],
|
|
38
|
+
input[TAU[6]], input[TAU[7]], input[TAU[8]], input[TAU[9]], input[TAU[10]], input[TAU[11]],
|
|
39
|
+
input[TAU[12]], input[TAU[13]], input[TAU[14]], input[TAU[15]], input[TAU[16]], input[TAU[17]],
|
|
40
|
+
input[TAU[18]], input[TAU[19]], input[TAU[20]], input[TAU[21]], input[TAU[22]], input[TAU[23]],
|
|
41
|
+
input[TAU[24]], input[TAU[25]], input[TAU[26]], input[TAU[27]], input[TAU[28]], input[TAU[29]],
|
|
42
|
+
input[TAU[30]], input[TAU[31]], input[TAU[32]], input[TAU[33]], input[TAU[34]], input[TAU[35]],
|
|
43
|
+
input[TAU[36]], input[TAU[37]], input[TAU[38]], input[TAU[39]], input[TAU[40]], input[TAU[41]],
|
|
44
|
+
input[TAU[42]], input[TAU[43]], input[TAU[44]], input[TAU[45]], input[TAU[46]], input[TAU[47]],
|
|
45
|
+
input[TAU[48]], input[TAU[49]], input[TAU[50]], input[TAU[51]], input[TAU[52]], input[TAU[53]],
|
|
46
|
+
input[TAU[54]], input[TAU[55]], input[TAU[56]], input[TAU[57]], input[TAU[58]], input[TAU[59]],
|
|
47
|
+
input[TAU[60]], input[TAU[61]], input[TAU[62]], input[TAU[63]]
|
|
48
|
+
]);
|
|
161
49
|
const L = (input) => {
|
|
162
50
|
const result = new Uint8Array(BLOCKSIZE);
|
|
163
51
|
for (let i = 0; i < 8; i++) {
|
|
@@ -181,8 +69,7 @@ const E = (block, keys) => {
|
|
|
181
69
|
// block will be mutated
|
|
182
70
|
let c = xorBytes(block, keys);
|
|
183
71
|
/*for (let i = 0; i < 12; i++) {
|
|
184
|
-
block = LPS(xorBytes(block, C[i]));
|
|
185
|
-
c = xorBytes(LPS(c), block);
|
|
72
|
+
block = LPS(xorBytes(block, C[i])); c = xorBytes(LPS(c), block);
|
|
186
73
|
}*/
|
|
187
74
|
block = LPS(xorBytes(block, C[0]));
|
|
188
75
|
c = xorBytes(LPS(c), block);
|
|
@@ -236,24 +123,24 @@ class Streebog {
|
|
|
236
123
|
}
|
|
237
124
|
digestInto(buf) {
|
|
238
125
|
const message = this.buffer.slice().reverse();
|
|
239
|
-
let n = new Uint8Array(
|
|
240
|
-
let sigma = new Uint8Array(
|
|
241
|
-
let hash = new Uint8Array(
|
|
126
|
+
let n = new Uint8Array(this.blockLen);
|
|
127
|
+
let sigma = new Uint8Array(this.blockLen);
|
|
128
|
+
let hash = new Uint8Array(this.blockLen).fill(this.is512 ? 0 : 1);
|
|
242
129
|
let blocks = 1;
|
|
243
|
-
for (let i = message.length; i >=
|
|
244
|
-
const pos = message.length - blocks *
|
|
245
|
-
hash = G(n, hash, message.subarray(pos, pos +
|
|
130
|
+
for (let i = message.length; i >= this.blockLen; i -= this.blockLen) {
|
|
131
|
+
const pos = message.length - blocks * this.blockLen;
|
|
132
|
+
hash = G(n, hash, message.subarray(pos, pos + this.blockLen));
|
|
246
133
|
n = add512(n, _0020);
|
|
247
|
-
sigma = add512(sigma, message.subarray(pos, pos +
|
|
134
|
+
sigma = add512(sigma, message.subarray(pos, pos + this.blockLen));
|
|
248
135
|
blocks++;
|
|
249
136
|
}
|
|
250
|
-
let paddedMsg = new Uint8Array(
|
|
137
|
+
let paddedMsg = new Uint8Array(this.blockLen);
|
|
251
138
|
const msg = message.subarray(0, message.length - (blocks - 1) * 64);
|
|
252
|
-
if (msg.length <
|
|
253
|
-
paddedMsg = pad1(paddedMsg,
|
|
254
|
-
paddedMsg[
|
|
139
|
+
if (msg.length < this.blockLen) {
|
|
140
|
+
paddedMsg = pad1(paddedMsg, this.blockLen);
|
|
141
|
+
paddedMsg[this.blockLen - msg.length - 1] = 0x01;
|
|
255
142
|
for (let i = 0; i < msg.length; i++)
|
|
256
|
-
paddedMsg[
|
|
143
|
+
paddedMsg[this.blockLen - msg.length + i] = msg[i];
|
|
257
144
|
}
|
|
258
145
|
hash = G(_0, G(_0, G(n, hash, paddedMsg), add512(n, numberToBytesBE(msg.length * 8, 4))), add512(sigma, paddedMsg));
|
|
259
146
|
if (this.is512)
|