Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Алгоритм шифрования
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Ivan Kuznetzov
Подскажите пожалуйста алгоритм шифрования/дешифрования потоковых данных. (есть массив из n байт, его надо зашифровать и расшифровывать на приеме, зная ключ), смотрел в сторону xxtea, работает только с long.
может тупо биты в байте переставлять, наподобие DES ? rolleyes.gif

P.S.
может у кого есть xxtea, который бы с потоком работал?
blackfin
Не для AVR, но все же: AES.
V_G
А очень нужно вникать в суть алгоритма?
Если нет, используйте проц xmega. Хоть в DES, хоть в AES шифруйте
Savrik
Когда-то я переделал для AVR DES. http://electronix.ru/forum/index.php?s=&am...st&p=458258. Посмотрите, код легко портируется.
Ivan Kuznetzov
Нашел тут простую реализацию XXTEA. уточню, код будет работать в меге32.

в описании алгоритма указано: at least two words (64 bits)

Код
void xxtea_crypt(unsigned long *v)
{
unsigned long long  q=40;
unsigned long long z=v[1], y=v[0], sum=0, e;

while ( q-- > 0 )
{
  sum += DELTA;
  e = sum >> 2&3;
  y = v[1];
  z = v[0]+= ( (((z>>9)^(y<<2))+((y>>3)^(z<<6)))^((sum^y)+(key[e]^z)) );
  y = v[0];
  z = v[1] += ( (((z>>9)^(y<<2))+((y>>3)^(z<<6)))^((sum^y)+(key[1^e]^z)) );
    }

}

Код
void xxtea_decrypt(unsigned long *v)
{
long  q=40;
long z=v[1], y=v[0], e, sum = q*DELTA;

while (sum != 0)
{
   e = sum>> 2&3;
   z = v[0];
   y = v[1] -= ( (((z>>9)^(y<<2))+((y>>3)^(z<<6)))^((sum^y)+(key[1^e]^z)) );
   z = v[1];
   y = v[0] -= ( (((z>>9)^(y<<2))+((y>>3)^(z<<6)))^((sum^y)+(key[e]^z)) );
   sum -= DELTA;
     }

}


как теперь туда байтовый массив запихать? Делал преобразование байт с помощью этой функции:

Код
ULONG GetInt32( UCHAR *pBytes )
{
return (ULONG)(*(pBytes + 3) << 24 | *(pBytes + 2) << 16 | *(pBytes + 1) << 8 | *pBytes);
}


IAR ругается что shift count is too large

P.S.
Админам: тема касается AVR
MrYuran
Цитата(Ivan Kuznetzov @ Mar 5 2010, 09:53) *
IAR ругается что shift count is too large

А просто взять байты и переложить в нужное место нельзя чтоли?
Ну или там с юнионами поизвращаться
Без всяких сдвигов
ИАР, кстати, мог бы и сам догадаться rolleyes.gif
Ivan Kuznetzov
Цитата(MrYuran @ Mar 5 2010, 12:40) *
А просто взять байты и переложить в нужное место нельзя чтоли?
Ну или там с юнионами поизвращаться
Без всяких сдвигов
ИАР, кстати, мог бы и сам догадаться rolleyes.gif

Все верно! иар оказался догадистый! просто сделал приведение типов, так работает:

Код
UCHAR buffer[256];

btea((unsigned long*)buffer, -(sizeof(buffer)/4));
Ivan Kuznetzov
ничего не понимаю... есть шифратор XTEA, который шифрует массив из 64-x long-гов, написан на Pascal. И есть точно такой-же код дешифратора, только на Си и в микроконтроллере, который кушает с флехи 256 байт в буфер и дешифрует их как (long*). дык вот непонятно почему код на си "переворачивает" каждый long (из 64-х) задом-наперёд. Если декодировать с помощью дельфи, то последовательность правильная получается.

код в Делфи:
Код
type
TTeaData = array of Longword;

procedure XTeaBlockEncrypt(var data: TTeaData; const key: TTeaKey; N: Longword = 2);
var
  y,z,sum,limit: Longword;
  i,no:integer;
begin
  no := Length(data);
  i:=0;
while (i < no ) do
begin

  y:=data[i];
  z:=data[i+1];
  sum:=0;
  limit := Delta*N;

  while sum <> limit do
  begin
    inc(y,(((z shl 4) xor (z shr 5)) + z) xor (sum+key[sum and 3]));
    inc(sum,Delta);
    inc(z,(((y shl 4) xor (y shr 5)) + y) xor (sum+key[(sum shr 11) and 3]));
  end;

  data[i]:=y;
  data[i+1]:=z;
  inc(i,2);
end;

end;


