]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_grasshopper_core.c
Add Grasshopper, CMake
[openssl-gost/engine.git] / gost_grasshopper_core.c
1 /*
2  * Maxim Tishkov 2016
3  * This file is distributed under the same license as OpenSSL
4  */
5
6 #if defined(__cplusplus)
7 extern "C" {
8 #endif
9
10 #include "gost_grasshopper_core.h"
11 #include "gost_grasshopper_math.h"
12 #include "gost_grasshopper_precompiled.h"
13 #include "gost_grasshopper_defines.h"
14
15 static GRASSHOPPER_INLINE void grasshopper_l(grasshopper_w128_t* w) {
16     uint8_t x;
17
18     // 16 rounds
19     for (unsigned int j = 0; j < sizeof(grasshopper_lvec) / sizeof(grasshopper_lvec[0]); j++) {
20
21         // An LFSR with 16 elements from GF(2^8)
22         x = w->b[15];    // since lvec[15] = 1
23
24         for (int i = 14; i >= 0; i--) {
25             w->b[i + 1] = w->b[i];
26             x ^= grasshopper_galois_mul(w->b[i], grasshopper_lvec[i]);
27         }
28         w->b[0] = x;
29     }
30 }
31
32 static GRASSHOPPER_INLINE void grasshopper_l_inv(grasshopper_w128_t* w) {
33     uint8_t x;
34
35     // 16 rounds
36     for (unsigned int j = 0; j < sizeof(grasshopper_lvec) / sizeof(grasshopper_lvec[0]); j++) {
37
38         x = w->b[0];
39         for (int i = 0; i < 15; i++) {
40             w->b[i] = w->b[i + 1];
41             x ^= grasshopper_galois_mul(w->b[i], grasshopper_lvec[i]);
42         }
43         w->b[15] = x;
44     }
45 }
46
47 // key setup
48
49 void grasshopper_set_encrypt_key(grasshopper_round_keys_t* subkeys, const grasshopper_key_t* key) {
50     grasshopper_w128_t c, x, y, z;
51
52     for (int i = 0; i < 16; i++) {
53         // this will be have to changed for little-endian systems
54         x.b[i] = key->k.b[i];
55         y.b[i] = key->k.b[i + 16];
56     }
57
58     grasshopper_copy128(&subkeys->k[0], &x);
59     grasshopper_copy128(&subkeys->k[1], &y);
60
61     for (int i = 1; i <= 32; i++) {
62
63         // C Value
64         grasshopper_zero128(&c);
65         c.b[15] = (uint8_t) i;        // load round in lsb
66         grasshopper_l(&c);
67
68         grasshopper_plus128(&z, &x, &c);
69         grasshopper_convert128(&z, grasshopper_pi);
70         grasshopper_l(&z);
71         grasshopper_append128(&z, &y);
72
73         grasshopper_copy128(&y, &x);
74         grasshopper_copy128(&x, &z);
75
76         if ((i & 7) == 0) {
77             int k = i >> 2;
78             grasshopper_copy128(&subkeys->k[k], &x);
79             grasshopper_copy128(&subkeys->k[k + 1], &y);
80         }
81     }
82
83     // security++
84     grasshopper_zero128(&c);
85     grasshopper_zero128(&x);
86     grasshopper_zero128(&y);
87     grasshopper_zero128(&z);
88 }
89
90 void grasshopper_set_decrypt_key(grasshopper_round_keys_t* subkeys, const grasshopper_key_t* key) {
91     grasshopper_set_encrypt_key(subkeys, key);
92
93     for (int i = 1; i < 10; i++) {
94         grasshopper_l_inv(&subkeys->k[i]);
95     }
96 }
97
98 void grasshopper_encrypt_block(grasshopper_round_keys_t* subkeys, grasshopper_w128_t* source,
99                                grasshopper_w128_t* target, grasshopper_w128_t* buffer) {
100     grasshopper_copy128(target, source);
101
102     for (int i = 0; i < 9; i++) {
103         grasshopper_append128(target, &subkeys->k[i]);
104         grasshopper_append128multi(buffer, target, grasshopper_pil_enc128);
105     }
106
107     grasshopper_append128(target, &subkeys->k[9]);
108 }
109
110 void grasshopper_encrypt_block2(grasshopper_round_keys_t* subkeys, grasshopper_w128_t* source,
111                                 grasshopper_w128_t* target) {
112     grasshopper_w128_t buffer;
113     grasshopper_encrypt_block(subkeys, source, target, &buffer);
114     grasshopper_zero128(&buffer);
115 }
116
117 void grasshopper_decrypt_block(grasshopper_round_keys_t* subkeys, grasshopper_w128_t* source,
118                                grasshopper_w128_t* target, grasshopper_w128_t* buffer) {
119     grasshopper_copy128(target, source);
120
121     grasshopper_append128multi(buffer, target, grasshopper_l_dec128);
122
123     for (int i = 9; i > 1; i--) {
124         grasshopper_append128(target, &subkeys->k[i]);
125         grasshopper_append128multi(buffer, target, grasshopper_pil_dec128);
126     }
127
128     grasshopper_append128(target, &subkeys->k[1]);
129     grasshopper_convert128(target, grasshopper_pi_inv);
130     grasshopper_append128(target, &subkeys->k[0]);
131 }
132
133 void grasshopper_decrypt_block2(grasshopper_round_keys_t* subkeys, grasshopper_w128_t* source,
134                                 grasshopper_w128_t* target) {
135     grasshopper_w128_t buffer;
136     grasshopper_decrypt_block(subkeys, source, target, &buffer);
137     grasshopper_zero128(&buffer);
138 }
139
140 #if defined(__cplusplus)
141 }
142 #endif