Using the key

73 3d 2c 20 65 68 65 73 74 74 67 69 79 67 61 20 62 6e 73 73 20 65 73 69 32 6c 65 68 33 20 6d 54, 

I encrypt 00 00 00 00 00 00 00 00 . At the beginning I break the text into two halves: B = 00 00 00 00 and A = 00 00 00 00 and the key into 8 parts:

 K1 = 33 20 6d 54, K2 = 32 6c 65 68, K3 = 20 65 73 69, K4 = 62 6e 73 73, K5 = 79 67 61 20, K6 = 74 74 67 69, K7 = 65 68 65 73, K8 = 73 3d 2c 20. 

Then I add A with K1 modulo 2 to 32 degrees, I get 33 20 6d 54 . As a replacement table I use:

 {4, e, 5, 7, 6, 4, d, 1}, {a, b, 8, d, c, b, b, f}, {9, 4, 1, a, 7, a, 4, d}, {2, c, d, 1, 1, 0, 1, 0}, {d, 6, a, 0, 5, 7, 3, 5}, {8, d, 3, 8, f, 2, f, 7}, {0, f, 4, 9, d, 1, 5, a}, {e, a, 2, f, 8, d, 9, 4}, {6, 2, e, e, 4, 3, 0, 9}, {b, 3, f, 4, a, 6, a, 2}, {1, 8, c, 6, 9, 8, e, 3}, {c, 1, 7, c, e, 5, 7, e}, {7, 0, 6, b, 0, 9, 6, 6}, {f, 7, 0, 2, 3, c, 8, b}, {5, 5, 9, 5, b, f, 2, 8}, {3, 9, b, 3, 2, e, c, c}. 

