Лабораторная работа: блочный шифр Camellia. Лабораторная 2 Филатов Camellia. Лабораторная работа 2 по методам и средствам защиты Реализация симметричной криптосистемы
Скачать 212.5 Kb.
|
|
| Студент | | | | Филатов А.А. | | ||||||||
| | | подпись, дата | | фамилия, инициалы | | ||||||||
| Группа | | АС-09-2 | | | | | |||||||
| | | | | | | ||||||||
| Принял | | | | | | ||||||||
| | | | | Батищев Р.В. | | ||||||||
| ученая степень, звание | | подпись, дата | | фамилия, инициалы | |
Липецк 2012
1. Задание
Изучить принципы работы и классификацию симметричных криптосистем, особенности современных алгоритмов, получить практические навыки программирования симметричных криптографических алгоритмов.
Таблица 1. Вариант алгоритма
№ | Алгоритм |
16. | Camellia |
Краткие теоретические сведения
Camellia — алгоритм симметричного блочного шифрования (размер блока 128 бит, ключ 128, 192, 256 бит), один из финалистов европейского конкурса NESSIE (наряду с AES и Shacal-2), разработка японских компаний Nippon Telegraph and Telephone Corporation и Mitsubishi Electric Corporation (представлен 10 марта 2000 г.). Сертифицирован японской организацией CRYPTREC как рекомендованный для промышленного и государственного использования алгоритм.
Camellia является дальнейшим развитием алгоритма шифрования E2, одного из алгоритмов, представленных на конкурсе AES и с использованием элементов алгоритма MISTY1.
Структура алгоритма основана на классической цепи Фейстеля с предварительным и финальным забеливанием. Цикловая функция использует нелинейное преобразование (S-блоки), блок линейного рассеивания каждые 16 циклов (побайтовая операция XOR) и байтовую перестановку.
В зависимости от длины ключа имеет 18 циклов (128 разрядный ключ), либо 24 цикла (192 и 256 разрядный ключ).
Поддержка алгоритма Camellia введена в 2008 году в браузере Mozilla Firefox 3. Алгоритм патентован, однако распространяется под рядом свободных лицензий, в частности, является частью проекта OpenSSL.
3. Алгоритм
3.1. Генерация ключа:
3.1.1. Ключ (К) разбивается на 2 128-битные части KL и KR.
-
Ключ
KL
KR
128
K
0
192
K >> 64
((K & MASK64) << 64) | ((K & MASK64))
256
K >> 128
K & MASK128
3.1.2. Вычисляем 128-битные числа KA и KB (см. схему). Переменные D1 и D2 64-битные.
D1 = (KL ^ KR) >> 64;
D2 = (KL ^ KR) & MASK64;
D2 = D2 ^ F(D1, C1);
D1 = D1 ^ F(D2, C2);
D1 = D1 ^ (KL >> 64);
D2 = D2 ^ (KL & MASK64);
D2 = D2 ^ F(D1, C3);
D1 = D1 ^ F(D2, C4);
KA = (D1 << 64) | D2;
D1 = (KA ^ KR) >> 64;
D2 = (KA ^ KR) & MASK64;
D2 = D2 ^ F(D1, C5);
D1 = D1 ^ F(D2, C6);
KB = (D1 << 64) | D2;
3.1.3. Вычисляем вспомогательные 64-битные ключи kw1, ..., kw4, k1, ..., k24, ke1, ..., ke6 в зависимости от размера ключа:
3.1.3.1. Ключ 128 бит:
kw1 = (KL <<< 0) >> 64;
kw2 = (KL <<< 0) & MASK64;
k1 = (KA <<< 0) >> 64;
k2 = (KA <<< 0) & MASK64;
k3 = (KL <<< 15) >> 64;
k4 = (KL <<< 15) & MASK64;
k5 = (KA <<< 15) >> 64;
k6 = (KA <<< 15) & MASK64;
ke1 = (KA <<< 30) >> 64;
ke2 = (KA <<< 30) & MASK64;
k7 = (KL <<< 45) >> 64;
k8 = (KL <<< 45) & MASK64;
k9 = (KA <<< 45) >> 64;
k10 = (KL <<< 60) & MASK64;
k11 = (KA <<< 60) >> 64;
k12 = (KA <<< 60) & MASK64;
ke3 = (KL <<< 77) >> 64;
ke4 = (KL <<< 77) & MASK64;
k13 = (KL <<< 94) >> 64;
k14 = (KL <<< 94) & MASK64;
k15 = (KA <<< 94) >> 64;
k16 = (KA <<< 94) & MASK64;
k17 = (KL <<< 111) >> 64;
k18 = (KL <<< 111) & MASK64;
kw3 = (KA <<< 111) >> 64;
kw4 = (KA <<< 111) & MASK64;
3.1.3.2. Ключ 192 или 256 бит:
kw1 = (KL <<< 0) >> 64;
kw2 = (KL <<< 0) & MASK64;
k1 = (KB <<< 0) >> 64;
k2 = (KB <<< 0) & MASK64;
k3 = (KR <<< 15) >> 64;
k4 = (KR <<< 15) & MASK64;
k5 = (KA <<< 15) >> 64;
k6 = (KA <<< 15) & MASK64;
ke1 = (KR <<< 30) >> 64;
ke2 = (KR <<< 30) & MASK64;
k7 = (KB <<< 30) >> 64;
k8 = (KB <<< 30) & MASK64;
k9 = (KL <<< 45) >> 64;
k10 = (KL <<< 45) & MASK64;
k11 = (KA <<< 45) >> 64;
k12 = (KA <<< 45) & MASK64;
ke3 = (KL <<< 60) >> 64;
ke4 = (KL <<< 60) & MASK64;
k13 = (KR <<< 60) >> 64;
k14 = (KR <<< 60) & MASK64;
k15 = (KB <<< 60) >> 64;
k16 = (KB <<< 60) & MASK64;
k17 = (KL <<< 77) >> 64;
k18 = (KL <<< 77) & MASK64;
ke5 = (KA <<< 77) >> 64;
ke6 = (KA <<< 77) & MASK64;
k19 = (KR <<< 94) >> 64;
k20 = (KR <<< 94) & MASK64;
k21 = (KA <<< 94) >> 64;
k22 = (KA <<< 94) & MASK64;
k23 = (KL <<< 111) >> 64;
k24 = (KL <<< 111) & MASK64;
kw3 = (KB <<< 111) >> 64;
kw4 = (KB <<< 111) & MASK64;
3.2. Шифрование
3.2.1 Шифрование происходит по схеме Фейстеля с 18 этапами для 128-битного ключа и 24 этапами для 192- и 256-битных ключей. Каждые 6 этапов применяются функции FL и FLINV.
3.2.1.1 Ключ 128 бит:
D1 = M >> 64; // сообщение делится на две 64-битные части
D2 = M & MASK64;
D1 = D1 ^ kw1; // Предварительное забеливание
D2 = D2 ^ kw2;
D2 = D2 ^ F(D1, k1);
D1 = D1 ^ F(D2, k2);
D2 = D2 ^ F(D1, k3);
D1 = D1 ^ F(D2, k4);
D2 = D2 ^ F(D1, k5);
D1 = D1 ^ F(D2, k6);
D1 = FL (D1, ke1); // FL
D2 = FLINV(D2, ke2); // FLINV
D2 = D2 ^ F(D1, k7);
D1 = D1 ^ F(D2, k8);
D2 = D2 ^ F(D1, k9);
D1 = D1 ^ F(D2, k10);
D2 = D2 ^ F(D1, k11);
D1 = D1 ^ F(D2, k12);
D1 = FL (D1, ke3); // FL
D2 = FLINV(D2, ke4); // FLINV
D2 = D2 ^ F(D1, k13);
D1 = D1 ^ F(D2, k14);
D2 = D2 ^ F(D1, k15);
D1 = D1 ^ F(D2, k16);
D2 = D2 ^ F(D1, k17);
D1 = D1 ^ F(D2, k18);
D2 = D2 ^ kw3; // Финальное забеливание
D1 = D1 ^ kw4;
C = (D2 << 64) | D1;
3.2.1.2 Ключ 192 или 256 бит:
D1 = M >> 64; // сообщение делится на две 64-битные части
D2 = M & MASK64;
D1 = D1 ^ kw1; // Предварительное забеливание
D2 = D2 ^ kw2;
D2 = D2 ^ F(D1, k1);
D1 = D1 ^ F(D2, k2);
D2 = D2 ^ F(D1, k3);
D1 = D1 ^ F(D2, k4);
D2 = D2 ^ F(D1, k5);
D1 = D1 ^ F(D2, k6);
D1 = FL (D1, ke1); // FL
D2 = FLINV(D2, ke2); // FLINV
D2 = D2 ^ F(D1, k7);
D1 = D1 ^ F(D2, k8);
D2 = D2 ^ F(D1, k9);
D1 = D1 ^ F(D2, k10);
D2 = D2 ^ F(D1, k11);
D1 = D1 ^ F(D2, k12);
D1 = FL (D1, ke3); // FL
D2 = FLINV(D2, ke4); // FLINV
D2 = D2 ^ F(D1, k13);
D1 = D1 ^ F(D2, k14);
D2 = D2 ^ F(D1, k15);
D1 = D1 ^ F(D2, k16);
D2 = D2 ^ F(D1, k17);
D1 = D1 ^ F(D2, k18);
D1 = FL (D1, ke5); // FL
D2 = FLINV(D2, ke6); // FLINV
D2 = D2 ^ F(D1, k19);
D1 = D1 ^ F(D2, k20);
D2 = D2 ^ F(D1, k21);
D1 = D1 ^ F(D2, k22);
D2 = D2 ^ F(D1, k23);
D1 = D1 ^ F(D2, k24);
D2 = D2 ^ kw3; // Финальное забеливание
D1 = D1 ^ kw4;
C = (D2 << 64) | D1;
3.3. Расшифрование
3.3.1 Алгоритм расшифрования идентичен шифрованию, с тем лишь различием, что вспомогательные ключи меняются местами по следующей схеме, в зависимости от длины исходного ключа:
-
Размер ключа
128 бит
192 или 256 бит
kw1 <-> kw3
kw1 <-> kw3
kw2 <-> kw4
kw2 <-> kw4
k1 <-> k18
k1 <-> k24
k2 <-> k17
k2 <-> k23
k3 <-> k16
k3 <-> k22
k4 <-> k15
k4 <-> k21
k5 <-> k14
k5 <-> k20
k6 <-> k13
k6 <-> k19
k7 <-> k12
k7 <-> k18
k8 <-> k11
k8 <-> k17
k9 <-> k10
k9 <-> k16
k10 <-> k15
k11 <-> k14
k12 <-> k13
ke1 <-> ke4
ke1 <-> ke6
ke2 <-> ke3
ke2 <-> ke5
ke3 <-> ke4
4. Программная реализация
Файл main.cpp:
#include "camellia.c"
#include
#include
using namespace std;
void main()
{
Byte *key = NULL, *keytable = NULL, *encript = NULL, *decript = NULL;
char fInput[128], fOutput[128];
FILE *fIn, *fOut;
int sizeOfKey, typeOfOperation=0, bytesRead, toDo;
bool isSizeTrue = false, isExit = false;
while(!isExit)
{
cout << "What to do: run(1) or exit(2)? ";
cin >> toDo;
switch(toDo)
{
case 1:
while(!isSizeTrue)
{
cout << "input size key: ";
cin >> sizeOfKey;
switch(sizeOfKey)
{
case 128:
isSizeTrue = true;
key = new Byte[128/(8*sizeof(Byte))];
break;
case 192:
isSizeTrue = true;
key = new Byte[192/(8*sizeof(Byte))];
break;
case 256:
isSizeTrue = true;
key = new Byte[256/(8*sizeof(Byte))];
break;
}
}
keytable = new Byte[256*sizeof(Byte)];
encript = new Byte[256/(8*sizeof(Byte))];
decript = new Byte[256/(8*sizeof(Byte))];
cout << "input in file: ";
cin >> fInput;
cout << "input out file: ";
cin >> fOutput;
cout << "input key: ";
cin >> key;
if((fIn=fopen(fInput, "ab+"))==NULL)
{
printf("Ошибка при открытии файла.\n");
exit(1);
}
if((fOut=fopen(fOutput, "ab+"))==NULL)
{
printf("Ошибка при открытии файла.\n");
exit(1);
}
cout << "Choose type of operatyon: encript(1), decript(2)? ";
cin >> typeOfOperation;
do
{
switch(typeOfOperation)
{
case 1:
while( (bytesRead = fread(encript, 1, 16, fIn)) > 0 )
{
if(bytesRead<16)
for(int i=bytesRead;i<16;i++)
encript[i] = NULL;
Camellia_Encrypt(sizeOfKey, encript, keytable, decript);
fwrite(decript,1,16,fOut);
}
break;
case 2:
while( (bytesRead = fread(encript, 1, 16, fIn)) > 0 )
{
if(bytesRead<16)
for(int i=bytesRead;i<16;i++)
encript[i] = NULL;
Camellia_Decrypt(sizeOfKey, encript, keytable, decript);
fwrite(decript,1,16,fOut);
}
break;
}
}
while(typeOfOperation !=1 && typeOfOperation !=2);
fclose(fIn);
fclose(fOut);
break;
case 2:
system("pause");
exit(0);
break;
}
}
}
Файл Camellia.c:
typedef unsigned char Byte;
typedef unsigned long Word;
void Camellia_Ekeygen( const int, const Byte *, Byte * );
void Camellia_Encrypt( const int, const Byte *, const Byte *, Byte * );
void Camellia_Decrypt( const int, const Byte *, const Byte *, Byte * );
void Camellia_Feistel( const Byte *, const Byte *, Byte * );
void Camellia_FLlayer( Byte *, const Byte *, const Byte * );
void ByteWord( const Byte *, Word * );
void WordByte( const Word *, Byte * );
void XorBlock( const Byte *, const Byte *, Byte * );
void SwapHalf( Byte * );
void RotBlock( const Word *, const int, Word * );
const Byte SIGMA[48] = {
0xa0,0x9e,0x66,0x7f,0x3b,0xcc,0x90,0x8b,
0xb6,0x7a,0xe8,0x58,0x4c,0xaa,0x73,0xb2,
0xc6,0xef,0x37,0x2f,0xe9,0x4f,0x82,0xbe,
0x54,0xff,0x53,0xa5,0xf1,0xd3,0x6f,0x1c,
0x10,0xe5,0x27,0xfa,0xde,0x68,0x2d,0x1d,
0xb0,0x56,0x88,0xc2,0xb3,0xe6,0xc1,0xfd};
const int KSFT1[26] = {
0,64,0,64,15,79,15,79,30,94,45,109,45,124,60,124,77,13,
94,30,94,30,111,47,111,47 };
const int KIDX1[26] = {
0,0,4,4,0,0,4,4,4,4,0,0,4,0,4,4,0,0,0,0,4,4,0,0,4,4 };
const int KSFT2[34] = {
0,64,0,64,15,79,15,79,30,94,30,94,45,109,45,109,60,124,
60,124,60,124,77,13,77,13,94,30,94,30,111,47,111,47 };
const int KIDX2[34] = {
0,0,12,12,8,8,4,4,8,8,12,12,0,0,4,4,0,0,8,8,12,12,
0,0,4,4,8,8,4,4,0,0,12,12 };
const Byte SBOX[256] = {
112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77,
139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215,
20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80,
170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148,
135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226,
82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158};
#define SBOX1(n) SBOX[(n)]
#define SBOX2(n) (Byte)((SBOX[(n)]>>7^SBOX[(n)]<<1)&0xff)
#define SBOX3(n) (Byte)((SBOX[(n)]>>1^SBOX[(n)]<<7)&0xff)
#define SBOX4(n) SBOX[((n)<<1^(n)>>7)&0xff]
void Camellia_Ekeygen( const int n, const Byte *k, Byte *e )
{
Byte t[64];
Word u[20];
int i;
if( n == 128 ){
for( i=0 ; i<16; i++ ) t[i] = k[i];
for( i=16; i<32; i++ ) t[i] = 0;
}
else if( n == 192 ){
for( i=0 ; i<24; i++ ) t[i] = k[i];
for( i=24; i<32; i++ ) t[i] = k[i-8]^0xff;
}
else if( n == 256 ){
for( i=0 ; i<32; i++ ) t[i] = k[i];
}
XorBlock( t+0, t+16, t+32 );
Camellia_Feistel( t+32, SIGMA+0, t+40 );
Camellia_Feistel( t+40, SIGMA+8, t+32 );
XorBlock( t+32, t+0, t+32 );
Camellia_Feistel( t+32, SIGMA+16, t+40 );
Camellia_Feistel( t+40, SIGMA+24, t+32 );
ByteWord( t+0, u+0 );
ByteWord( t+32, u+4 );
if( n == 128 ){
for( i=0; i<26; i+=2 ){
RotBlock( u+KIDX1[i+0], KSFT1[i+0], u+16 );
RotBlock( u+KIDX1[i+1], KSFT1[i+1], u+18 );
WordByte( u+16, e+i*8 );
}
}
else{
XorBlock( t+32, t+16, t+48 );
Camellia_Feistel( t+48, SIGMA+32, t+56 );
Camellia_Feistel( t+56, SIGMA+40, t+48 );
ByteWord( t+16, u+8 );
ByteWord( t+48, u+12 );
for( i=0; i<34; i+=2 ){
RotBlock( u+KIDX2[i+0], KSFT2[i+0], u+16 );
RotBlock( u+KIDX2[i+1], KSFT2[i+1], u+18 );
WordByte( u+16, e+(i<<3) );
}
}
}
void Camellia_Encrypt( const int n, const Byte *p, const Byte *e, Byte *c )
{
int i;
XorBlock( p, e+0, c );
for( i=0; i<3; i++ ){
Camellia_Feistel( c+0, e+16+(i<<4), c+8 );
Camellia_Feistel( c+8, e+24+(i<<4), c+0 );
}
Camellia_FLlayer( c, e+64, e+72 );
for( i=0; i<3; i++ ){
Camellia_Feistel( c+0, e+80+(i<<4), c+8 );
Camellia_Feistel( c+8, e+88+(i<<4), c+0 );
}
Camellia_FLlayer( c, e+128, e+136 );
for( i=0; i<3; i++ ){
Camellia_Feistel( c+0, e+144+(i<<4), c+8 );
Camellia_Feistel( c+8, e+152+(i<<4), c+0 );
}
if( n == 128 ){
SwapHalf( c );
XorBlock( c, e+192, c );
}
else{
Camellia_FLlayer( c, e+192, e+200 );
for( i=0; i<3; i++ ){
Camellia_Feistel( c+0, e+208+(i<<4), c+8 );
Camellia_Feistel( c+8, e+216+(i<<4), c+0 );
}
SwapHalf( c );
XorBlock( c, e+256, c );
}
}
void Camellia_Decrypt( const int n, const Byte *c, const Byte *e, Byte *p )
{
int i;
if( n == 128 ){
XorBlock( c, e+192, p );
}
else{
XorBlock( c, e+256, p );
for( i=2; i>=0; i-- ){
Camellia_Feistel( p+0, e+216+(i<<4), p+8 );
Camellia_Feistel( p+8, e+208+(i<<4), p+0 );
}
Camellia_FLlayer( p, e+200, e+192 );
}
for( i=2; i>=0; i-- ){
Camellia_Feistel( p+0, e+152+(i<<4), p+8 );
Camellia_Feistel( p+8, e+144+(i<<4), p+0 );
}
Camellia_FLlayer( p, e+136, e+128 );
for( i=2; i>=0; i-- ){
Camellia_Feistel( p+0, e+88+(i<<4), p+8 );
Camellia_Feistel( p+8, e+80+(i<<4), p+0 );
}
Camellia_FLlayer( p, e+72, e+64 );
for( i=2; i>=0; i-- ){
Camellia_Feistel( p+0, e+24+(i<<4), p+8 );
Camellia_Feistel( p+8, e+16+(i<<4), p+0 );
}
SwapHalf( p );
XorBlock( p, e+0, p );
}
void Camellia_Feistel( const Byte *x, const Byte *k, Byte *y )
{
Byte t[8];
t[0] = SBOX1(x[0]^k[0]);
t[1] = SBOX2(x[1]^k[1]);
t[2] = SBOX3(x[2]^k[2]);
t[3] = SBOX4(x[3]^k[3]);
t[4] = SBOX2(x[4]^k[4]);
t[5] = SBOX3(x[5]^k[5]);
t[6] = SBOX4(x[6]^k[6]);
t[7] = SBOX1(x[7]^k[7]);
y[0] ^= t[0]^t[2]^t[3]^t[5]^t[6]^t[7];
y[1] ^= t[0]^t[1]^t[3]^t[4]^t[6]^t[7];
y[2] ^= t[0]^t[1]^t[2]^t[4]^t[5]^t[7];
y[3] ^= t[1]^t[2]^t[3]^t[4]^t[5]^t[6];
y[4] ^= t[0]^t[1]^t[5]^t[6]^t[7];
y[5] ^= t[1]^t[2]^t[4]^t[6]^t[7];
y[6] ^= t[2]^t[3]^t[4]^t[5]^t[7];
y[7] ^= t[0]^t[3]^t[4]^t[5]^t[6];
}
void Camellia_FLlayer( Byte *x, const Byte *kl, const Byte *kr )
{
Word t[4],u[4],v[4];
ByteWord( x, t );
ByteWord( kl, u );
ByteWord( kr, v );
t[1] ^= (t[0]&u[0])<<1^(t[0]&u[0])>>31;
t[0] ^= t[1]|u[1];
t[2] ^= t[3]|v[1];
t[3] ^= (t[2]&v[0])<<1^(t[2]&v[0])>>31;
WordByte( t, x );
}
void ByteWord( const Byte *x, Word *y )
{
int i;
for( i=0; i<4; i++ ){
y[i] = ((Word)x[(i<<2)+0]<<24) + ((Word)x[(i<<2)+1]<<16)
+ ((Word)x[(i<<2)+2]<<8 ) + ((Word)x[(i<<2)+3]<<0 );
}
}
void WordByte( const Word *x, Byte *y )
{
int i;
for( i=0; i<4; i++ ){
y[(i<<2)+0] = (Byte)(x[i]>>24&0xff);
y[(i<<2)+1] = (Byte)(x[i]>>16&0xff);
y[(i<<2)+2] = (Byte)(x[i]>> 8&0xff);
y[(i<<2)+3] = (Byte)(x[i]>> 0&0xff);
}
}
void RotBlock( const Word *x, const int n, Word *y )
{
int r;
if( r = (n & 31) ){
y[0] = x[((n>>5)+0)&3]<
y[1] = x[((n>>5)+1)&3]<
}
else{
y[0] = x[((n>>5)+0)&3];
y[1] = x[((n>>5)+1)&3];
}
}
void SwapHalf( Byte *x )
{
Byte t;
int i;
for( i=0; i<8; i++ ){
t = x[i];
x[i] = x[8+i];
x[8+i] = t;
}
}
void XorBlock( const Byte *x, const Byte *y, Byte *z )
{
int i;
for( i=0; i<16; i++ ) z[i] = x[i] ^ y[i];
}
5. Тестовый пример
Содержимое файла test.txt:
Camellia — алгоритм симметричного блочного шифрования (размер блока 128 бит, ключ 128, 192, 256 бит), один из финалистов европейского конкурса NESSIE (наряду с AES и Shacal-2), разработка японских компаний Nippon Telegraph and Telephone Corporation и Mitsubishi Electric Corporation (представлен 10 марта 2000 г.). Сертифицирован японской организацией CRYPTREC как рекомендованный для промышленного и государственного использования алгоритм. Camellia является дальнейшим развитием алгоритма шифрования E2, одного из алгоритмов, представленных на конкурсе AES и с использованием элементов алгоритма MISTY1. Структура алгоритма основана на классической цепи Фейстеля с предварительным и финальным забеливанием. Цикловая функция использует нелинейное преобразование (S-блоки), блок линейного рассеивания каждые 16 циклов (побайтовая операция XOR) и байтовую перестановку. В зависимости от длины ключа имеет 18 циклов (128 разрядный ключ), либо 24 цикла (192 и 256 разрядный ключ). Поддержка алгоритма Camellia введена в 2008 году в браузере Mozilla Firefox 3. Алгоритм патентован, однако распространяется под рядом свободных лицензий, в частности, является частью проекта OpenSSL. |
Работа программы:
|
Содержание файла test_encrypt.txt:
鐏둶⨊尞歖蹼穔얏驓꽥ᨈ屶춝▼ᚿ耨쭌萞౯ᔺ熗ⰴ➓鋏㾃砟䗬❒蠈F 翰塪ῠ촰駨栗咧봦ಥオ榨녘㰡譴翵⧸楖렝䘕瑴乚⥐牃䮒 鱌䤼뙺傗㰷ਇ癗ࣷ↑틳Ủ㌙硴ᧆⷧ⫏ܬ窇ᰯ螆Ⱘ馫ዼ립槻 煢헾뷹ꐦȵ聩쾃㜦沙藛䌔痘갌҅䢎ꮠ풵왯䀳옥ॴ畖ꐯ垌재Əꑵ㩘㡌唊 ࣶꑰힹ㞄栛ꂜ䊳蔚䦿⛮ಬꗜ橞竜着鄠㞀ᚲ곖䱲䜘➾苷 彣㯩ꑨ皦ﻏ極ݷ뤨亲띌毥氄ᡀ덜ꐒ믉挲荔㊤뼹븴ﺍ⬠郻ⱴꎹ幠뺿齟ℎ臤繫⥡ 迶燀輠㑒㊙젱⪍ɪ㶽턁胊焷吮ೳ蘫뷰켜ࠟ徖쓿쫍總停ﻫ蟪䀩ో쨕伜諚 橜㿀㋧阥ሑ䨨꩝꒯窨量鳢ଷ⊹社ꥺ䇻짒꧲飀抍輠۶䔩㦯嫊凅踗Ȱ焨轶㊼ 恾霒탈簣슖ꉥ癛㝩⥵酸૾븰㲪䒌㗺풅蠙梋揹ㅯ鉙䟩ⶂ汔蘨濢瓏녹 꼄췒瘝ᐚ萅蜏绢䫙嗧腽菜䅥썈꣰䪐⹉ॱ䐆䑋牋㉱꿉⭶ኦᢘ⤐≱⛟⤳뢋孛ᑶ ℏꂿ힖ꏜ⁂琉턄髎䪣퇘嬡┿由侥㻍ᬿ䷇Ʀ鈰⮋賚迾欮㣭璼惪喽볗覴½ ﰝ槤蒜輭ᨔ咹郝蠡⛁墫瀟蘆윀鸀֝篧롾㺯貢⚄ᗡꐑ廃ᒼ벁겫᳖睛峟츄怉 繀땬罤让⺈뤝쵉ލ競ﲥ騇怒棜欼款య싥眏અ摭憷ꛮ㗄䕶꠪ ㋗欟嘗呕痕櫦䗝쌣鴞鞼㋈!㜞嗠鱷㼐Ʂ딍懷폹䧩鹺孹ꋳ➌읷떔ʜ ᠸ浩䱦揓㹕晚爼鿽랶ﭮ뜕阏쩌婣辴旈鎍讵劧勒簩箫迆抖졛Ⅻ灥ᵯ 춷ꎪ୬怬⬭唐⤽⪽륨泸脆ꪋ鴟⥿艹뻣싾鳒覤䔄ཋ錝圽玮ꘔ詇↮鉞햄㚥깴גꡣ 뵓랺遻呖끣腙䆰㟙꠷묳鐨뢹並閏嚘锷햫螥姅ꢫ驅㪕⬋✨皕⥚ |
Содержание файла test_decrypt.txt идентично содержимому файла test.txt.
6. Литература
1. Википедия. Camellia (Алгоритм) [Интернет ресурс] URL: http://ru.wikipedia.org/wiki/Camellia_(Алгоритм), 09.11.2012
2. Википедия. Сеть Фейстеля [Интернет ресурс] URL: http://ru.wikipedia.org/wiki/Сеть_Фейстеля, 09.11.2012
3. Camellia Source Codes [Интернет ресурс] URL: http://info.isl.ntt.co.jp/crypt/eng/camellia/index.html, 09.11.2012
0>8>