Главная страница
Навигация по странице:

  • Размер ключа 128 бит 192 или 256 бит

  • Лабораторная работа: блочный шифр Camellia. Лабораторная 2 Филатов Camellia. Лабораторная работа 2 по методам и средствам защиты Реализация симметричной криптосистемы


    Скачать 212.5 Kb.
    НазваниеЛабораторная работа 2 по методам и средствам защиты Реализация симметричной криптосистемы
    АнкорЛабораторная работа: блочный шифр Camellia
    Дата09.12.2021
    Размер212.5 Kb.
    Формат файлаdoc
    Имя файлаЛабораторная 2 Филатов Camellia.doc
    ТипЛабораторная работа
    #298353


    Липецкий государственный технический университет

    Кафедра автоматизированных систем управления


    Лабораторная работа №2

    по методам и средствам защиты

    Реализация симметричной криптосистемы





    Студент










    Филатов А.А.













    подпись, дата




    фамилия, инициалы







    Группа




    АС-09-2





































    Принял































    Батищев Р.В.







    ученая степень, звание




    подпись, дата




    фамилия, инициалы





    Липецк 2012

    1. Задание



    Изучить принципы работы и классификацию симметричных криптосистем, особенности современных алгоритмов, получить практические навыки программирования симметричных криптографических алгоритмов.
    Таблица 1. Вариант алгоритма



    Алгоритм

    16.

    Camellia
    1. Краткие теоретические сведения




    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]<>5)+1)&3]>>(32-r);

    y[1] = x[((n>>5)+1)&3]<>5)+2)&3]>>(32-r);

    }

    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



    написать администратору сайта