1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
/*
* GOST 28147-89
* (C) 1999-2009 Jack Lloyd
*/
#include <botan/gost_28147.h>
#include <botan/loadstor.h>
namespace Botan {
/*
* GOST Constructor
*/
GOST_28147_89::GOST_28147_89() : BlockCipher(8, 32)
{
// GostR3411_94_TestParamSet (OID 1.2.643.2.2.31.0)
const byte sbox[8][16] = {
{0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3}
{0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9},
{0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB},
{0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3},
{0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2},
{0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE},
{0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC},
{0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC},
};
for(size_t i = 0; i != 4; ++i)
for(size_t j = 0; j != 256; ++j)
{
u32bit T = sbox[2*i][j%16] | (sbox[2*i+1][j/16] << 4);
SBOX[256*i+j] = rotate_left(T, (11+8*i) % 32);
}
}
/*
* GOST Encryption
*/
void GOST_28147_89::enc(const byte in[], byte out[]) const
{
u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1);
for(u32bit j = 0; j != 32; j += 2)
{
u32bit T0;
T0 = N1 + EK[j];
N2 ^= SBOX[get_byte(3, T0)] |
SBOX[get_byte(2, T0)+256] |
SBOX[get_byte(1, T0)+512] |
SBOX[get_byte(0, T0)+768];
T0 = N2 + EK[j+1];
N1 ^= SBOX[get_byte(3, T0)] |
SBOX[get_byte(2, T0)+256] |
SBOX[get_byte(1, T0)+512] |
SBOX[get_byte(0, T0)+768];
}
store_le(out, N2, N1);
}
/*
* GOST Decryption
*/
void GOST_28147_89::dec(const byte in[], byte out[]) const
{
u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1);
for(u32bit j = 0; j != 32; j += 2)
{
u32bit T0;
T0 = N1 + EK[31-j];
N2 ^= SBOX[get_byte(3, T0)] |
SBOX[get_byte(2, T0)+256] |
SBOX[get_byte(1, T0)+512] |
SBOX[get_byte(0, T0)+768];
T0 = N2 + EK[30-j];
N1 ^= SBOX[get_byte(3, T0)] |
SBOX[get_byte(2, T0)+256] |
SBOX[get_byte(1, T0)+512] |
SBOX[get_byte(0, T0)+768];
}
store_le(out, N2, N1);
}
/*
* GOST Key Schedule
*/
void GOST_28147_89::key_schedule(const byte key[], u32bit)
{
for(u32bit j = 0; j != 8; ++j)
{
u32bit K = load_le<u32bit>(key, j);
EK[j] = EK[j+8] = EK[j+16] = K;
}
for(u32bit j = 24; j != 32; ++j)
EK[j] = EK[7-(j-24)];
}
}
|