@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.
@@ -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
+ };
@@ -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`)
@@ -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");
@@ -1,5 +1,5 @@
1
1
  import { type TArg, type TRet } from "@noble/curves/utils.js";
2
- import { type GostCurveParameters } from "./const.js";
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.slice(0, size));
64
- const s = bytesToNumberBE(signature.slice(size));
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));
@@ -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: number;
6
+ readonly blockLen = 32;
7
7
  readonly outputLen = 32;
8
8
  readonly canXOF = false;
9
9
  /** GOST R 34.11-94 hash function */
@@ -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 C4 = new Uint8Array(32);
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
- let u = hin;
44
- let v = m;
45
- let w = xorBytes(hin, m);
46
- const k1 = new Magma(P(w).reverse(), sbox, true);
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
- w = xorBytes(u, v);
54
- const k3 = new Magma(P(w).reverse(), sbox, true);
55
- u = xorBytes(A(u), C4);
33
+ const k3 = _getMagma(u, v, sbox);
34
+ u = A(u);
56
35
  v = A(A(v));
57
- w = xorBytes(u, v);
58
- const k4 = new Magma(P(w).reverse(), sbox, true);
59
- const s = 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());
60
- //let x = new Uint8Array(s);
61
- //for(let i = 0; i < 12; i++) x = chi(x);
62
- let x = chi(s);
63
- x = chi(x);
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 = BLOCKSIZE;
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(BLOCKSIZE);
74
+ const h = new Uint8Array(this.blockLen);
171
75
  const m = new Uint8Array(this.data);
172
- for (let i = 0; i < m.length; i += BLOCKSIZE) {
173
- let part = m.slice(i, i + BLOCKSIZE).reverse();
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 < BLOCKSIZE)
177
- part = numberToBytesBE(bytesToNumberBE(part), BLOCKSIZE);
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, BLOCKSIZE), this.sbox), numberToBytesBE(checksum, BLOCKSIZE), this.sbox));
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";
@@ -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).fill(0));
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]);
@@ -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 high_bit;
29
- for (let i = 0; i < 8; i++) {
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 & 0b10000000;
9
+ high_bit = a & 0x80;
33
10
  a <<= 1;
34
- if (high_bit == 0b10000000)
35
- a ^= 0b11000011;
11
+ if (high_bit == 0x80)
12
+ a ^= 0xC3;
36
13
  b >>= 1;
37
14
  }
38
15
  return result & 0xFF;
39
16
  };
40
- const R = (input) => {
41
- const result = new Uint8Array(BLOCKSIZE);
42
- result.set(input.slice(0, 15), 1);
43
- result[0] = input[15];
44
- //let temp = 0;
45
- //for (let i = 0; i < BLOCKSIZE; i++) temp ^= gfMultiply(result[i], L[i]);
46
- let temp = gfMultiply(result[0], L[0]);
47
- temp ^= gfMultiply(result[1], L[1]);
48
- temp ^= gfMultiply(result[2], L[2]);
49
- temp ^= gfMultiply(result[3], L[3]);
50
- temp ^= gfMultiply(result[4], L[4]);
51
- temp ^= gfMultiply(result[5], L[5]);
52
- temp ^= gfMultiply(result[6], L[6]);
53
- temp ^= gfMultiply(result[7], L[7]);
54
- temp ^= gfMultiply(result[8], L[8]);
55
- temp ^= gfMultiply(result[9], L[9]);
56
- temp ^= gfMultiply(result[10], L[10]);
57
- temp ^= gfMultiply(result[11], L[11]);
58
- temp ^= gfMultiply(result[12], L[12]);
59
- temp ^= gfMultiply(result[13], L[13]);
60
- temp ^= gfMultiply(result[14], L[14]);
61
- temp ^= gfMultiply(result[15], L[15]);
62
- result[0] = temp;
63
- return result;
64
- };
65
- const Rr = (input) => {
66
- const result = new Uint8Array(BLOCKSIZE);
67
- //let temp = 0;
68
- //for (let i = 0; i < BLOCKSIZE; i++) temp ^= gfMultiply(input[i], L[i]);
69
- let temp = gfMultiply(input[0], L[0]);
70
- temp ^= gfMultiply(input[1], L[1]);
71
- temp ^= gfMultiply(input[2], L[2]);
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 = (in_key1, in_key2, iter_constant) => xorBytes(LLS(xorBytes(in_key1, iter_constant)), in_key2);
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 = KEYSIZE;
137
- blockSize = 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).fill(null).map(() => new Uint8Array(this.blockSize));
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
- currentBlock = xorBytes(this.roundKeys[9], currentBlock);
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
- currentBlock = xorBytes(this.roundKeys[0], SLLr(currentBlock));
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
- //let result = 0;
6
- //for (let i = 0; i < 8; i++) result |= sbox[i][(value >> (4 * i)) & 0x0f] << (4 * i);
7
- let result = sbox[0][(value >> 0) & 0x0f] << 0;
8
- result |= sbox[1][(value >> 4) & 0x0f] << 4;
9
- result |= sbox[2][(value >> 8) & 0x0f] << 8;
10
- result |= sbox[3][(value >> 12) & 0x0f] << 12;
11
- result |= sbox[4][(value >> 16) & 0x0f] << 16;
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;
@@ -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))); //((out[j * 4]) | (out[j * 4 + 1] << 8) | (out[j * 4 + 2] << 16) | (out[j * 4 + 3] << 24)) >>> 0;
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
- const cipher = new Magma(out, sbox, true);
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
  };
@@ -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.4",
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
- const result = new Uint8Array(BLOCKSIZE);
25
- //for (let i = 0; i < BLOCKSIZE; i++) result[i] = PI[input[i]];
26
- result[0] = PI[input[0]];
27
- result[1] = PI[input[1]];
28
- result[2] = PI[input[2]];
29
- result[3] = PI[input[3]];
30
- result[4] = PI[input[4]];
31
- result[5] = PI[input[5]];
32
- result[6] = PI[input[6]];
33
- result[7] = PI[input[7]];
34
- result[8] = PI[input[8]];
35
- result[9] = PI[input[9]];
36
- result[10] = PI[input[10]];
37
- result[11] = PI[input[11]];
38
- result[12] = PI[input[12]];
39
- result[13] = PI[input[13]];
40
- result[14] = PI[input[14]];
41
- result[15] = PI[input[15]];
42
- result[16] = PI[input[16]];
43
- result[17] = PI[input[17]];
44
- result[18] = PI[input[18]];
45
- result[19] = PI[input[19]];
46
- result[20] = PI[input[20]];
47
- result[21] = PI[input[21]];
48
- result[22] = PI[input[22]];
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(BLOCKSIZE);
240
- let sigma = new Uint8Array(BLOCKSIZE);
241
- let hash = new Uint8Array(BLOCKSIZE).fill(this.is512 ? 0 : 1);
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 >= BLOCKSIZE; i -= BLOCKSIZE) {
244
- const pos = message.length - blocks * BLOCKSIZE;
245
- hash = G(n, hash, message.subarray(pos, pos + BLOCKSIZE));
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 + BLOCKSIZE));
134
+ sigma = add512(sigma, message.subarray(pos, pos + this.blockLen));
248
135
  blocks++;
249
136
  }
250
- let paddedMsg = new Uint8Array(BLOCKSIZE);
137
+ let paddedMsg = new Uint8Array(this.blockLen);
251
138
  const msg = message.subarray(0, message.length - (blocks - 1) * 64);
252
- if (msg.length < BLOCKSIZE) {
253
- paddedMsg = pad1(paddedMsg, BLOCKSIZE);
254
- paddedMsg[BLOCKSIZE - msg.length - 1] = 0x01;
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[BLOCKSIZE - msg.length + i] = msg[i];
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)
package/types.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { TArg, TRet } from "@noble/hashes/utils.js";
2
+ export type HashFunctionWrapper = (msg: TArg<Uint8Array>) => TRet<Uint8Array>;
2
3
  /** Cipher core */
3
4
  export type Cipher = {
4
5
  /** Block size */