+ if (gost2015_acpkm_omac_init(NID_kuznyechik_mac, enc, key,
+ c->omac_ctx, cipher_key, c->kdf_seed) != 1) {
+ EVP_MD_CTX_free(c->omac_ctx);
+ c->omac_ctx = NULL;
+ return 0;
+ }
+
+ return gost_grasshopper_cipher_init(ctx, cipher_key, iv, enc);
+ }
+
+ return gost_grasshopper_cipher_init(ctx, key, iv, enc);
+}
+
+// TODO: const *in, const *c
+void gost_grasshopper_encrypt_wrap(unsigned char *in, unsigned char *out,
+ gost_grasshopper_cipher_ctx *c) {
+ grasshopper_encrypt_block(&c->encrypt_round_keys,
+ (grasshopper_w128_t *) in,
+ (grasshopper_w128_t *) out,
+ &c->buffer);
+}
+
+
+
+/* ----------------------------------------------------------------------------------------------- */
+/*! Функция реализует операцию умножения двух элементов конечного поля \f$ \mathbb F_{2^{128}}\f$,
+ порожденного неприводимым многочленом
+ \f$ f(x) = x^{128} + x^7 + x^2 + x + 1 \in \mathbb F_2[x]\f$. Для умножения используется
+ простейшая реализация, основанная на приведении по модулю после каждого шага алгоритма. */
+/* ----------------------------------------------------------------------------------------------- */
+static void gf128_mul_uint64 (uint64_t *result, uint64_t *arg1, uint64_t *arg2)
+{
+ int i = 0;
+ register uint64_t t, X0, X1;
+ uint64_t Z0 = 0, Z1 = 0;
+
+#ifdef L_ENDIAN
+ X0 = BSWAP64(*(arg1 + 1));
+ X1 = BSWAP64(*arg1);
+#else
+ X0 = *(arg1 + 1);
+ X1 = *arg1;
+#endif
+
+ //first 64 bits of arg1
+#ifdef L_ENDIAN
+ t = BSWAP64(*(arg2 + 1));
+#else
+ t = *(arg2 + 1);
+#endif
+
+ for (i = 0; i < 64; i++) {
+ if (t & 0x1) {
+ Z0 ^= X0;
+ Z1 ^= X1;
+ }
+ t >>= 1;
+ if (X1 & 0x8000000000000000) {
+ X1 <<= 1;
+ X1 ^= X0>>63;
+ X0 <<= 1;
+ X0 ^= 0x87;