A S-box de Rijndael é uma operação frequentemente usada na criptografia e descriptografia AES . Geralmente é implementado como uma tabela de pesquisa de 256 bytes. Isso é rápido, mas significa que você precisa enumerar uma tabela de pesquisa de 256 bytes no seu código. Aposto que alguém nesta multidão poderia fazê-lo com menos código, dada a estrutura matemática subjacente.
Escreva uma função no seu idioma favorito que implemente a S-box de Rijndael. O menor código vence.
code-golf
math
cryptography
Keith Randall
fonte
fonte
Respostas:
Ruby, 161 caracteres
Para verificar a saída, você pode usar o seguinte código para imprimi-lo em forma de tabela:
fonte
GolfScript, 60 caracteres
Esse código define uma função nomeada
S
que recebe um byte e aplica a caixa S de Rijndael. (Ele também usa uma função auxiliar interna chamadar
para salvar alguns caracteres.)Essa implementação usa uma tabela de logaritmo para calcular os inversos GF (2 8 ), conforme sugerido por Thomas Pornin . Para salvar alguns caracteres, toda a tabela de logaritmos é recalculada para cada byte de entrada; mesmo assim, e apesar do GolfScript ser uma linguagem muito lenta em geral, esse código leva apenas 10 ms para processar um byte no meu laptop antigo. O pré-cálculo da tabela de logaritmo (as
L
) acelera-a para cerca de 0,5 ms por byte, ao custo modesto de mais três caracteres:Por conveniência, aqui está um equipamento de teste simples que chama a função
S
, conforme definido acima, para calcular e imprimir toda a caixa S em hexadecimal, como na Wikipedia :Experimente este código online.
(A demonstração on-line pré-calcula a tabela de logaritmo para evitar muito tempo. Mesmo assim, o site GolfScript on-line às vezes pode exceder o tempo limite; esse é um problema conhecido do site, e uma atualização geralmente o corrige.)
Explicação:
Vamos começar com o cálculo da tabela de logaritmos e, especificamente, com a função auxiliar
r
:Essa função recebe duas entradas na pilha: um byte e uma máscara de bits de redução (uma constante entre 256 e 511). Duplica o byte de entrada, multiplica a cópia por 2 e, se o resultado exceder 255, XORs com a máscara de bits para trazê-lo de volta para 256.
Dentro do código de geração da tabela de log, a função
r
é chamada com a máscara de bits de redução 283 = 0x11b (que corresponde ao polinômio de redução de Rijndael GF (2 8 ) x 8 + x 4 + x 3 + x + 1) e o resultado é XOR com o byte original, multiplicando-o efetivamente por 3 (= x + 1, como um polinômio) no campo finito de Rijndael. Essa multiplicação é repetida 255 vezes, iniciando no byte 1, e os resultados (mais um byte zero inicial) são coletados em uma matriz de 257 elementosL
que se parece com isso (parte do meio omitida):A razão pela qual existem 257 elementos é que, com o 0 precedido e o 1 ocorrendo duas vezes, podemos encontrar o inverso modular de qualquer byte dado simplesmente pesquisando seu índice (com base em zero) nessa matriz, negando-o e procurando o byte no índice negado na mesma matriz. (No GolfScript, como em muitas outras linguagens de programação, os índices negativos da matriz contam para trás a partir do final da matriz.) Na verdade, é exatamente isso que o código
L?~)L=
no início da funçãoS
faz.O restante do código chama a função auxiliar
r
quatro vezes com a máscara de bit de redução 257 = 2 8 + 1 para criar quatro cópias com rotação de bits do byte de entrada invertido. Todos eles são coletados em uma matriz, juntamente com a constante 99 = 0x63, e XORed juntos para produzir a saída final.fonte
x86-64 Código da máquina -
23 22 2019 bytesUsa o conjunto de instruções AES-NI
O uso de convenções de chamada do Windows recebe um byte e gera um byte. Não é necessário reverter o valor
ShiftRows
, pois isso não afeta o primeiro byte.fonte
A tabela pode ser gerada sem computar inversos no campo finito GF (256), usando logaritmos. Seria assim (código Java, usando
int
para evitar problemas com obyte
tipo assinado ):A idéia é que 3 é um gerador multiplicativo de GF (256) *. A tabela
t[]
é tal quet[x]
é igual a 3 x ; desde 3 255 = 1, obtemos esse 1 / (3 x ) = 3 255-x .fonte
0x1B
(um 1 no literal hex) em vez de0x11B
int
tipo é de 32 bits em Java; Eu devo cancelar a parte superior.GolfScript (82 caracteres)
Usa variáveis globais
A
eB
, e cria a função como variável globalS
.A inversão de Galois é força bruta; Eu experimentei ter uma
mul
função separada que poderia ser reutilizada para a transformação afina pós-inversão, mas acabou sendo mais cara devido ao comportamento diferente do estouro.Isso é muito lento para uma demonstração on-line - atingia o tempo limite até nas duas primeiras linhas da tabela.
fonte
Python, 176 caracteres
Esta resposta é para a pergunta-comentário de Paŭlo Ebermann sobre tornar a função constante. Este código se encaixa na conta.
fonte
d
isso pode gerar a tabela de pesquisa em tempo de compilação, eu poderia economizar alguns tornando o ubyte um parâmetro genérico
edite diretamente
ubyte
para,ubyte
sem pesquisas de array, sem ramificações e loops totalmente desenroláveisedit2 usou o algo do @Thomas para criar a tabela de pesquisa
fonte
Stax , 53 bytes
Execute e depure
Eu não tenho nenhum entendimento particular de S-boxes. Esta é uma conversão da solução de Thomas Pornin (8 anos!) .
fonte