C # — Реализация RC4 на ракетке

Я пытаюсь перевести реализацию C4 шифра RC4, который я написал, на язык Racket.

Тем не менее, они производят разные ключевые потоки. Я уже исключил возможность неправильного написания фазы планирования ключей; это должно быть правильно, так как они приводят к одному и тому же массиву S, Таким образом, я сосредоточен на поиске различий на этапе генерации ключевого потока.

C #:

public int Dencode (int c)
{
I = (I + 1) % 256;
J = (J + S [I]) % 256;
int tmp = S [I];
S [I] = S [J];
S [J] = tmp;
return S [(S[I] + S[J]) % 256] ^ c;
}

Ракетка:

(define (toret c)
(set! i (unsafe-fxmodulo (add1 i) 256))
(set! j (unsafe-fxmodulo (add1 (Sr i)) 256))
(swap! (box (Sr i)) (box (Sr j)))
(bitwise-xor (Sr (unsafe-fxmodulo (+ (Sr i) (Sr j)) 256)) c))

с swap определяется как

(define (swap! ba bb)
(define temp (unbox ba))
(set-box! ba (unbox bb))
(set-box! bb temp))

а также Sr определяется как (define (Sr x) (unsafe-bytes-ref S x)),

В чем разница? Почему эти функции выдают разные результаты? В обоих случаях i а также j инициализируются до 0, и S является идентичным 256-байтовым массивом.

1

Решение

Линия

(swap! (box (Sr i)) (box (Sr j)))

не будет делать то, что вы ожидаете. Это не делает волшебно (Sr i) а также (Sr j) изменчивые ссылки. swap! процедура меняет содержимое ящиков — но ящики содержат (Sr i) а также (Sr j) по значению, а не по ссылке.

Что вам нужно сделать, это изменить свой swap! процедура использования unsafe-bytes-set! вместо.


Вот некоторый код, чтобы продемонстрировать мою точку зрения:

#lang racket
(require racket/unsafe/ops)

(define (box-swap! x y)
(define tmp (unbox x))
(set-box! x (unbox y))
(set-box! y tmp))

(define (wrong-swap! bs x y)
(box-swap! (box (unsafe-bytes-ref bs x))
(box (unsafe-bytes-ref bs y))))

(define (right-swap! bs x y)
(define tmp (unsafe-bytes-ref bs x))
(unsafe-bytes-set! bs x (unsafe-bytes-ref bs y))
(unsafe-bytes-set! bs y tmp))

Пример:

> (define bs (bytes 1 2 3 4 5 6))
> bs
#"\1\2\3\4\5\6"> (wrong-swap! bs 0 5)
> bs
#"\1\2\3\4\5\6"> (right-swap! bs 0 5)
> bs
#"\6\2\3\4\5\1"
1

Другие решения

Произошла очень глупая ошибка. (set! j (unsafe-fxmodulo (add1 (Sr i)) 256)) не эквивалентно J = (J + S [I]) % 256;! Добавление отладочных строк printf после каждого оператора очень помогло.

-1

По вопросам рекламы [email protected]