Код в МК:
Код
void xtea_dec(unsigned long* data, unsigned char dataLength)
{
    unsigned char i=0;
    unsigned long x1;
    unsigned long x2;
    unsigned long sum;
    unsigned long iterations;
      
    iterations = NUM_ITERATIONS;
    
    while(i<dataLength)
    {
        sum = DELTA*iterations;
        x1=*data;
        x2=*(data+1);

        while(sum != 0)
        {
          x2 -= ((((x1<<4) ^ (x1>>5)) + x1) ^ (sum + key[(sum>>11)&0x03]));
          sum-=DELTA;
          x1 -= ((((x2<<4) ^ (x2>>5)) + x2) ^ (sum + key[sum&0x03]));
        }
              
        *(data++)=x1;
        *(data++)=x2;
        i+=2;
    }    
}


res = f_read(&fil,buffer,sizeof(buffer),&br); //читаем массив с флешки

xtea_dec((unsigned long*)buffer, (sizeof(buffer)/4));  //декодируем массив


кстати, при кодировании/декодировании самой мегой проц, случае с байтами, тоже задом-наперед результат ставит, вот результат из терминала протеуса:
Код
(char) operation:
33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
[b]8D 1 87 4D[/b] D F0 DE FF 8D 1 87 4D D F0 DE FF 8D 1 87 4D D F0 DE FF 8D 1 87 4D D F0 DE FF
33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33

(Long) operation:
33333333 33333333 33333333 33333333 33333333 33333333 33333333 33333333
[b]4D87018D[/b] FFDEF00D 4D87018D FFDEF00D 4D87018D FFDEF00D 4D87018D FFDEF00D
33333333 33333333 33333333 33333333 33333333 33333333 33333333 33333333


А если забить на все эти преобразования из long в char и оперировать там-и-там с long, как тогда лонг можно побайтно выдать в SPI, причем пачками не более 32-х байт?
с массивом байт все просто, а как с long massiv[64] сделать?:
Код
for(j=0;j<sizeof(buffer);j+=32){
while (!DREQ);
vs_stream(&buffer[j],32);}
V_G
Про собственно шифрование ничего не скажу. А вот про переворот вроде понятно.
На Си существует следующий порядок размещения многобайтных переменных в памяти: младший байт - по младшему адресу.
На Паскале (и в Дельфях) - похоже, наоборот: первыми (по младшим адресам) размещены старшие байты.

Чтобы не мучить МК, перепишите паскалевский код на Си
Ivan Kuznetzov
Цитата(V_G @ Mar 11 2010, 17:59) *
Про собственно шифрование ничего не скажу. А вот про переворот вроде понятно.
На Си существует следующий порядок размещения многобайтных переменных в памяти: младший байт - по младшему адресу.
На Паскале (и в Дельфях) - похоже, наоборот: первыми (по младшим адресам) размещены старшие байты.

Чтобы не мучить МК, перепишите паскалевский код на Си

кароче получилось! Сначала поменял декодирование массива char-ов на массив long. Декодирую, отсылаю - пашет! пошел дальше: меняю размер декодируемого блока - (от 32-х long до 128 long) все равно пашет! тоесть для XTEA пофигу каким блоком декодировать. Далее, дай, думаю, вернусь к массиву char - сделал - РАБОТАЕТ! так и не понял в чем прикол был... smile3046.gif Коды на дельфи и на Си, кстати полностью идентичны...

Еще вопрос к спецам по Дельфи: как этот код оптимизировать? если оперирую с дин. массивом data - ничего не пашет, приходится перед кодированием забивать из Buf в data, а затем обратно в Buf из data и Buf уже в файл. Если проделываю BlockRead или BlockWrite над массивом data - прога вываливается..

Код
type TTeaData = array of Longword;

var
Buf: array[0..511] of Longword;
data: TTeaData;


Код
        BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
          for i := 0 to (SizeOf(Buf) div 4) - 1 do
          begin
          data[i]:= Buf[i];
          end;

          if algo=0 then XTeaBlockEncrypt(data, MasterKey);
          if algo=1 then XXTeaEncrypt(data, MasterKey);

        for i := 0 to (SizeOf(Buf) div 4) - 1 do
          begin
          Buf[i]:= data[i];
          end;

        BlockWrite(ToF, Buf, NumRead, NumWritten);
XVR
Цитата(V_G @ Mar 11 2010, 15:59) *
Про собственно шифрование ничего не скажу. А вот про переворот вроде понятно.
На Си существует следующий порядок размещения многобайтных переменных в памяти: младший байт - по младшему адресу.
На Паскале (и в Дельфях) - похоже, наоборот
К C/Pascal это не имеет НИКАКОГО отношения. Порядок следования байтов в long'е определяется архитектурой процессора. Для Intel'овских процессоров используется LSB размещение (младшие биты/байты идут в памяти первыми). На МК видимо наоборот.
Есть нюанс - если МК аппаратно не поддерживает работу более чем с байтовыми переменными, то решение о LSB/MSB остается полностью на усмотрение компилятора.

Цитата
Чтобы не мучить МК, перепишите паскалевский код на Си
Не поможет - на x86 LSB будет везде, вне зависимости от C/Pascal/Delphi/etc
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.