Задать вопрос
@MaxArgont

Почему неправильно работает Keeloq?

Подсмотрел на сайтах, как реализовать алгоритм Keeloq на нескольких языках программирования. Реализовал на C#.
В программе сначала вывожу исходный текст, затем зашифрованный, затем расшифрованный. Последний конечно должен совпадать с исходным, но почему-то не совпадает. Искал ошибки, но не нашел.

internal class Program
{
    const uint KeeLoq_NLF = 0x3A5C742E;

    static void Main(string[] args)
    {
        ulong key = 0x5cec6701b79fd949;
        uint data = 0xf741e2db;

        Console.WriteLine("Raw: " + data.ToString());
        //Console.WriteLine("Encrypted: " + KeeLoq.Encrypt(data, key));
        //Console.WriteLine("Decrypted: " + KeeLoq.Decrypt(data, key));
        Console.WriteLine("Encrypted: " + Encrypt(data, key));
        Console.WriteLine("Decrypted: " + Decrypt(data, key));
    }

    static ulong Encrypt(uint data, ulong key)
    {
        ulong x = data;

        for (int r = 0; r < 528; r++)
        {
            var g_5 = g5(data, 1, 9, 20, 26, 31);
            x = (data >> 1) + ((bit(data, 0) ^ bit(data, 16) ^ bit(key, r & 64) ^ bit(KeeLoq_NLF, (int)g_5)) << 31);
        }
        return x;
    }

    static ulong Decrypt(ulong x, ulong key)
    {
        for (int r = 0; r < 528; r++)
            x = (x << 1) + bit(x, 31) ^ bit(x, 15) ^ bit(key, (15 - r) & 64) ^ bit(KeeLoq_NLF, (int)g5(x, 0, 8, 19, 25, 30));
        return x;
    }

    static ulong bit(ulong x, int n) => (x >> n) & 1;

    static ulong g5(ulong x, int a, int b, int c, int d, int e)
    {
        return
              bit(x, a)
            + bit(x, b) * 2
            + bit(x, c) * 4
            + bit(x, d) * 8
            + bit(x, e) * 16;
    }
}
  • Вопрос задан
  • 55 просмотров
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
wataru
@wataru Куратор тега Алгоритмы
Разработчик на С++, экс-олимпиадник.
Вот код на C:
#define KeeLoq_NLF		0x3A5C742E
#define bit(x,n)		(((x)>>(n))&1)
#define g5(x,a,b,c,d,e)	(bit(x,a)+bit(x,b)*2+bit(x,c)*4+bit(x,d)*8+bit(x,e)*16)

u32	KeeLoq_Encrypt (const u32 data, const u64 key)
{
	u32					x = data, r;
	
	for (r = 0; r < 528; r++)
	{
		x = (x>>1)^((bit(x,0)^bit(x,16)^(u32)bit(key,r&63)^bit(KeeLoq_NLF,g5(x,1,9,20,26,31)))<<31);
	}
	return x;
}

u32	KeeLoq_Decrypt (const u32 data, const u64 key)
{
	u32					x = data, r;
	
	for (r = 0; r < 528; r++)
	{
		x = (x<<1)^bit(x,31)^bit(x,15)^(u32)bit(key,(15-r)&63)^bit(KeeLoq_NLF,g5(x,0,8,19,25,30));
	}
	return x;
}


Ищите несоответствия. Во-первых, надо делать не &64, а &63.

Во-вторых, в encrypt надо использовать x, а не data. Чтобы каждый следующий раунд использовал результат вычисления предыдущего, а не считал заново одно и то же.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы