Коммит f90bea17 создал по автору Моисеенко Андрей Алексеевич's avatar Моисеенко Андрей Алексеевич
Просмотр файлов

~

владелец cd08c00f
......@@ -753,6 +753,7 @@
<ClCompile Include="des\des_setkey.cpp" />
<ClCompile Include="exp5.cpp" />
<ClCompile Include="Gost_BS_MAA.cpp" />
<ClCompile Include="Kuznechik_MAA.cpp" />
<ClCompile Include="Longint2.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="ntlm.cpp" />
......@@ -808,6 +809,7 @@
<ClInclude Include="des\des_locl.h" />
<ClInclude Include="exp5.h" />
<ClInclude Include="Gost_BS_MAA.h" />
<ClInclude Include="Kuznechik_MAA.h" />
<ClInclude Include="Longint2.h" />
<ClInclude Include="ntlm.h" />
<ClInclude Include="ntlm_proxy_auth.h" />
......
......@@ -72,6 +72,9 @@
<ClCompile Include="util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Kuznechik_MAA.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="CryptLib.h">
......@@ -131,6 +134,9 @@
<ClInclude Include="util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Kuznechik_MAA.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
......
// CryptLib Project
/* CryptLib library for RusRoute firewall and other projects of
* Andrey A. Moiseenko / IE Moiseenko A.A. (Russia)
* e-mail: support@maasoftware.ru, maa2002@mail.ru
* web: http://maasoftware.ru, http://maasoftware.com, http://maasoft.ru, http://maasoft.org
* Author's full name: Andrey Alekseevitch Moiseenko
* (russian name: Моисеенко Андрей Алексеевич)
*/
// CryptLib/Kuzhechik_MAA.cpp
/* Copyright (C) 2002-2024 Andrey A. Moiseenko (support@maasoftware.ru)
* All rights reserved.
*
* This library contains the basic cryptography function,
* prime numbers checks and generator, random number generator,
* Mantgomery exponent, symmetric GOST and asymmetric RSA-like.
* This file is GOST chiper implementation given from
* the book Bruce Schneier "Applied Cryptography" with changes of
* Andrey A. Moiseenko (support@maasoftware.ru).
* This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Andrey A. Moiseenko, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Andrey A. Moiseenko should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Andrey A. Moiseenko (support@maasoftware.ru)
*
* THIS SOFTWARE IS PROVIDED BY ANDREY A. MOISEENKO ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include "stdafx.h"
//#include "perm.h"
#include "temp.h"
//#define KUZNECHIK_DEBUG
//#include <stdio.h>
// unsigned char, uint64_t
//#include <stdint.h>
// memcpy
//#include <string.h>
// https://rekovalev.site/kuznechik-crypto/
// git clone https://git.rekovalev.site/Crypto/C_Kuznechik_GOST_R_34.12-2015.git
//
// mod by MAA
//
// Таблица прямого нелинейного преобразования согластно ГОСТ 34.12-2015
const unsigned char CChipherKuznechik::Pi[256] =
{
0xFC, 0xEE, 0xDD, 0x11, 0xCF, 0x6E, 0x31, 0x16, 0xFB, 0xC4, 0xFA, 0xDA, 0x23, 0xC5, 0x04, 0x4D,
0xE9, 0x77, 0xF0, 0xDB, 0x93, 0x2E, 0x99, 0xBA, 0x17, 0x36, 0xF1, 0xBB, 0x14, 0xCD, 0x5F, 0xC1,
0xF9, 0x18, 0x65, 0x5A, 0xE2, 0x5C, 0xEF, 0x21, 0x81, 0x1C, 0x3C, 0x42, 0x8B, 0x01, 0x8E, 0x4F,
0x05, 0x84, 0x02, 0xAE, 0xE3, 0x6A, 0x8F, 0xA0, 0x06, 0x0B, 0xED, 0x98, 0x7F, 0xD4, 0xD3, 0x1F,
0xEB, 0x34, 0x2C, 0x51, 0xEA, 0xC8, 0x48, 0xAB, 0xF2, 0x2A, 0x68, 0xA2, 0xFD, 0x3A, 0xCE, 0xCC,
0xB5, 0x70, 0x0E, 0x56, 0x08, 0x0C, 0x76, 0x12, 0xBF, 0x72, 0x13, 0x47, 0x9C, 0xB7, 0x5D, 0x87,
0x15, 0xA1, 0x96, 0x29, 0x10, 0x7B, 0x9A, 0xC7, 0xF3, 0x91, 0x78, 0x6F, 0x9D, 0x9E, 0xB2, 0xB1,
0x32, 0x75, 0x19, 0x3D, 0xFF, 0x35, 0x8A, 0x7E, 0x6D, 0x54, 0xC6, 0x80, 0xC3, 0xBD, 0x0D, 0x57,
0xDF, 0xF5, 0x24, 0xA9, 0x3E, 0xA8, 0x43, 0xC9, 0xD7, 0x79, 0xD6, 0xF6, 0x7C, 0x22, 0xB9, 0x03,
0xE0, 0x0F, 0xEC, 0xDE, 0x7A, 0x94, 0xB0, 0xBC, 0xDC, 0xE8, 0x28, 0x50, 0x4E, 0x33, 0x0A, 0x4A,
0xA7, 0x97, 0x60, 0x73, 0x1E, 0x00, 0x62, 0x44, 0x1A, 0xB8, 0x38, 0x82, 0x64, 0x9F, 0x26, 0x41,
0xAD, 0x45, 0x46, 0x92, 0x27, 0x5E, 0x55, 0x2F, 0x8C, 0xA3, 0xA5, 0x7D, 0x69, 0xD5, 0x95, 0x3B,
0x07, 0x58, 0xB3, 0x40, 0x86, 0xAC, 0x1D, 0xF7, 0x30, 0x37, 0x6B, 0xE4, 0x88, 0xD9, 0xE7, 0x89,
0xE1, 0x1B, 0x83, 0x49, 0x4C, 0x3F, 0xF8, 0xFE, 0x8D, 0x53, 0xAA, 0x90, 0xCA, 0xD8, 0x85, 0x61,
0x20, 0x71, 0x67, 0xA4, 0x2D, 0x2B, 0x09, 0x5B, 0xCB, 0x9B, 0x25, 0xD0, 0xBE, 0xE5, 0x6C, 0x52,
0x59, 0xA6, 0x74, 0xD2, 0xE6, 0xF4, 0xB4, 0xC0, 0xD1, 0x66, 0xAF, 0xC2, 0x39, 0x4B, 0x63, 0xB6
};
// Таблица обратного нелинейного преобразования
const unsigned char CChipherKuznechik::Pi_reverse[256] =
{
0xA5, 0x2D, 0x32, 0x8F, 0x0E, 0x30, 0x38, 0xC0, 0x54, 0xE6, 0x9E, 0x39, 0x55, 0x7E, 0x52, 0x91,
0x64, 0x03, 0x57, 0x5A, 0x1C, 0x60, 0x07, 0x18, 0x21, 0x72, 0xA8, 0xD1, 0x29, 0xC6, 0xA4, 0x3F,
0xE0, 0x27, 0x8D, 0x0C, 0x82, 0xEA, 0xAE, 0xB4, 0x9A, 0x63, 0x49, 0xE5, 0x42, 0xE4, 0x15, 0xB7,
0xC8, 0x06, 0x70, 0x9D, 0x41, 0x75, 0x19, 0xC9, 0xAA, 0xFC, 0x4D, 0xBF, 0x2A, 0x73, 0x84, 0xD5,
0xC3, 0xAF, 0x2B, 0x86, 0xA7, 0xB1, 0xB2, 0x5B, 0x46, 0xD3, 0x9F, 0xFD, 0xD4, 0x0F, 0x9C, 0x2F,
0x9B, 0x43, 0xEF, 0xD9, 0x79, 0xB6, 0x53, 0x7F, 0xC1, 0xF0, 0x23, 0xE7, 0x25, 0x5E, 0xB5, 0x1E,
0xA2, 0xDF, 0xA6, 0xFE, 0xAC, 0x22, 0xF9, 0xE2, 0x4A, 0xBC, 0x35, 0xCA, 0xEE, 0x78, 0x05, 0x6B,
0x51, 0xE1, 0x59, 0xA3, 0xF2, 0x71, 0x56, 0x11, 0x6A, 0x89, 0x94, 0x65, 0x8C, 0xBB, 0x77, 0x3C,
0x7B, 0x28, 0xAB, 0xD2, 0x31, 0xDE, 0xC4, 0x5F, 0xCC, 0xCF, 0x76, 0x2C, 0xB8, 0xD8, 0x2E, 0x36,
0xDB, 0x69, 0xB3, 0x14, 0x95, 0xBE, 0x62, 0xA1, 0x3B, 0x16, 0x66, 0xE9, 0x5C, 0x6C, 0x6D, 0xAD,
0x37, 0x61, 0x4B, 0xB9, 0xE3, 0xBA, 0xF1, 0xA0, 0x85, 0x83, 0xDA, 0x47, 0xC5, 0xB0, 0x33, 0xFA,
0x96, 0x6F, 0x6E, 0xC2, 0xF6, 0x50, 0xFF, 0x5D, 0xA9, 0x8E, 0x17, 0x1B, 0x97, 0x7D, 0xEC, 0x58,
0xF7, 0x1F, 0xFB, 0x7C, 0x09, 0x0D, 0x7A, 0x67, 0x45, 0x87, 0xDC, 0xE8, 0x4F, 0x1D, 0x4E, 0x04,
0xEB, 0xF8, 0xF3, 0x3E, 0x3D, 0xBD, 0x8A, 0x88, 0xDD, 0xCD, 0x0B, 0x13, 0x98, 0x02, 0x93, 0x80,
0x90, 0xD0, 0x24, 0x34, 0xCB, 0xED, 0xF4, 0xCE, 0x99, 0x10, 0x44, 0x40, 0x92, 0x3A, 0x01, 0x26,
0x12, 0x1A, 0x48, 0x68, 0xF5, 0x81, 0x8B, 0xC7, 0xD6, 0x20, 0x0A, 0x08, 0x00, 0x4C, 0xD7, 0x74
};
// Вектор линейного преобразования
const unsigned char CChipherKuznechik::linear_vector[16] =
{
0x94, 0x20, 0x85, 0x10, 0xC2, 0xC0, 0x01, 0xFB,
0x01, 0xC0, 0xC2, 0x10, 0x85, 0x20, 0x94, 0x01
};
const unsigned char CChipherKuznechik::StaticKey[32] =
{
0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,
0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef
};
CChipherKuznechik::CChipherKuznechik() noexcept
{
memset(round_keys, 0, sizeof(round_keys));
};
CChipherKuznechik::~CChipherKuznechik()
{
memset(round_keys, 0, sizeof(round_keys));
};
// Функция S
void CChipherKuznechik::S(_uqword* in_out) noexcept
{
// Переход к представлению в байтах
unsigned char *byte = (unsigned char*)in_out;
for (int i = 0; i < KUZNECHIK_BLOCK_SIZE; i++)
{
byte[i] = Pi[byte[i]];
}
}
// Обратная функция S
void CChipherKuznechik::S_reverse(_uqword* in_out) noexcept
{
// Переход к представлению в байтах
unsigned char *byte = (unsigned char*)in_out;
for (int i = 0; i < KUZNECHIK_BLOCK_SIZE; i++)
{
byte[i] = Pi_reverse[byte[i]];
}
}
// Функция умножения в поле Галуа
unsigned char CChipherKuznechik::GF_mult(unsigned char a, unsigned char b) noexcept
{
unsigned char c = 0;
while (b)
{
if ((b & 1))
{
c ^= a;
}
a = (a & 0x80) ? (a << 1) ^ 0xC3 : (a << 1);
b >>= 1;
}
return c;
}
// Функция R
void CChipherKuznechik::R(unsigned char *in_out) noexcept
{
// Аккумулятор
unsigned char acc = in_out[15];
// Переход к представлению в байтах
unsigned char *byte = (unsigned char*)in_out;
for (int i = 14; i >= 0; i--)
{
byte[i + 1] = byte[i];
acc ^= GF_mult(byte[i], linear_vector[i]);
}
byte[0] = acc;
}
// Обратная функция R
void CChipherKuznechik::R_reverse(unsigned char *in_out) noexcept
{
// Аккумулятор
unsigned char acc = in_out[0];
// Переход к представлению в байтах
unsigned char *byte = (unsigned char*)in_out;
for (int i = 0; i < 15; i++)
{
byte[i] = byte[i + 1];
acc ^= GF_mult(byte[i], linear_vector[i]);
}
byte[15] = acc;
}
// Функция L
void CChipherKuznechik::L(unsigned char* in_out) noexcept
{
for (int i = 0; i < KUZNECHIK_BLOCK_SIZE; i++)
{
R(in_out);
}
}
// Обратная функция L
void CChipherKuznechik::L_reverse(unsigned char *in_out) noexcept
{
for (int i = 0; i < 16; i++)
{
R_reverse(in_out);
}
}
// Генерация итерационных ключей
void CChipherKuznechik::gen_round_keys(const unsigned char* key, chunk* round_keys) noexcept
{
// Счетчик
int i;
// Константы
unsigned char cs[32][KUZNECHIK_BLOCK_SIZE] = {};
// Генерация констант с помощью L-преобразования номера итерации
for (i = 0; i < 32; i++)
{
cs[i][15] = i + 1;
L(cs[i]);
}
// Итерационные ключи (четный и нечетный)
chunk ks[2] = {};
// Разместим ключ шифрования
// результат = итерационный ключ = (преобразование к указателю на чанк)[номер чанка][часть чанка]
round_keys[0][0] = ks[0][0] = ((chunk*)key)[0][0];
round_keys[0][1] = ks[0][1] = ((chunk*)key)[0][1];
round_keys[1][0] = ks[1][0] = ((chunk*)key)[1][0];
round_keys[1][1] = ks[1][1] = ((chunk*)key)[1][1];
// Генерация оставшихся ключей с использованием констант
for (i = 1; i <= 32; i++)
{
// Новый ключ
chunk new_key = {0};
// Преобразование X
X(ks[0], (const _uqword*)cs[i - 1], new_key);
// Преобразование S
S(new_key);
// Преобразование L
L((unsigned char*)new_key);
// Преобразование X
X(new_key, ks[1], new_key);
// Сдвигаем ключи
ks[1][0] = ks[0][0];
ks[1][1] = ks[0][1];
// Записываем новый ключ
ks[0][0] = new_key[0];
ks[0][1] = new_key[1];
// Каждую 8 итерацию сети Фейстеля за исключением нулевой запишем ключи
if ((i > 0) && (i % 8 == 0))
{
round_keys[(i >> 2)][0] = ks[0][0];
round_keys[(i >> 2)][1] = ks[0][1];
round_keys[(i >> 2) + 1][0] = ks[1][0];
round_keys[(i >> 2) + 1][1] = ks[1][1];
}
}
}
// Функция шифрования
// Поддерживает запись результата в исходный массив
void CChipherKuznechik::kuznechik_encrypt128(const chunk* round_keys, _uqword* p) noexcept
{
// В течении 10 итераций
for (int i = 0; i < 10; i++)
{
// Преобразование X
X(p, round_keys[i], p);
// Для всех итераций кроме последней
if (i < 9)
{
// Преобразование S
S(p);
// Преобразование L
L((unsigned char*)p);
}
}
}
void CChipherKuznechik::kuznechik_decrypt128(const chunk* round_keys, _uqword* p) noexcept
{
// Преобразование X
X(p, round_keys[9], p);
for (int i = 8; i >= 0; i--)
{
// Преобразование L
L_reverse((unsigned char*)p);
// Преобразование S
S_reverse(p);
// Преобразование X
X(p, round_keys[i], p);
}
}
// Функция шифрования
// Поддерживает запись результата в исходный массив
void CChipherKuznechik::kuznechik_encrypt(const chunk* round_keys, const _uqword* in, _uqword* out) noexcept
{
// Буфер
chunk p;
// Создадим копию входных данных
p[0] = in[0]; //memcpy(p, in, sizeof(chunk));
p[1] = in[1];
kuznechik_encrypt128(round_keys, p);
// Копируем полученный результат
out[0] = p[0]; //memcpy(out, p, sizeof(chunk));
out[1] = p[1];
}
void CChipherKuznechik::kuznechik_decrypt(const chunk* round_keys, const _uqword* in, _uqword* out) noexcept
{
// Буфер
chunk p;
// Создадим копию входных данных
p[0] = in[0]; //memcpy(p, in, sizeof(chunk));
p[1] = in[1];
kuznechik_decrypt128(round_keys, p);
// Копируем полученный результат
out[0] = p[0]; //memcpy(out, p, sizeof(chunk));
out[1] = p[1];
}
// Печать чанка
void CChipherKuznechik::print_chunk(const void* p) noexcept
{
for (int i = 0; i < (int)sizeof(chunk); i++)
{
printf("0x%02X ", ((unsigned char*)p)[i]);
}
printf("\n");
}
void CChipherKuznechik::SetKey(const unsigned char* key) noexcept
{
// Генерация итерационных ключей
gen_round_keys(key ? key : StaticKey, round_keys);
#ifdef KUZNECHIK_DEBUG
// Вывод итерационных ключей
printf("Итерацционные ключи:\n");
for (int i = 0; i < 10; i++)
print_chunk(round_keys[i]);
#endif
}
void CChipherKuznechik::Encrypt(const unsigned char* pIn, size_t Size, unsigned char* pOut) noexcept
{
while (Size >= KUZNECHIK_BLOCK_SIZE)
{
// Шифрование
kuznechik_encrypt(round_keys, (const _uqword*)pIn, (_uqword*)pOut);
#ifdef KUZNECHIK_DEBUG
// Вывод зашифрованных данных
printf("Зашифрованные данные:\n");
print_chunk(pOut);
#endif
pIn += KUZNECHIK_BLOCK_SIZE;
pOut += KUZNECHIK_BLOCK_SIZE;
Size -= KUZNECHIK_BLOCK_SIZE;
}
#if 0
if (Size)
{
//Size = KUZNECHIK_BLOCK_SIZE;
uint64_t t[2] = { 0,0 }, t2[2] = { 0,0 };
memcpy(t, pIn, Size);
// Шифрование
kuznechik_encrypt(round_keys, t, t2);
#ifdef KUZNECHIK_DEBUG
// Вывод зашифрованных данных
printf("Зашифрованные данные:\n");
print_chunk(t2);
#endif
memcpy(pOut, t2, Size);
}
#endif
}
void CChipherKuznechik::Decrypt(const unsigned char* pIn, size_t Size, unsigned char* pOut) noexcept
{
while (Size >= KUZNECHIK_BLOCK_SIZE)
{
// Расшифровка
kuznechik_decrypt(round_keys, (const _uqword*)pIn, (_uqword*)pOut);
#ifdef KUZNECHIK_DEBUG
// Вывод зашифрованных данных
printf("Расшифрованные данные:\n");
print_chunk(pOut);
#endif
pIn += KUZNECHIK_BLOCK_SIZE;
pOut += KUZNECHIK_BLOCK_SIZE;
Size -= KUZNECHIK_BLOCK_SIZE;
}
#if 0
if (Size)
{
//Size = KUZNECHIK_BLOCK_SIZE;
uint64_t t[2] = { 0,0 }, t2[2] = { 0,0 };
memcpy(t, pIn, Size);
// Шифрование
kuznechik_decrypt(round_keys, t, t2);
#ifdef KUZNECHIK_DEBUG
// Вывод зашифрованных данных
printf("Расшифрованные данные:\n");
print_chunk(t2);
#endif
memcpy(pOut, t2, Size);
}
#endif
}
int main_kuznechik(int argc, char *argv[])
{
// Ключ (256 бит = 32 байт)
const unsigned char key[32] =
{
0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,
0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef
};
// Открытые данные
const unsigned char data[KUZNECHIK_BLOCK_SIZE] =
{
0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,
0xff,0xee,0xdd,0xcc,0xbb,0xaa,0x99,0x88
};
const unsigned char edata[KUZNECHIK_BLOCK_SIZE] =
{
0x7F,0x67,0x9D,0x90,0xBE,0xBC,0x24,0x30,
0x5A,0x46,0x8D,0x42,0xB9,0xD4,0xED,0xCD
};
// Вывод открытых данных
printf("Ключ:\n");
CChipherKuznechik::print_chunk(&key[0]);
CChipherKuznechik::print_chunk(&key[16]);
// Вывод открытых данных
printf("Открытые данные:\n");
CChipherKuznechik::print_chunk(data);
CChipherKuznechik k;
k.SetKey(key);
/*
Итерационные ключи:
0x88 0x99 0xAA 0xBB 0xCC 0xDD 0xEE 0xFF 0x00 0x11 0x22 0x33 0x44 0x55 0x66 0x77
0xFE 0xDC 0xBA 0x98 0x76 0x54 0x32 0x10 0x01 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
0xDB 0x31 0x48 0x53 0x15 0x69 0x43 0x43 0x22 0x8D 0x6A 0xEF 0x8C 0xC7 0x8C 0x44
0x3D 0x45 0x53 0xD8 0xE9 0xCF 0xEC 0x68 0x15 0xEB 0xAD 0xC4 0x0A 0x9F 0xFD 0x04
0x57 0x64 0x64 0x68 0xC4 0x4A 0x5E 0x28 0xD3 0xE5 0x92 0x46 0xF4 0x29 0xF1 0xAC
0xBD 0x07 0x94 0x35 0x16 0x5C 0x64 0x32 0xB5 0x32 0xE8 0x28 0x34 0xDA 0x58 0x1B
0x51 0xE6 0x40 0x75 0x7E 0x87 0x45 0xDE 0x70 0x57 0x27 0x26 0x5A 0x00 0x98 0xB1
0x5A 0x79 0x25 0x01 0x7B 0x9F 0xDD 0x3E 0xD7 0x2A 0x91 0xA2 0x22 0x86 0xF9 0x84
0xBB 0x44 0xE2 0x53 0x78 0xC7 0x31 0x23 0xA5 0xF3 0x2F 0x73 0xCD 0xB6 0xE5 0x17
0x72 0xE9 0xDD 0x74 0x16 0xBC 0xF4 0x5B 0x75 0x5D 0xBA 0xA8 0x8E 0x4A 0x40 0x43
*/
// Зашифрованные данные
CChipherKuznechik::chunk encrypted;
k.Encrypt(data, sizeof(data), (unsigned char*)encrypted);
printf("Зашифрованные данные:\n");
CChipherKuznechik::print_chunk(encrypted);
printf("%s\n", !memcmp(encrypted, edata, sizeof(edata)) ? "== (ok)" : "!= (fail)");
// Результат расшифровки
CChipherKuznechik::chunk decrypted;
k.Decrypt((const unsigned char*)encrypted, sizeof(data), (unsigned char*)decrypted);
printf("Расшифрованные данные:\n");
CChipherKuznechik::print_chunk(decrypted);
printf("%s\n", !memcmp(decrypted, data, sizeof(data)) ? "== (ok)" : "!= (fail)");
return 0;
}
// CryptLib Project
/* CryptLib library for RusRoute firewall and other projects of
* Andrey A. Moiseenko / IE Moiseenko A.A. (Russia)
* e-mail: support@maasoftware.ru, maa2002@mail.ru
* web: http://maasoftware.ru, http://maasoftware.com, http://maasoft.ru, http://maasoft.org
* Author's full name: Andrey Alekseevitch Moiseenko
* (russian name: Моисеенко Андрей Алексеевич)
*/
// CryptLib/Kuzhechik_MAA.h
/* Copyright (C) 2002-2024 Andrey A. Moiseenko (support@maasoftware.ru)
* All rights reserved.
*
* This library contains the basic cryptography function,
* prime numbers checks and generator, random number generator,
* Mantgomery exponent, symmetric GOST and asymmetric RSA-like.
* This file is GOST chiper implementation given from
* the book Bruce Schneier "Applied Cryptography" with changes of
* Andrey A. Moiseenko (support@maasoftware.ru).
* This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Andrey A. Moiseenko, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Andrey A. Moiseenko should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Andrey A. Moiseenko (support@maasoftware.ru)
*
* THIS SOFTWARE IS PROVIDED BY ANDREY A. MOISEENKO ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include "stdafx.h"
//#include "perm.h"
#include "temp.h"
//#include <stdio.h>
// uint8_t, uint64_t
//#include <stdint.h>
// memcpy
//#include <string.h>
// https://rekovalev.site/kuznechik-crypto/
// git clone https://git.rekovalev.site/Crypto/C_Kuznechik_GOST_R_34.12-2015.git
//
// mod by MAA
//
// Длинна блока в байтах(16 байт = 128 бит)
#define KUZNECHIK_BLOCK_SIZE 16
class CChipherKuznechik
{
public:
// Один блок (чанк) задается как массив двух беззнаковых целых по 64 бита
typedef _uqword chunk[2];
protected:
// Итерационные ключи
chunk round_keys[10];
// Таблица прямого нелинейного преобразования согластно ГОСТ 34.12-2015
static const unsigned char Pi[256], Pi_reverse[256];
static const unsigned char linear_vector[16];
static const unsigned char StaticKey[32];
// Функция X
static constexpr void X(const _uqword *a, const _uqword* b, _uqword* c) noexcept
{
c[0] = a[0] ^ b[0];
c[1] = a[1] ^ b[1];
}
static void S(_uqword* in_out) noexcept;
static void S_reverse(_uqword* in_out) noexcept;
static unsigned char GF_mult(unsigned char a, unsigned char b) noexcept;
static void R(unsigned char* in_out) noexcept;
static void R_reverse(unsigned char* in_out) noexcept;
static void L(unsigned char* in_out) noexcept;
static void L_reverse(unsigned char* in_out) noexcept;
static void gen_round_keys(const unsigned char* key, chunk* round_keys) noexcept;
static void kuznechik_encrypt(const chunk* round_keys, const _uqword* in, _uqword* out) noexcept;
static void kuznechik_decrypt(const chunk* round_keys, const _uqword* in, _uqword* out) noexcept;
static void kuznechik_encrypt128(const chunk* round_keys, _uqword* p) noexcept;
static void kuznechik_decrypt128(const chunk* round_keys, _uqword* p) noexcept;
public:
static void print_chunk(const void* p) noexcept;
CChipherKuznechik() noexcept;
~CChipherKuznechik();
void SetKey(const unsigned char* key) noexcept;
void Encrypt(const unsigned char* pIn, size_t Size, unsigned char* pOut) noexcept;
void Decrypt(const unsigned char* pIn, size_t Size, unsigned char* pOut) noexcept;
};
......@@ -7,6 +7,7 @@ HEADERS =
SOURCES = stdafx.cpp \
exp5.cpp \
Gost_BS_MAA.cpp \
Kuznechik_MAA.cpp \
main.cpp \
longint2.cpp \
RSA.cpp \
......@@ -24,6 +25,7 @@ SOURCES = stdafx.cpp \
OBJECTS = stdafx.o \
exp5.o \
Gost_BS_MAA.o \
Kuznechik_MAA.o \
main.o \
longint2.o \
RSA.o \
......
......@@ -67,6 +67,7 @@
#endif
#include "Gost_BS_MAA.h"
#include "Kuznechik_MAA.h"
#include "longint2.h"
#include "RSA.h"
//#include "exp3.h"
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать