Botan 1.10.17

gost_28147.cpp
Go to the documentation of this file.
1 /*
2 * GOST 28147-89
3 * (C) 1999-2009,2011 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7
8 #include <botan/gost_28147.h>
9 #include <botan/loadstor.h>
10 #include <botan/rotate.h>
11
12 namespace Botan {
13
14 byte GOST_28147_89_Params::sbox_entry(size_t row, size_t col) const
15 {
16 byte x = sboxes[4 * col + (row / 2)];
17
18 return (row % 2 == 0) ? (x >> 4) : (x & 0x0F);
19 }
20
21 GOST_28147_89_Params::GOST_28147_89_Params(const std::string& n) : name(n)
22 {
23 // Encoded in the packed fromat from RFC 4357
24
25 // GostR3411_94_TestParamSet (OID 1.2.643.2.2.31.0)
26 static const byte GOST_R_3411_TEST_PARAMS[64] = {
27 0x4E, 0x57, 0x64, 0xD1, 0xAB, 0x8D, 0xCB, 0xBF, 0x94, 0x1A, 0x7A,
28 0x4D, 0x2C, 0xD1, 0x10, 0x10, 0xD6, 0xA0, 0x57, 0x35, 0x8D, 0x38,
29 0xF2, 0xF7, 0x0F, 0x49, 0xD1, 0x5A, 0xEA, 0x2F, 0x8D, 0x94, 0x62,
30 0xEE, 0x43, 0x09, 0xB3, 0xF4, 0xA6, 0xA2, 0x18, 0xC6, 0x98, 0xE3,
31 0xC1, 0x7C, 0xE5, 0x7E, 0x70, 0x6B, 0x09, 0x66, 0xF7, 0x02, 0x3C,
32 0x8B, 0x55, 0x95, 0xBF, 0x28, 0x39, 0xB3, 0x2E, 0xCC };
33
34 // GostR3411-94-CryptoProParamSet (OID 1.2.643.2.2.31.1)
35 static const byte GOST_R_3411_CRYPTOPRO_PARAMS[64] = {
36 0xA5, 0x74, 0x77, 0xD1, 0x4F, 0xFA, 0x66, 0xE3, 0x54, 0xC7, 0x42,
37 0x4A, 0x60, 0xEC, 0xB4, 0x19, 0x82, 0x90, 0x9D, 0x75, 0x1D, 0x4F,
38 0xC9, 0x0B, 0x3B, 0x12, 0x2F, 0x54, 0x79, 0x08, 0xA0, 0xAF, 0xD1,
39 0x3E, 0x1A, 0x38, 0xC7, 0xB1, 0x81, 0xC6, 0xE6, 0x56, 0x05, 0x87,
40 0x03, 0x25, 0xEB, 0xFE, 0x9C, 0x6D, 0xF8, 0x6D, 0x2E, 0xAB, 0xDE,
41 0x20, 0xBA, 0x89, 0x3C, 0x92, 0xF8, 0xD3, 0x53, 0xBC };
42
43 if(name == "R3411_94_TestParam")
44 sboxes = GOST_R_3411_TEST_PARAMS;
45 else if(name == "R3411_CryptoPro")
46 sboxes = GOST_R_3411_CRYPTOPRO_PARAMS;
47 else
48 throw Invalid_Argument("GOST_28147_89_Params: Unknown " + name);
49 }
50
51 /*
52 * GOST Constructor
53 */
54 GOST_28147_89::GOST_28147_89(const GOST_28147_89_Params& param) :
55 SBOX(1024), EK(8)
56 {
57 // Convert the parallel 4x4 sboxes into larger word-based sboxes
58 for(size_t i = 0; i != 4; ++i)
59 for(size_t j = 0; j != 256; ++j)
60 {
61 const u32bit T = (param.sbox_entry(2*i , j % 16)) |
62 (param.sbox_entry(2*i+1, j / 16) << 4);
63 SBOX[256*i+j] = rotate_left(T, (11+8*i) % 32);
64 }
65 }
66
67 std::string GOST_28147_89::name() const
68 {
69 /*
70 'Guess' the right name for the sbox on the basis of the values.
71 This would need to be updated if support for other sbox parameters
72 is added. Preferably, we would just store the string value in the
73 constructor, but can't break binary compat.
74 */
75 std::string sbox_name = "";
76 if(SBOX[0] == 0x00072000)
77 sbox_name = "R3411_94_TestParam";
78 else if(SBOX[0] == 0x0002D000)
79 sbox_name = "R3411_CryptoPro";
80 else
81 throw Internal_Error("GOST-28147 unrecognized sbox value");
82
83 return "GOST-28147-89(" + sbox_name + ")";
84 }
85
86 /*
87 * Two rounds of GOST
88 */
89 #define GOST_2ROUND(N1, N2, R1, R2) \
90 do { \
91 u32bit T0 = N1 + EK[R1]; \
92 N2 ^= SBOX[get_byte(3, T0)] | \
93 SBOX[get_byte(2, T0)+256] | \
94 SBOX[get_byte(1, T0)+512] | \
95 SBOX[get_byte(0, T0)+768]; \
96 \
97 u32bit T1 = N2 + EK[R2]; \
98 N1 ^= SBOX[get_byte(3, T1)] | \
99 SBOX[get_byte(2, T1)+256] | \
100 SBOX[get_byte(1, T1)+512] | \
101 SBOX[get_byte(0, T1)+768]; \
102 } while(0)
103
104 /*
105 * GOST Encryption
106 */
107 void GOST_28147_89::encrypt_n(const byte in[], byte out[], size_t blocks) const
108 {
109 for(size_t i = 0; i != blocks; ++i)
110 {
111 u32bit N1 = load_le<u32bit>(in, 0);
112 u32bit N2 = load_le<u32bit>(in, 1);
113
114 for(size_t j = 0; j != 3; ++j)
115 {
116 GOST_2ROUND(N1, N2, 0, 1);
117 GOST_2ROUND(N1, N2, 2, 3);
118 GOST_2ROUND(N1, N2, 4, 5);
119 GOST_2ROUND(N1, N2, 6, 7);
120 }
121
122 GOST_2ROUND(N1, N2, 7, 6);
123 GOST_2ROUND(N1, N2, 5, 4);
124 GOST_2ROUND(N1, N2, 3, 2);
125 GOST_2ROUND(N1, N2, 1, 0);
126
127 store_le(out, N2, N1);
128
129 in += BLOCK_SIZE;
130 out += BLOCK_SIZE;
131 }
132 }
133
134 /*
135 * GOST Decryption
136 */
137 void GOST_28147_89::decrypt_n(const byte in[], byte out[], size_t blocks) const
138 {
139 for(size_t i = 0; i != blocks; ++i)
140 {
141 u32bit N1 = load_le<u32bit>(in, 0);
142 u32bit N2 = load_le<u32bit>(in, 1);
143
144 GOST_2ROUND(N1, N2, 0, 1);
145 GOST_2ROUND(N1, N2, 2, 3);
146 GOST_2ROUND(N1, N2, 4, 5);
147 GOST_2ROUND(N1, N2, 6, 7);
148
149 for(size_t j = 0; j != 3; ++j)
150 {
151 GOST_2ROUND(N1, N2, 7, 6);
152 GOST_2ROUND(N1, N2, 5, 4);
153 GOST_2ROUND(N1, N2, 3, 2);
154 GOST_2ROUND(N1, N2, 1, 0);
155 }
156
157 store_le(out, N2, N1);
158 in += BLOCK_SIZE;
159 out += BLOCK_SIZE;
160 }
161 }
162
163 /*
164 * GOST Key Schedule
165 */
166 void GOST_28147_89::key_schedule(const byte key[], size_t)
167 {
168 for(size_t i = 0; i != 8; ++i)
169 EK[i] = load_le<u32bit>(key, i);
170 }
171
172 }
Botan::Block_Cipher_Fixed_Params< 8, 32 >::BLOCK_SIZE
Definition: block_cipher.h:107
Botan::GOST_28147_89_Params::GOST_28147_89_Params
GOST_28147_89_Params(const std::string &name="R3411_94_TestParam")
Definition: gost_28147.cpp:21
Botan::GOST_28147_89_Params
Definition: gost_28147.h:21
Botan::store_le
void store_le(u16bit in, byte out[2])
Definition: loadstor.h:427
Botan::Internal_Error
Definition: exceptn.h:45
Botan::rotate_left
T rotate_left(T input, size_t rot)
Definition: rotate.h:21
Botan::Invalid_Argument
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::GOST_28147_89::GOST_28147_89
GOST_28147_89(const GOST_28147_89_Params &params)
Definition: gost_28147.cpp:54
Botan::GOST_28147_89::decrypt_n
void decrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: gost_28147.cpp:137
Botan::GOST_28147_89::name
std::string name() const
Definition: gost_28147.cpp:67
Botan::load_le< u32bit >
u32bit load_le< u32bit >(const byte in[], size_t off)
Definition: loadstor.h:183
Botan
Definition: algo_base.h:14
Botan::GOST_28147_89::encrypt_n
void encrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: gost_28147.cpp:107
Botan::GOST_28147_89_Params::sbox_entry
byte sbox_entry(size_t row, size_t col) const
Definition: gost_28147.cpp:14
GOST_2ROUND
#define GOST_2ROUND(N1, N2, R1, R2)
Definition: gost_28147.cpp:89
Botan::u32bit
unsigned int u32bit
Definition: types.h:32