3 I replace with 2, 3 with c, 2 with 1, 0 with 7, 6 with d, d with c, 5 with f, 4 with 5. I get 2c 17 dc f5 .
11-bit be e7 a9 60 left gives: be e7 a9 60
Next, the result obtained is XOR B and I get be e7 a9 60
Now the problem itself: after all 32 steps of the cycle, the result should be 42 AB BC CE 32 BC 0B 1B (example from GOST 34.11-94. Https://ru.wikipedia.org/wiki/%D0%93%D0%9E% D0% A1% D0% A2_% D0% A0_34.11-94 ), but it turns out different. Tell me, please, what am I doing wrong?

Code example:

 private String encrypt(BigInteger[] key, String strForA, String strForB) { int index = 0; BigInteger A = new BigInteger(strForA, 16); BigInteger B = new BigInteger(strForB, 16); BigInteger interA = BigInteger.ZERO; System.out.println("A = " + A.toString(16)); for (int i = 0; i < 32; i++) { System.out.println("ЦИКЛ " + i); if (i < 24) index = i % 8; else index = 7 - (i % 8); interA = multiply(A, key[index]); interA = B.xor(interA); if (i < 31) { B = A; A = interA; } else B = interA; } String resultB = B.toString(16); String resultA = A.toString(16); while (resultB.length() % 2 != 0) resultB = 0 + resultB; while (resultA.length() % 2 != 0) resultA = 0 + resultA; return resultB + resultA; } private BigInteger multiply(BigInteger a, BigInteger b) { BigInteger sum = a.add(b).mod(MODUL); String sumString = sum.toString(16); String newSumString = ""; while (sumString.length() < 8) sumString = 0 + sumString; for (int i = 0; i < sumString.length(); i++) { newSumString += Integer.toString(ReplacementTable.table[Integer.parseInt(sumString.substring(i, i + 1), 16)][i], 16); } BigInteger result = new BigInteger(newSumString, 16); return shift(result); } private BigInteger shift(BigInteger number) { StringBuilder sb = new StringBuilder(number.toString(2)); while (sb.toString().length() < 32) sb.insert(0, '0'); for (int i = 0; i < 11; i++) { sb.append(sb.charAt(0)); sb.deleteCharAt(0); } String afterShift = sb.toString(); return new BigInteger(afterShift, 2); } 
  • add sample code - Mikhail Vaysman
  • @MikhailVaysman, added - Alexander

1 answer 1

I made a mistake when dividing the key into 8 parts and using the replacement table. It was necessary to start replacing at the end of the line.
GOST 28147-89 in the simple replacement mode. Algorithm.
K is the key.
A - low bits.
B - high bits.
The key K is divided into 8 keys, and K = {K8, K7, K6, K5, K4, K3, K2, K1}.
A stacks with one of the 8 resulting keys modulo 2 to the power of 32.
We get S = (A + Ki) mod 2 ^ 32.
The resulting S is divided into 8 parts, and S = {S8, S7, S6, S5, S4, S3, S2, S1}.
Next, the resulting 4-bit characters are converted using the replacement table.
The first is S1, it turns out S1 ', then S2, it turns out S2' and so on.
After this operation we get S '= {S8', S7 ', S6', S5 ', S4', S3 ', S2', S1 '}.
Next, the resulting S 'cyclically shift left by 11 bits, we get R.
Now, applying the XOR operation, we get the result of the step:
RESULT = R XOR B.
Perform permutation:
B = A,
A = RESULT.
In a cycle of 32 steps. The first 24 steps of the keys are given in order K1, K2, K3, K4, K5, K6, K7, K8, K1, K2, K3, K4, K5, K6, K7, K8, K1, K2, K3, K4, K5, K6 , K7, K8. From step 25 to 32, the keys are served in the reverse order: K8, K7, K6, K5, K4, K3, K2, K1.
After 32 steps, the result is glued as follows - first the low bits A, then the high bits B.

A detailed example of the first step of the cycle.
K = 73 3d 2c 20 65 68 65 73 74 74 67 69 79 67 61 20 62 6e 73 73 20 65 73 69 32 6c 65 68 33 20 6d 54, encrypt 00 00 00 00 00 00 00 00 00. At the beginning I break the text into two halves: B = 00 00 00 00 and A = 00 00 00 00 and a key in 8 parts:
K8 = 73 3d 2c 20,
K7 = 65 68 65 73,
K6 = 74 74 67 69,
K5 = 79 67 61 20,
K4 = 62 6e 73 73,
K3 = 20 65 73 69,
K2 = 32 6c 65 68,
K1 = 33 20 6d 54.
Then I add A with K1 modulo 2 to 32 degrees, I get 33 20 6d 54. As a replacement table, I use the replacement table of the Central Bank of the Russian Federation:
{4, e, 5, 7, 6, 4, d, 1},
{a, b, 8, d, c, b, b, f},
{9, 4, 1, a, 7, a, 4, d},
{2, c, d, 1, 1, 0, 1, 0},
{d, 6, a, 0, 5, 7, 3, 5},
{8, d, 3, 8, f, 2, f, 7},
{0, f, 4, 9, d, 1, 5, a},
{e, a, 2, f, 8, d, 9, 4},
{6, 2, e, e, 4, 3, 0, 9},
{b, 3, f, 4, a, 6, a, 2},
{1, 8, c, 6, 9, 8, e, 3},
{c, 1, 7, c, e, 5, 7, e},
{7, 0, 6, b, 0, 9, 6, 6},
{f, 7, 0, 2, 3, c, 8, b},
{5, 5, 9, 5, b, f, 2, 8},
{3, 9, b, 3, 2, e, c, c}.
4 I replace d, 5 with d, d with 0, 6 with 9, 0 with 6, 2 with a, 3 with 1, 3 with 0
I get 01 a6 90 dd.
Cyclic shift to the left by 11 bits gives: 34 86 e8 0d
Next, the result obtained XOR B and get 34 86 e8 0d
Now
B = A = 00 00 00 00
A = 34 86 e8 0d

The result of the 32 steps will be
42 ab bc ce 32 bc 0b 1b