3 * This file is distributed under the same license as OpenSSL
6 #if defined(__cplusplus)
10 #include "gost_grasshopper_core.h"
11 #include "gost_grasshopper_math.h"
12 #include "gost_grasshopper_precompiled.h"
13 #include "gost_grasshopper_defines.h"
15 static GRASSHOPPER_INLINE void grasshopper_l(grasshopper_w128_t* w) {
20 for (j = 0; j < sizeof(grasshopper_lvec) / sizeof(grasshopper_lvec[0]); j++) {
23 // An LFSR with 16 elements from GF(2^8)
24 x = w->b[15]; // since lvec[15] = 1
26 for (i = 14; i >= 0; i--) {
27 w->b[i + 1] = w->b[i];
28 x ^= grasshopper_galois_mul(w->b[i], grasshopper_lvec[i]);
34 static GRASSHOPPER_INLINE void grasshopper_l_inv(grasshopper_w128_t* w) {
39 for (j = 0; j < sizeof(grasshopper_lvec) / sizeof(grasshopper_lvec[0]); j++) {
41 for (i = 0; i < 15; i++) {
42 w->b[i] = w->b[i + 1];
43 x ^= grasshopper_galois_mul(w->b[i], grasshopper_lvec[i]);
51 void grasshopper_set_encrypt_key(grasshopper_round_keys_t* subkeys, const grasshopper_key_t* key) {
52 grasshopper_w128_t c, x, y, z;
55 for (i = 0; i < 16; i++) {
56 // this will be have to changed for little-endian systems
58 y.b[i] = key->k.b[i + 16];
61 grasshopper_copy128(&subkeys->k[0], &x);
62 grasshopper_copy128(&subkeys->k[1], &y);
64 for (i = 1; i <= 32; i++) {
67 grasshopper_zero128(&c);
68 c.b[15] = (uint8_t) i; // load round in lsb
71 grasshopper_plus128(&z, &x, &c);
72 grasshopper_convert128(&z, grasshopper_pi);
74 grasshopper_append128(&z, &y);
76 grasshopper_copy128(&y, &x);
77 grasshopper_copy128(&x, &z);
81 grasshopper_copy128(&subkeys->k[k], &x);
82 grasshopper_copy128(&subkeys->k[k + 1], &y);
87 grasshopper_zero128(&c);
88 grasshopper_zero128(&x);
89 grasshopper_zero128(&y);
90 grasshopper_zero128(&z);
93 void grasshopper_set_decrypt_key(grasshopper_round_keys_t* subkeys, const grasshopper_key_t* key) {
95 grasshopper_set_encrypt_key(subkeys, key);
97 for (i = 1; i < 10; i++) {
98 grasshopper_l_inv(&subkeys->k[i]);
102 void grasshopper_encrypt_block(grasshopper_round_keys_t* subkeys, grasshopper_w128_t* source,
103 grasshopper_w128_t* target, grasshopper_w128_t* buffer) {
105 grasshopper_copy128(target, source);
107 for (i = 0; i < 9; i++) {
108 grasshopper_append128(target, &subkeys->k[i]);
109 grasshopper_append128multi(buffer, target, grasshopper_pil_enc128);
112 grasshopper_append128(target, &subkeys->k[9]);
115 void grasshopper_decrypt_block(grasshopper_round_keys_t* subkeys, grasshopper_w128_t* source,
116 grasshopper_w128_t* target, grasshopper_w128_t* buffer) {
118 grasshopper_copy128(target, source);
120 grasshopper_append128multi(buffer, target, grasshopper_l_dec128);
122 for (i = 9; i > 1; i--) {
123 grasshopper_append128(target, &subkeys->k[i]);
124 grasshopper_append128multi(buffer, target, grasshopper_pil_dec128);
127 grasshopper_append128(target, &subkeys->k[1]);
128 grasshopper_convert128(target, grasshopper_pi_inv);
129 grasshopper_append128(target, &subkeys->k[0]);
132 #if defined(__cplusplus)