Генератор длинных ключей на основе многочленов Галуа


А вот теперь я приведу подход к созданию простых, но устойчивых шифров. Суть
подхода заключается в том, что для надежного шифрования длина ключа должна быть
больше длины шифруемого сообщения, не содержать повторений и прочих артефактов,
по которым можно определить формат сообщения. Такими свойствами обладают
неприводимые многочлены Галуа - многочлены, период повторения которых очень
велик по сравнению с длиной и сложностью самого многочлена. С помощью таких
многочленов можно генерить сверх длинные неповторяющиеся последовательности, к
примеру, многочлен третьего порядка (с тремя коэффициентами) - позволяет
сгенерировать 7 неповторяющихся чисел (2^x-1)

Файл KeyGenerator.h

/*///////////////////////////////////////////////////////////////

 KeyGenerator, GNU C++, 2005-01-18

 Генератор длинных ключей
 на основе неприводимых многочленов Галуа

 Artix, master@7masterov.ru, icq:53666599, skype:artixmaster
 
 * Error in code? Nothing is perfect!
 * Free source for free Linux, use it for free!
 * Please, do not remove this comment!

///////////////////////////////////////////////////////////////*/
#ifndef KeyGeneratorH
#define KeyGeneratorH

class KeyGenerator {

private:
    unsigned int vKeyValue;    // Значение
    unsigned int vBitMaskLen;  // Битовая длина маски (0xFF)
    unsigned int vBitMask;     // = 2^vBitMaskLen-1
    unsigned int vPolinom;     // Битовый полином

public:
    KeyGenerator();
    unsigned int GetKey();
    void SetBitMaskLen(unsigned int iBitMaskLen);
    void SetKeyValue(unsigned int iStartValue);
}; // class

#end

Файл KeyGenerator.c

#include "KeyGenerator.h"

KeyGenerator::KeyGenerator()
{
    vPolinom = 0x05;
    vKeyValue = 1;
    vBitMaskLen = 3;
    vBitMask = 0x07;
}

// Установка "рабочего поля"
void KeyGenerator::SetBitMaskLen(unsigned int iBitMaskLen)
{
    vBitMask = 1;
    vBitMaskLen = iBitMaskLen;
    for(unsigned int i=1;i<vBitMaskLen;i++) vBitMask|=(vBitMask<<1);
}

// Установка стартового значения
void KeyGenerator::SetKeyValue(unsigned int iStartValue)
{
    vKeyValue = iStartValue;
}

// Получение псевдослучайного числа
unsigned int KeyGenerator::GetKey()
{
    // bit = бит переноса
    // vBitMask = поле маски
    // vPolinom = неприводимый многочлен
    unsigned int bit=0;
    for(unsigned int i=0,b=1; i<vBitMaskLen; i++,b<<=1)
        bit+=(((vKeyValue&b&vPolinom)!=0)?1:0);
    bit&=0x01; vKeyValue<<=1; 
    vKeyValue|=bit; vKeyValue&=vBitMask;
    return vKeyValue;
}


Пример использования класса:

KeyGenerator p;

// Стартовое значение
p.SetKeyValue( 1 );

// Период повторения ключа = 2^3-1 = 7
p.SetBitMaskLen( 3 );

int rndKey;
// Получаем псевдослучайную последовательность
for(int i=0;i<32;i++) {
    rndKey = p.GetKey();
}

В дальнейшем с полученной последовательностью ключей можно делать XOR, сдвиг,
замену - но лучше сделать обмен блоков, что-то типа упрощенного алгоритма DES,
и тогда надежность шифра сильно-сильно возрастет. Стоит также отметить, что
неприводимых многочленов не так уж и много, поиск таких многочленов - это
отдельная задача, и в реальных боевых задачах лучше использовать многочлены
32-ого порядка и выше, всегда осложняя их перестановками блоков.