-
Notifications
You must be signed in to change notification settings - Fork 170
/
gost_grasshopper_core.c
134 lines (106 loc) · 3.64 KB
/
gost_grasshopper_core.c
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
* Maxim Tishkov 2016
* This file is distributed under the same license as OpenSSL
*/
#if defined(__cplusplus)
extern "C" {
#endif
#include "gost_grasshopper_core.h"
#include "gost_grasshopper_math.h"
#include "gost_grasshopper_precompiled.h"
#include "gost_grasshopper_defines.h"
static GRASSHOPPER_INLINE void grasshopper_l(grasshopper_w128_t* w) {
unsigned int j;
int i;
// 16 rounds
for (j = 0; j < sizeof(grasshopper_lvec) / sizeof(grasshopper_lvec[0]); j++) {
uint8_t x;
// An LFSR with 16 elements from GF(2^8)
x = w->b[15]; // since lvec[15] = 1
for (i = 14; i >= 0; i--) {
w->b[i + 1] = w->b[i];
x ^= grasshopper_galois_mul(w->b[i], grasshopper_lvec[i]);
}
w->b[0] = x;
}
}
static GRASSHOPPER_INLINE void grasshopper_l_inv(grasshopper_w128_t* w) {
unsigned int j;
int i;
// 16 rounds
for (j = 0; j < sizeof(grasshopper_lvec) / sizeof(grasshopper_lvec[0]); j++) {
uint8_t x = w->b[0];
for (i = 0; i < 15; i++) {
w->b[i] = w->b[i + 1];
x ^= grasshopper_galois_mul(w->b[i], grasshopper_lvec[i]);
}
w->b[15] = x;
}
}
// key setup
void grasshopper_set_encrypt_key(grasshopper_round_keys_t* subkeys, const grasshopper_key_t* key) {
grasshopper_w128_t c, x, y, z;
int i;
for (i = 0; i < 16; i++) {
// this will be have to changed for little-endian systems
x.b[i] = key->k.b[i];
y.b[i] = key->k.b[i + 16];
}
grasshopper_copy128(&subkeys->k[0], &x);
grasshopper_copy128(&subkeys->k[1], &y);
for (i = 1; i <= 32; i++) {
// C Value
grasshopper_zero128(&c);
c.b[15] = (uint8_t) i; // load round in lsb
grasshopper_l(&c);
grasshopper_plus128(&z, &x, &c);
grasshopper_convert128(&z, grasshopper_pi);
grasshopper_l(&z);
grasshopper_append128(&z, &y);
grasshopper_copy128(&y, &x);
grasshopper_copy128(&x, &z);
if ((i & 7) == 0) {
int k = i >> 2;
grasshopper_copy128(&subkeys->k[k], &x);
grasshopper_copy128(&subkeys->k[k + 1], &y);
}
}
// security++
grasshopper_zero128(&c);
grasshopper_zero128(&x);
grasshopper_zero128(&y);
grasshopper_zero128(&z);
}
void grasshopper_set_decrypt_key(grasshopper_round_keys_t* subkeys, const grasshopper_key_t* key) {
int i;
grasshopper_set_encrypt_key(subkeys, key);
for (i = 1; i < 10; i++) {
grasshopper_l_inv(&subkeys->k[i]);
}
}
void grasshopper_encrypt_block(grasshopper_round_keys_t* subkeys, grasshopper_w128_t* source,
grasshopper_w128_t* target, grasshopper_w128_t* buffer) {
int i;
grasshopper_copy128(target, source);
for (i = 0; i < 9; i++) {
grasshopper_append128(target, &subkeys->k[i]);
grasshopper_append128multi(buffer, target, grasshopper_pil_enc128);
}
grasshopper_append128(target, &subkeys->k[9]);
}
void grasshopper_decrypt_block(grasshopper_round_keys_t* subkeys, grasshopper_w128_t* source,
grasshopper_w128_t* target, grasshopper_w128_t* buffer) {
int i;
grasshopper_copy128(target, source);
grasshopper_append128multi(buffer, target, grasshopper_l_dec128);
for (i = 9; i > 1; i--) {
grasshopper_append128(target, &subkeys->k[i]);
grasshopper_append128multi(buffer, target, grasshopper_pil_dec128);
}
grasshopper_append128(target, &subkeys->k[1]);
grasshopper_convert128(target, grasshopper_pi_inv);
grasshopper_append128(target, &subkeys->k[0]);
}
#if defined(__cplusplus)
}
#endif