Автор Тема: Тонкости программирования и использования AVR  (Прочитано 34500 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Там есть исходник на С, но по си я дуб дубом...
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

eriser

  • Права бана
  • Профи
  • *
  • Сообщений: 202
  • Карма: 1
  • Пол: Мужской
  • Да чтоб вы все были здоровы...
    • Просмотр профиля
Там ещё есть на делфи (он же паскаль). Честно говоря и знаток я невеликий, и пока смотрю на это как баран...
 procedure TForm1.Button1Click (Sender: TObject);
var
  i: integer;
  error: boolean;
begin
  error := False;
  randomize();
  for i := 0 to test_count - 1 do
    begin
    buf[0] := random(maxlong);
    buf[1] := random(maxlong);
    buf[2] := random(maxlong);
    buf[3] := random(maxlong);
    tkey[0] := random(maxlong);
    tkey[1] := random(maxlong);
    tkey[2] := random(maxlong);
    tkey[3] := random(maxlong);
    tkey[4] := random(maxlong);
    tkey[5] := random(maxlong);
    tkey[6] := random(maxlong);
    tkey[7] := random(maxlong);
    xtea3_setkey(@tkey);   // Loading then key
    memo1.Lines.Add(#13#10#13#10 + \'KEY: \');
    memo1.Lines.Add(Format(\'%8x %8x %8x %8x %8x %8x %8x %8x \',
      [key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]]));
    memo1.Lines.Add(\'ORIGINAL: \');
    memo1.Lines.Add(Format(\'%8x %8x %8x %8x\', [buf[0], buf[1], buf[2], buf[3]]));
    move(buf, cb, 16);
    xtea3_crypt(@cb); // Encryption of 2-longwords (64 bit block)
    memo1.Lines.Add(\'ENCRYPTED: \');
    memo1.Lines.Add(Format(\'%8x %8x %8x %8x \', [cb[0], cb[1], cb[2], cb[3]]));
    xtea3_setkey(@tkey);   // Loading then key
    xtea3_decrypt(@cb); // Decryption of 2-longwords (64 bit block)
    memo1.Lines.Add(\'DECRYPTED: \');
    memo1.Lines.Add(Format(\'%8x %8x %8x %8x \', [cb[0], cb[1], cb[2], cb[3]]));
    if (cb[0] <> buf[0]) or (cb[1] <> buf[1]) or (cb[2] <> buf[2]) or
      (cb[3] <> buf[3]) then
      error := True;
    if error then
      memo1.Lines.Add(\'DECODED TO BAD DATA!!!\')
    else
      memo1.Lines.Add(\'DECODED OK\');
    end;
  memo1.Lines.Add(#13#10#13#10#13#10 + \' ------------------------------  \');
  if error then
    memo1.Lines.Add(\'TEST FAILED, DECODED DATA IS BAD.\')
  else
    memo1.Lines.Add(FORMAT(\'ALL %U TESTS FINISHED OK!\', [test_count]));
end;
« Последнее редактирование: 24 Октября 2009, 00:30:18 от eriser »
Не все йогурты одинаково полезны!

eriser

  • Права бана
  • Профи
  • *
  • Сообщений: 202
  • Карма: 1
  • Пол: Мужской
  • Да чтоб вы все были здоровы...
    • Просмотр профиля
Тут для примера генерируются случайные данные и ключ
buf[0] := random(maxlong);
    buf[1] := random(maxlong);
    buf[2] := random(maxlong);
    buf[3] := random(maxlong);
    tkey[0] := random(maxlong);
    tkey[1] := random(maxlong);
    tkey[2] := random(maxlong);
    tkey[3] := random(maxlong);
    tkey[4] := random(maxlong);
    tkey[5] := random(maxlong);
    tkey[6] := random(maxlong);
    tkey[7] := random(maxlong);

Тут вывод  того что нагенерилось. Тоесть, для того чтобы что-то закодировать нужно  подсовывать реальные данные в переменную  buf и ключ соответственно.

 memo1.Lines.Add(Format(\'%8x %8x %8x %8x %8x %8x %8x %8x \',
      [key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]]));
    memo1.Lines.Add(\'ORIGINAL: \');
    memo1.Lines.Add(Format(\'%8x %8x %8x %8x\', [buf[0], buf[1], buf[2], buf[3]]));
   

« Последнее редактирование: 24 Октября 2009, 00:18:17 от eriser »
Не все йогурты одинаково полезны!

eriser

  • Права бана
  • Профи
  • *
  • Сообщений: 202
  • Карма: 1
  • Пол: Мужской
  • Да чтоб вы все были здоровы...
    • Просмотр профиля
Вот тут всё и происходит.
Какие  метаморфозы тут происходят предстоит ещё выяснить, я уже больше года програмный код в глаза не видел, нужно вспоминать. Если сам разберёшся расскажи. Если нет, как нибудь выпьем этот треугольник...

move(buf, cb, 16);
    xtea3_crypt(@cb); // Encryption of 2-longwords (64 bit block)
 
Ну а дальше понятно...


   memo1.Lines.Add(\'ENCRYPTED: \');
    memo1.Lines.Add(Format(\'%8x %8x %8x %8x \', [cb[0], cb[1], cb[2], cb[3]]));
   
Тут опять загвоздка...

     xtea3_setkey(@tkey);   // Loading then key
    xtea3_decrypt(@cb); // Decryption of 2-longwords (64 bit block)


    memo1.Lines.Add(\'DECRYPTED: \');
    memo1.Lines.Add(Format(\'%8x %8x %8x %8x \', [cb[0], cb[1], cb[2], cb[3]]));
    if (cb[0] <> buf[0]) or (cb[1] <> buf[1]) or (cb[2] <> buf[2]) or
      (cb[3] <> buf[3]) then
      error := True;
    if error then
      memo1.Lines.Add(\'DECODED TO BAD DATA!!!\')
    else
      memo1.Lines.Add(\'DECODED OK\');
    end;
« Последнее редактирование: 23 Октября 2009, 23:47:23 от eriser »
Не все йогурты одинаково полезны!

eriser

  • Права бана
  • Профи
  • *
  • Сообщений: 202
  • Карма: 1
  • Пол: Мужской
  • Да чтоб вы все были здоровы...
    • Просмотр профиля
У меня где-то был код кодировки viaccess (насколько помню на паскале и для pic 16f84 но нужно искать). По сравнению с XTEA, viaccess мне казался когда-то понятнее, хоть и код был намного сложнее. Если ничего не получится-неплохой вариант. :-/
« Последнее редактирование: 23 Октября 2009, 23:51:18 от eriser »
Не все йогурты одинаково полезны!

Форум проекта "Минилаб-Мастер"


Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Стоп-стоп-стоп...

А мне показалось, что основные функции там в этом коде:

(**      XTEA3.PAS by Alexander Myasnikov                                  **)
 (**      XTEA-3 by Tom St Denis implementation for Delphi programmers      **)
 (**      XTEA-3 encrypts 128 bit block with 256 bit key                    **)
 (**      XTEA-3 is based on original TEA , but with large key and block    **)
 (**      It seems to be much secure version                                **)
 (**      Implemented by Alexander Myasnikov                                **)
 (**      WEB:       www.darksoftware.narod.ru                              **)

{$Q-}

library libxtea3;


type
  t128buf = array [0..3] of longword;

type
  p128buf = ^t128buf;


var
  key: array [0..7] of longword;

const
  ITERATIONS = 32;

  function rol (N, R: longword): longword;
  asm
      MOV EAX,N
      MOV ECX, R
      ROL EAX, CL
  end;


  procedure crypt (plain: p128buf); stdcall; export;
  var
    a, b, c, d, sum, r, t: longword;
  begin
    sum := 0;
    a := plain[0] + key[0];
    b := plain[1] + key[1];
    c := plain[2] + key[2];
    d := plain[3] + key[3];
    for r := 0 to ITERATIONS - 1 do
      begin
      a := a + (((b shl 4) + rol(key[(sum mod 4) + 4], b)) xor
        (d + sum) xor ((b shr 5) + rol(key[sum mod 4], b shr 27)));
      sum := sum + $9E3779B9;
      c := c + (((d shl 4) + rol(key[((sum shr 11) mod 4) + 4], d)) xor
        (b + sum) xor ((d shr 5) + rol(key[(sum shr 11) mod 4], d shr 27)));

      t := a;
      a := b;
      b := c;
      c := d;
      d := t;
      end;
    plain[0] := a xor key[4];
    plain[1] := b xor key[5];
    plain[2] := c xor key[6];
    plain[3] := d xor key[7];
  end;


  procedure decrypt (plain: p128buf); stdcall; export;
  var
    a, b, c, d, delta, sum, r, t: longword;
  begin
    delta := $9E3779B9;
    sum := delta * ITERATIONS;

    d := plain[3] xor key[7];
    c := plain[2] xor key[6];
    b := plain[1] xor key[5];
    a := plain[0] xor key[4];


    for r := ITERATIONS - 1 downto 0 do
      begin

      t := d;
      d := c;
      c := b;
      b := a;
      a := t;

      c := c - (((d shl 4) + rol(key[((sum shr 11) mod 4) + 4], d)) xor
        (b + sum) xor ((d shr 5) + rol(key[(sum shr 11) mod 4], d shr 27)));

      sum := sum - $9E3779B9;

      a := a - (((b shl 4) + rol(key[(sum mod 4) + 4], b)) xor
        (d + sum) xor ((b shr 5) + rol(key[sum mod 4], b shr 27)));

      end;


    plain[3] := d - key[3];
    plain[2] := c - key[2];
    plain[1] := b - key[1];
    plain[0] := a - key[0];

  end;


  procedure setup (k: pointer); stdcall; export;
  begin
    move(k^, key, 32);
  end;


exports
  crypt,
  decrypt,
  setup;

end.
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Все вроде понятно, даже вроде понял, что делает код

asm    
 MOV EAX,N      
MOV ECX, R    
 ROL EAX, CL 
end;
 - в баскоме есть могучие команды ROTATE и SHIFT, но с конструкцией

type  t128buf = array [0..3] of longword;
type  p128buf = ^t128buf;

понять не могу - что там за птичка? Все справочники прошерстил...
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
А выше ты выдернул оболочку основного кода.....
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

pumpkin

  • Профи
  • ****
  • Сообщений: 240
  • Карма: 2
  • Пол: Мужской
  • Это Я :-)
    • Просмотр профиля
type
  t128buf = array [0..3] of longword;
  p128buf = ^t128buf;
это ссылка (указатель), то есть переменная типа p128buf содержит (если не ноль) адрес массива типа t128buf.

функция rol циклически сдвигает N на R бит.
« Последнее редактирование: 24 Октября 2009, 15:03:23 от pumpkin »

pumpkin

  • Профи
  • ****
  • Сообщений: 240
  • Карма: 2
  • Пол: Мужской
  • Это Я :-)
    • Просмотр профиля
Прокомментарил код:
library libxtea3;

//*** описываем тип для шифруемого блока - массив 4 * Longword = 128 bit
type
  t128buf = array [0..3] of longword;

//*** описываем тип - указатель на тип t128buf (типизированный pointer)
type
  p128buf = ^t128buf;


//*** этот переменная есть массив, содержащий текущий
//*** ключ (8 * Longword = 256 bit) который используется
//*** в функциях crypt и decrypt
var
  key: array [0..7] of longword;

//*** количество итераций
const
  ITERATIONS = 32;

  //*** функция циклически сдвигает влево N на R бит:
  //*** заносим N в регистр EAX, заносим R в регистр ECX
  //*** прокручиваем регистр EAX на CL позиций
  //*** (регистр CL - младший байт регистра ECX)
  function rol (N, R: longword): longword;
  asm
      MOV EAX,N
      MOV ECX, R
      ROL EAX, CL
  end;

  //*** функция шифрует блок в 128 бит (16 байт) находящийся в массиве
  //*** по адресу plain на текущем ключе key (32 байта)
  procedure crypt (plain: p128buf); stdcall; export;
  var
    a, b, c, d, sum, r, t: longword;
  begin
    //*** арифметика думаю понятна и описывать не надо
    sum := 0;
    a := plain[0] + key[0];
    b := plain[1] + key[1];
    c := plain[2] + key[2];
    d := plain[3] + key[3];
    for r := 0 to ITERATIONS - 1 do
      begin
      a := a + (((b shl 4) + rol(key[(sum mod 4) + 4], b)) xor
        (d + sum) xor ((b shr 5) + rol(key[sum mod 4], b shr 27)));
      sum := sum + $9E3779B9;
      c := c + (((d shl 4) + rol(key[((sum shr 11) mod 4) + 4], d)) xor
        (b + sum) xor ((d shr 5) + rol(key[(sum shr 11) mod 4], d shr 27)));
      t := a;
      a := b;
      b := c;
      c := d;
      d := t;
      end;
    plain[0] := a xor key[4];
    plain[1] := b xor key[5];
    plain[2] := c xor key[6];
    plain[3] := d xor key[7];
  end;

  //*** операция обратная crypt
  procedure decrypt (plain: p128buf); stdcall; export;
  var
    a, b, c, d, delta, sum, r, t: longword;
  begin
    // ------------- поскипано --------------
  end;

  //*** копирует 32 байта (256 бит) из адреса k в текущий ключ
  //*** то есть просто как бы присваивание ключа
  procedure setup (k: pointer); stdcall; export;
  begin
    move(k^, key, 32);
  end;

exports
  crypt,
  decrypt,
  setup;

end.

Форум проекта "Минилаб-Мастер"


Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Вот спасибо-то, pumpkin!
Я правильно понимаю, что вместо массивов t128buf  p128buf можно сразу использовать plain? И что в нем содержатся исходные данные для зашифровки?

И конструкция b shl 4 проворачивает переменную B на 4 бита влево с потерей данных (необратимо?)
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
А вот еще вопрос назрел... Комада rol  - ассемблерная и крутит биты в регистрах. А в регистры данные загружаются задом наперед, как известно. А комада shl - это команда делфи, и крутит она байты тоже влево, но так как они не в регистрах, на самом деле =  направо.. Я правильно понимаю? В басгоме есть команда ROLL которая крутит биты у любой переменной по кругу, но в какую сторону круть, чтобы эмулировать ассемблерный roll? Ведь у avr контороллеров нет 32-х разрядных регистров....
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

pumpkin

  • Профи
  • ****
  • Сообщений: 240
  • Карма: 2
  • Пол: Мужской
  • Это Я :-)
    • Просмотр профиля
Цитировать
Я правильно понимаю, что вместо массивов t128buf  p128buf можно сразу использовать plain? И что в нем содержатся исходные данные для зашифровки?
Да, это просто массив из 4-х DWORD-ов (longword-в), ему и поинтеру на него просто дали имена, чтоб, пердавать масив в качестве аргумента в функцию. Не знаю, есть ли в баскоме такая конструкция, но это типа Dim plain(4) as Longword

Цитировать
И конструкция b shl 4 проворачивает переменную B на 4 бита влево с потерей данных (необратимо?) 
Да, это сдвиг. Слева 4 бита пропадают навсегда, справа 4 бита нулей добавляются.

Цитировать
А вот еще вопрос назрел... Комада rol- ассемблерная и крутит биты в регистрах. А в регистры данные загружаются задом наперед, как известно. А комада shl - это команда делфи, и крутит она байты тоже влево, но так как они не в регистрах, на самом деле =направо.. Я правильно понимаю? В басгоме есть команда ROLL которая крутит биты у любой переменной по кругу, но в какую сторону круть, чтобы эмулировать ассемблерный roll? Ведь у avr контороллеров нет 32-х разрядных регистров.... 
ROL крутит налево, ROR крутит напрво. И крутят они (как и shl/shr) биты, расположенные в человеческом понимании, так что задумываться о big endian или little endian не нужно.

pumpkin

  • Профи
  • ****
  • Сообщений: 240
  • Карма: 2
  • Пол: Мужской
  • Это Я :-)
    • Просмотр профиля
1. Вначале заносишь в key 256-битный (32 байта = 8 лонгуордов) ключ.
2. Закидываешь очередные 128 бит (4 лонгуорда)  исходных данных в plain и после шифрации извлекаешь из него зашифрованные данные.
3. Повторяешь п.2 пока не закончатся исходные данные.

Но одинаковые входные блоки данных будут шифроваться в одинаковые выходные. Если хочешь избежать этого (если считаешь это критичным), то надо шифровать блоки не независимо, а использовать иной режим (не "простой замены"). Вот здесь режимы расписаны http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B6%D0%B8%D0%BC_%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"

Спасибо огромное, оперативно... :-)

В баскоме нельзя делать такие длинные конструкции как
A = A +(((b Shl 4) + Rol(key[(sum Mod 4) + 4] , B)) Xor(d + Sum) Xor((b Shr 5) + Rol(key[sum Mod 4] , B Shr 27)));
Одна операция - одна строка. Тут вроде все понятно, кроме того что между математическими функщиями  Xor нет математических знаков.  )) Xor(d + Sum) Xor((b Shr 5) + Rol. Там умножение подрозумевается или как?
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

Форум проекта "Минилаб-Мастер"