|
|
  |
Полином для вычисления обратной CRC, Из CRC получить исходный код |
|
|
|
Mar 16 2015, 09:08
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Имею идею шифровать код прошивки с помощью CRC. Конкретно, декодировать его с помощью встроенной в STM32F2xx CRC-32 с полиномом: X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2+ X +1 То есть, каждое исходное слово заменяется CRC, вычисленной с его участием, следующее слово заменяется следующей CRC. Вопрос, как закодировать, чтобы после декодирования получить исходный код? Каким полиномом? Думаю, перекрутить 32 в 1, и т. п. Пока читаю пару статей о CRC, может, кто-то уже знает точный ответ?
|
|
|
|
|
Mar 16 2015, 13:12
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Пытаюсь понять на простом примере. Вот в этом калькуляторе http://www.zorc.breitbandkatze.de/crc.htmlзадаю полином 8 порядка 100000111 (hex 7), все реверсы убираю, для данных 0 получаю результат 0x90. Никак, деля вручную, не могу получить. Получается 0xFD. upd. Ага, вышло, когда посчитал на бумаге не для 0, а для 0x30 ('0'). Значит, в строке Data sequence задаются символы. Ух... Вот эта программа помогла понять. Там свои тараканы. http://depa.usst.edu.cn/chenjq/www2/softwa...calculation.htmЦитата(yes @ Mar 16 2015, 15:32)  может я что-то непонимаю - но не уверен, обратима ли эта операция? Обратима, так как основана на xor. Похоже, если задать данные 0x01, то CRC выдаст результат, равный ее полиному (без старшего разряда. Так, как она описывается в форме 0xXXXX). CRC-08(0x01) = 0x07. А если задать данные, равные полиному (вместе со старшим битом), то CRC равна 0. Для верхнего примера CRC-08(0x0107) = 0.
|
|
|
|
|
Mar 16 2015, 14:19
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(ViKo @ Mar 16 2015, 16:12)  Обратима, так как основана на xor. То, что она основана на XOR, не говорит о том, что одному выходному значению строго соответствует одно входное при любых начальных условиях. И, кстати, это, действительно, не факт. Я даже подозреваю обратное, по причине того, что при делении на полином, имеющий максимальную степень, равную размеру слова, но имеющий еще компоненты меньших степеней, остаток может содержать этот самый старший бит, который реально отбрасывается, а может и не содержать. При этом оставшиеся биты могут быть одинаковыми.
|
|
|
|
|
Mar 16 2015, 14:21
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(SM @ Mar 16 2015, 17:19)  То, что она основана на XOR, не говорит о том, что одному выходному значению строго соответствует одно входное при любых начальных условиях. И, кстати, это, действительно, не факт. Это зависит от длины данных. Думаю, если данные короче или равны размеру полинома, то будет однозначное соответствие. Я так и хочу использовать. Пример из обычной математики - если имеем байт, то остаток от деления байта на 256 будет однозначно определять исходные данные.
|
|
|
|
|
Mar 16 2015, 14:39
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(ViKo @ Mar 16 2015, 17:31)  Без инициализации, только в самом начале однажды (это слово инициализации и будет главным секретом). Вот поэтому однозначности точно не будет. Для начального значения, равному нулю (даже не FFFFFFF, а именно нулевой остаток), я допускаю, что однозначность имеется. Но для любых других начальных условий однозначности, на сколько я понимаю, не будет. Ведь добавление очередных 32 бит - это домножение полинома, соответствующего всем предыдущим данным, на полином, соответствующий этим 32 битам. То есть, был, например, полином 1536-го порядка, после обработки 48 слов, и стал 1568-го порядка. И, вроде как, никакой гарантии нет, что не будет двух одинаковых остатков для двух разных домножений для каждого из слов, кроме самого первого после инициализации. Я не могу строго это доказать, но чисто интуитивно уверен, что для каких-то определенных данных, прошедших перед текущим данным, однозначности не будет по причине того, что полином имеет степень, равную длине слова, и компоненты, меньшие этой степени.
|
|
|
|
|
Mar 16 2015, 14:47
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
А мне интуиция говорит, что, поскольку я имею те же объемы исходной и выходной информации, то и восстановить его я могу. Я пропускаю через некую числомолотилку - регистр с обратными связями и исключающими или поток битов. Если я результирующий поток пропущу через некую реверсную числомолотилку, то получу исходный поток.
Пораскинув мозгами, не нахожу достаточной стойкости данного способа ко взлому. Допустим, кого-то осенит, или подслушает, или купит, принцип действия. А дальше - подобрать начальное значение, и все. Не проще ли заксорить массив каким-нибудь длинным выражением, которое подбирать замучаешься?
Разве что, для общего развития, сотворить.
|
|
|
|
|
Mar 16 2015, 15:25
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(ViKo @ Mar 16 2015, 17:47)  А мне интуиция говорит, что, поскольку я имею те же объемы исходной и выходной информации, то и восстановить его я могу. Для сравнения, чтобы более понятно было. А то деление полиномов для Вас это, видимо, некий "космос". А я вот приземленный пример приведу. С алгебраическим делением, имеющим все те же свойства, что и деление полиномов. Допустим, размер 8 бит, а генерирующий полином соответствует числу 311 (оно простое, что эквивалентно примитивности полинома). Начальное значение 0. Считаем просто - в начале в некоем аккумуляторе 1. Каждое последующее число домножается к аккумулятору (и в нем остается произведение) - это эквивалент домножения текущего полинома данных на полином, соответствующий новому байту, после чего находится остаток от деления на 311, после чего из него берется 8 бит (еще один остаток от /256) - это алгебраический эквивалент CRC (с точки зрения обратимости операций, а не числового результата. входные данные: 22 -> 22 33 -> 104 44 -> 222 11 -> 9 и еще: 22 -> 22 33 -> 104 44 -> 222 248 -> 9 получите гранату - числу 9 соответствует два варианта входной последовательности. Цитата(ViKo @ Mar 16 2015, 17:47)  Не проще ли заксорить массив каким-нибудь длинным выражением, которое подбирать замучаешься? Есть очень простой (на ксорах) и вполне стойкий шифр - TEA, XTEA. В конце концов, если самосинхронизирующиеся скремблеры, у них реализация похожа на CRC. ------------------ UPD: Я неправильно сделал эквивалент формирования входного полинома данных. Для каждого следующего байта аккумулятор должен домножаться на 256 (на x^8) и прибавляться данное. А не домножать аккумулятор на данноею Вот правильный пример: Код байт аккумулятор "типа-CRC-делением" 22 22 22 33 5665 67 44 1450284 91 11 371272715 37 и второй вариант Код байт аккумулятор "типа-CRC-делением" 22 22 22 33 5665 67 44 1450284 91 66 371272770 37 Смысл тот же, числу 37 после таких входных данных, 22 33 и 44, соответствует два варианта - 11 или 66.
|
|
|
|
|
Mar 16 2015, 15:28
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(SM @ Mar 16 2015, 18:14)  Каждое последующее число домножается к аккумулятору (и в нем остается произведение) - это эквивалент домножения текущего полинома данных на полином... Вот здесь, по-моему, кроется ошибка. Мы не перемножаем числа, а сдвигаемся. Как по длинному числу, потоку. То есть, разбили поток на слова, чтобы хранить его в массиве. А при расчете CRC с сохранением предыдущего результата (без инициализации) мы бит выдвинули, бит задвинули. Только результат выдаем сразу для целого слова этих битов. По поводу UPD - у вас аккумулятор безразмерный, растет и растет число в нем...  Надо от старья избавляться. Приведите пример нормальный, "космический". Простейший, CRC-4: x4 + x1 + 1
|
|
|
|
|
Mar 16 2015, 15:37
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(ViKo @ Mar 16 2015, 18:28)  Надо от старья избавляться. CRC то не избавляется. CRC - это остаток от деления полинома, представляющего все входные данные, от момента инициализации. Поэтому в таком эквиваленте следует иметь безразмерный аккумулятор. И поэтому в CRC будут аналогичные "дубли", зависящие от всех предыдущих данных. Засада кроется не в обрезании "полинома данных" - сделать, как бы, CRC со скользящим окном, а именно в том, что генерирующий полином имеет единицу в разряде, на 1 старше, чем размер CRC. (этот бит для любого полинома = 1, и обычно скрыт, так как вроде как, лишний, в расчете непосредственно не участвует )
|
|
|
|
|
Mar 16 2015, 15:50
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(SM @ Mar 16 2015, 18:37)  CRC то не избавляется. CRC - это остаток от деления полинома, представляющего все входные данные, от момента инициализации. Избавляется. Старший бит породил остаток и улетел в космос. Я ведь не последний результат расчета CRC использую. А все, что рассчитал. Представьте, выполнил один первый раз, получил CRC. Могу я выполнить обратное действие, получить исходное слово? Очевидно, могу. На этом о том исходном слове забываю, как будто и нет его. Дальше вычисляю... в-общем, рекурсия, наша песня хороша... только выполнить ее нужно задом наперед при кодировании, чтобы при аппаратном декодировании передом назад все летало.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|