UM IP DE CRIPTOGRAFIA PADRÃO RIJNDAEL PARA PROJETOS EM FPGA Marcelo B. de Barcelos, Alex F. Panato, Ricardo A. da Luz Reis mb@e-trust.com.br panato@inf.ufrgs.br reis@inf.ufrgs.br Universidade Federal do Rio Grande do Sul - UFRGS Instituto de Informática Cx. Postal 15064 - Av. Bento Gonçalves, 9500 - Campus do Vale - Bloco IV CEP 91501-970, Porto Alegre - RS - Brasil RESUMO Este trabalho visa apresentar a implementação um IP para encriptação e decriptação de dados, segundo o padrão AES- 128 (algoritmo Rijndael), eleito pelo NIST (National Institut of Standards and Technology) como novo padrão para criptografia simétrica. Foram desenvolvidas duas arquiteturas em lógica programável Altera, usando linguagem VHDL. O uso de hardware provê desempenho adequado para diversas implementações, nas quais o uso de software não atinge os requisitos necessários. Propomos duas arquiteturas: uma para alto desempenho e uma segunda visando economia de área. Os resultados obtidos para os dispositivos utilizados encontram-se entre os melhores encontrados na literatura atual. 1. INTRODUÇÃO Em 12 de setembro de 1997, o NIST requisitou propostas para o chamado Advanced Encription Standard (AES) [01][02]. Muitos algoritmos foram apresentados na primeira etapa, com propostas de mais de 12 países. Foram selecionados 15 algoritmos para a primeira etapa [03]. Na segunda etapa, foram cinco os concorrentes, na qual o NIST aprimorou a análise de cada proposta, estimulando um ataque para todos os competidores [04]. Os algoritmos presentes foram:?mars [05]?RC6 [06]?RIJNDAEL [07]?SERPENT [08]?TWOFISH [09] Inicialmente, a conclusão era que os cinco competidores apresentavam características similares. Em 2 de outubro, o NIST anunciou o algoritmo Rijndael como vencedor do concurso, dado suas melhores qualificações em termos de segurança, desempenho, eficiência, facilidade de implementação e flexibilidade. [10] O algoritmo Rijndael foi desenvolvido por Joan Daemen, da Proton World International, e Vincent Fijmen, da Katholieke Universiteit Leuven [11]. O Rijndael é um algoritmo simétrico com chaves de 128, 192 e 256 bits e blocos cifrados de 128, 192 e 256 bits também. A natureza do algoritmo permite que o tamanho das chaves e dos blocos seja múltiplo de 32 bits. [11] O objetivo da implementação em hardware programável é prover alto poder de processamento para aplicações dedicadas, como servidores web, nos quais o uso intenso de criptografia produz uma queda significativa de desempenho quando usadas alternativas em software. O chip de baixo custo encontra utilidade em servidores locais de rede, permitindo, aproximadamente, 26MB/s de saída de dados encriptados/decriptados sem perda significativa de desempenho no servidor. Autor Throughput Throughput Plataforma Encriptação Decriptação [12] 68,4 Mbps 72,7 Mbps Código C, rodando em um Pentium Pro 200 MHz. [13] 254 Mbps 254 Mbps Código C, rodando em um Celeron 850 MHz. [14] 268 Mbps* 248 Mbps* Código VHDL sobre um FPGA Altera Flex10K. [15] 271 Mbps 272 Mbps Código C, rodando em um Pentium III 800 MHz. [16] 414 Mbps* 414 Mbps* Código VHDL sobre um FPGA Xilinx Virtex. [17] 605 Mbps* 605 Mbps* Código VHDL sobre um ASIC 0,5 um. * Arquitetura interativa Tabela 1 Desempenho para diferentes implementações em software e hardware.. O algoritmo Rijndael consiste, basicamente, do uso de
funções de soma, deslocamentos e substituições de bytes. São diversas rodadas (rounds), cada uma delas usando as seguintes funções: Byte_Sub (substituição de bytes), Shift_Row (deslocamento de linhas), Mix_Column (deslocamento de colunas) e Add_Key_F (soma de dados) ou suas inversas, Ibyte_Sub, IShift_Row, IMix_Column e Add_Key_F (que é sua própria inversa), no primeiro caso para encriptação e no segundo para decriptação. Muitos outros trabalhos foram desenvolvidos sobre o Rijndael. Na Tabela 1, apresentamos alguns resultados da implementação do algoritmo em hardware e software encontrados na literatura. 2. IMPLEMENTAÇÃO DO AES-128 De acordo com a definição do NIST, o padrão AES usa o algoritmo Rijndael com blocos de dados de 128 bits e chave de 128, 192 e 256 bits. Este trabalho, utilizando componentes Altera, faz uso apenas da versão com chave de 128 bits, chamada AES-128. Utilizamos a linguagem VHDL para a descrição do IP de Criptografia. Como ambiente de desenvolvimento, foram utilizados as ferramentas Leonardo Spectrum v2001_1a.28 e Max+Plus2 10.0. O primeiro foi utilizado para a escrita, correção e otimização do código. O segundo foi utilizado para fitting, simulação e análise dos resultados de desempenho. É importante ressaltar que houve discrepância entre os resultados de clock sugerido pelo Leonardo Spectrum e clock mínimo aceito pelo Max+Plus2, sendo os resultados do primeiro muito mais otimistas. Como a análise dos resultados é possível apenas no Max+Plus2, nossos resultados apresentam desempenho inferior ao estimado pelo Leonardo Spectrum, assim, o chip pode fornecer resultados melhores do que os apresentados neste trabalho. Foram desenvolvidas duas arquiteturas diferentes. A primeira visa obter um alto poder de processamento, a custa de uma utilização maior de área. A segunda visa baixar ao máximo a ocupação de área, permitindo um desempenho satisfatório para a aplicação. Na arquitetura voltada para desempenho, foi possível a implementação usando apenas um dispositivo da família FLEX10KA, o FLEX10KA250, devido a necessidade de memória da função Byte_Sub. A utilização da memória embutida no chip foi de 100% (cerca de 40kbytes), mas o uso de logic cells (LC's) foi de apenas 40%. O uso de memória é alto, pois o Rijndael utiliza intensamente substituição de bytes e estamos considerando uma aplicação plena em 128 bits. Infelizmente, não há nesta família um dispositivo com igual memória, mas com um menor número de LC's, permitindo uma maior homogeneidade. Assim, tem-se uma grande quantidade de área sem utilização nesta solução em FPGA. É importante lembrar que o foco de otimização desta arquitetura foi sempre o desempenho. Na versão do dispositivo focado em área, existiam diversas opções. A única exigência era um processamento de 32 bits para a função de substituição de bytes, diminuindo a necessidade de área embutida no chip. O primeiro dispositivo elaborado foi um de 128 bits de entrada e 128 bits de saída, com um processamento interno de 32 bits. O segundo possuía 32 bits de entrada, 128 bits de saída e 32 bits de processamento interno. O terceiro procurou diminuir ainda mais o número de pinos usados, tendo 32 bits de entrada, 32 de saída e processamento interno de 32 bits. O primeiro não demonstrou um ganho significativo de desempenho, apesar de utilizar mais pinos de I/O. O segundo mostrou um desempenho satisfatório e um menor uso de pinos de I/O. O terceiro apresentava uma complicação desnecessária para controle e comunicação com o processador mestre do barramento, o que o levou a ser descartado. Para o uso da função de substituição de bytes de 32 bits, são necessários 16kbytes de memória embutida, o que limita o dispositivo ao uso de um FLEX10KA50. Dispositivos menores, como o FLEX10KA30, possuem um número suficiente de LC's, mas não dispõem de memória para a implementação desta arquitetura. Tendo em vista esta sobra de LC's no FPGA, foi possível programar o Leonardo Spectrum para otimização de desempenho nesta proposta também. Por este motivo, também, é desnecessário o uso de soluções com um menor número de pinos como a terceira proposta elaborada para este IP. De fato, a utilização do componente mostrada anteriormente considerava apenas a parte referente a encriptação, seja na arquitetura de 128 ou 32 bits. A decriptação consome uma quantidade de recursos ligeiramente maior e produz resultados iguais ou inferiores, devido a diferença entre as funções Mix_Column e Imix_Column. Assim, nosso trabalho produziu quatro dispositivos, dois para encriptação e dois para decriptação, nas versões área e desempenho. Considerando o código VHDL, há uma clara diferença entre as versões visando desempenho ou área. Entretanto, decidimos unificar o pacote base, contendo todas as funções, variáveis, tipos e descrição das memórias para as duas versões, o que nos garantiu uma flexibilidade interessante para alterações e ensaios de outras arquiteturas ainda em estudo. Nas duas arquiteturas, decidimos manter a mesma interface, com os mesmos pinos (exceto por pequenas diferenças advindas de particularidades de cada arquitetura) e sistema de operação. Desta forma, a utilização dos dispositivos foi padronizada, facilitando sua operação. 3.1. Dispositivo 128 bits 3. INTERFACE Recebe os dados a serem encriptados/decriptados, bem como a chave, em 128 bits. Sua saída apresenta dados criptografados diretamente em 128 bits. É utilizado o chip da Altera EPF10K250AGC599-1, com 470 pinos de I/O, 12160 LC's e 40960 bits de RAM embutida. Decriptador e encriptador usam um FPGA cada. A entrada é dividida para dados e chave. Cada uma toma 128 bits por vez, armazenando-os em uma variável matricial de 4 por 4 palavras de 8 bits (state_t), totalizando 128 bits. Todo o processamento é feito inteiramente sobre os 128 bits da variável. A operação de leitura armazena a entrada de dados em uma variável, que é lida pela variável de trabalho do processo Rijndael. A saída é feita transferindo-se os dados da variável de trabalho para uma variável que armazena o dado de saída, garantindo a estabilidade para leitura dos dados pelo processador. As round keys são armazenadas em uma variável de 10 vetores de 4 linhas por 4 colunas de 8 bits, ou seja, um vetor de dez componentes state_t. A chave de entrada é armazenada no primeiro dos componentes e as demais são geradas através dele. Isto garante que a variável de armazenagem seja usada no processo Rijndael sem que tenha de ser remapeada.
Nome Tipo Descrição CLK IN Clock de geração da chave. CLK2 IN Clock do processo Rijndael. SETUP IN Determina período de operação. WR_KEY IN Indica que a chave está no barramento. WR_DATA IN Indica que o dado está no barramento. KEYIN IN Entrada da chave em 128 bits. DATAIN IN Entrada de dados em 128 bits. KEY_OK OUT Indica que todas as chaves foram geradas. DATA_OK OUT Permissão de leitura/escrita no barramento. DATAOUT OUT Saída de dados em 128 bits. Tabela 3.1 Pinagem dos dispositivos 128 bits. O sinal SETUP indica os dois modos de funcionamento do dispositivo, ou seja, com o sinal ativado o processo de encriptação/decriptação não roda e, quando desativado, é executado o processamento do algoritmo. Desta forma, a entrada da chave e do dado inicial, deve ser realizada com o SETUP alto, mas a entrada de novos dados deve ser feita com o SETUP baixo. Para escrever um dado, deve-se acionar o sinal WR_DATA, mantendo WR_KEY baixo. Para escrita da chave, WR_KEY deve estar alto e WR_DATA baixo. Para interromper o uso do dispositivo, basta usar o modo inativo do SETUP, ou seja, sinal alto. Assim, novos dados não são processados. Isto deve ser feito logo após a leitura do último dado de interesse enviado ao dispositivo. Para retomar seu funcionamento, basta escrever um dado novo acionando o sinal WR_DATA, mantendo o sinal SETUP alto. Após a escrita do dado, o sinal SETUP deve ser desativado e a operação retomada ao modo convencional. O dispositivo indica que colocou o resultado de seu processamento no barramento através do sinal DATA_OK. Quando ocorre sua borda descendente, a leitura do dado de saída pode ser realizada. A borda de subida indica que o dispositivo está apto a ler um novo dado de entrada no barramento. O sinal KEY_OK indica quando a formação do vetor de round keys está concluído. É recomendado que o processamento não comece antes deste sinal ser um zero lógico, ou seja, que o sinal SETUP permaneça alto. 3.2. Dispositivo 32 bits Recebe os dados a serem encriptados/decriptados, bem como a chave, em 32 bits. Sua saída apresenta dados criptados/decriptados diretamente em 128 bits. É utilizado o chip da Altera EPF10K50VBC484-1, com 291 pinos de I/O, 2880 LCs e 20480 bits de RAM embutida. Decriptador e encriptador usam um FPGA cada. A entrada de dados toma 32 bits por vez, armazenandoos em uma variável matricial de 4 por 4 palavras de 8 bits, totalizando 128 bits. Toda a operação, tanto de leitura quanto de processamento de dados, é executada sobre as linhas desta variável, exceto pela função Mix_Column, que age sobre as colunas. A leitura da entrada é composta por quatro estados, cada um responsável pela leitura e armazenamento de uma etapa de 32 dos 128 bits totais. A entrada é compartilhada entre dados e chave, permitindo uma redução ainda maior no número de pinos de I/O utilizados. A saída, para evitar uma redução grande de desempenho, utiliza 128 bits diretamente. Nome Tipo Descrição CLK IN Clock comum a todos os blocos. SETUP IN Determina período de operação. WR_KEY IN Indica que a chave está no barramento. WR_DATA IN Indica que o dado está no barramento. AIN IN Indica qual dos pacotes está no barramento. DIN IN Entrada para chave e dados em 32 bits. DATA_OK OUT Permissão de leitura/escrita no barramento. DATAOUT OUT Saída de dados em 128 bits. Tabela 3.2 Pinagem dos dispositivos 32 bits. O sinal SETUP indica os dois modos de funcionamento do dispositivo, ou seja, com o sinal ativado o processo de encriptação/decriptação não roda e, quando desativado, o processamento do algoritmo é feito. Desta forma, a entrada da chave e do dado inicial, deve ser realizada com o SETUP alto, mas a entrada de novos dados deve ser feita com o SETUP baixo. Para escrever um dado, deve-se acionar o sinal WR_DATA, mantendo WR_KEY baixo. Para escrita da chave, WR_KEY deve estar alto e WR_DATA baixo. Os dados e chave são recebidos em pacotes de 32 bits e sua ordem correta é determinada pelo sinal AIN. Assim, para receber o primeiro pacote, deve-se indicar o valor 00 em AIN. Para interromper o uso do dispositivo, basta usar o modo inativo do SETUP, ou seja, sinal alto. Assim, novos dados não são processados. Isto deve ser feito logo após a leitura do último dado de interesse enviado ao dispositivo. Para retomar seu funcionamento, basta escrever um dado novo acionando o sinal WR_DATA, mantendo o sinal SETUP alto. Após a escrita do dado, o sinal SETUP deve ser desativado e a operação retomada ao modo convencional. O dispositivo indica que colocou o resultado de seu processamento no barramento através do sinal DATA_OK. Quando ocorre sua borda descendente, a leitura do dado de saída pode ser realizada. A borda de subida indica que o dispositivo está apto a ler um novo dado de entrada no barramento. 4.1. Dispositivos 128 bits 4. ARQUITETURA DO PROJETO Nesta arquitetura são executados paralelamente quatro processos. Desta forma, é garantida uma separação adequada no tratamento de cada dado. Figura 4.1 Diagrama do dispositivo 128 bits.
O processo Data_In, de uma forma geral, é responsável pela recepção dos dados de entrada, sejam eles o texto não cifrado (texto a ser encriptado) ou o texto cifrado (texto a ser decriptado). Ele toma 128 bits de entrada de dados e armazena em uma variável específica. O processo é ativado pelo sinal WR_DATA, que indica ao dispositivo que há um dado pronto para ser lido no barramento. A independência deste processo junto ao corpo geral permite que a leitura do dado de entrada seja feita durante o processamento do dado anterior, ou seja, não é perdido tempo de processamento neste processo. No caso do decriptador, este processo realiza, também, a função Add_Key_F inicial. Data_In) e indicado o acionamento do sinal DATA_OK. O processo de saída simplesmente realiza a interface de saída de dados. Ele aciona os sinais DATA_OK e KEY_OK, quando solicitado por instruções internas do processo Rijndael. Sua função mais importante, contudo, é garantir a estabilidade da saída ao longo de todo o processo, ou seja, ela será alterada somente quando existir uma nova saída para ser exibida. Figura 4.3 Diagrama de decriptação Rijndael. 4.2. Dispositivos 32 bits Figura 4.2 Diagrama de encriptação Rijndael. O processo Key_In é responsável pela recepção da chave, seu armazenamento e geração das round keys que serão usadas ao longo de todos os rounds, ou seja, todas as round keys são geradas previamente e armazenadas para o uso de forma adequada. O processo é ativado pelo sinal WR_KEY. O processo Rijndael roda o algoritmo em 128 bits. É controlado pelo sinal SETUP, que determina seu funcionamento. No encriptador, a execução consiste na realização de uma Add_Key_F, seguido de uma Byte_Sub, de uma Shift_Row e, excetuando-se o round 9, quando não é executada, de uma Mix_Column. No round 9, ao invés da execução da Mix_Column, é transferida para a variável de trabalho o novo dado de entrada (já armazenado pelo processo Data_In) e indicado o acionamento do sinal DATA_OK. No decriptador, a execução consiste na realização de uma IByte_Sub, seguido de uma IShift_Row e, excetuando-se o round 0, quando não são executadas, de uma Add_Key_F e de uma Imix_Column (a Add_Key_F correspondente ao round final é realizada no processo de saída). No round 0, ao invés da execução da Mix_Column, é transferido para a variável de trabalho o novo dado de entrada (já armazenado pelo processo Há quatro processos sendo executados paralelamente nesta arquitetura Desta forma, é garantida uma separação adequada no tratamento de cada dado. Figura 4.4 Diagrama do dispositivo 32 bits. O processo Data_In é responsável pela recepção dos dados de entrada. Estes dados são fornecidos pelo barramento em pacotes de 32 bits, cuja ordem deve ser indicada ao sinal AIN, e armazena-os em uma variável temporária de 128 bits. O processo é acionado pelo sinal DATA_IN e é independente do processamento central, garantindo que um novo dado possa ser lido durante o processamento.
O processo Key_In é, neste caso, muito semelhante ao Data_In. As chaves, neste caso, são geradas uma a uma, em cada round, de acordo com a necessidade. O processo toma pacotes de 32 bits por vez, armazena a chave de entrada em uma variável fixa de 128 bits e lá permanece até que deseje-se trocá-la, já que, durante um processo de troca de dados, não é comum haver troca da chave. É acionado pelo sinal WR_KEY O processo Rijndael roda o algoritmo em 32 bits. É controlado pelo sinal SETUP, que determina seu funcionamento. É composto por quatro estados, responsáveis por determinadas funções, todos trabalhando sobre a mesma variável. A máquina de estados é mostrada nas figuras 4.5 (encriptador) e 4.6 (decriptador). O primeiro estado é executado apenas no primeiro round de funcionamento. É responsável pela Add_Key_F inicial. Além disso, ajusta valores corretos do round atual e alimenta a variável round_key com seu valor inicial, ou seja, o valor da chave de entrada. Na verdade, este processo é, por si só, todo o round 0. No caso do encriptador, a chave inicial deve ser a própria chave. No decriptador, contudo, a chave inicial deve ser a última das round keys, ou seja, deve ser fornecida pelo processador mestre do sistema. Este resultado facilita e otimiza a operação do dispositivo e gera apenas um cálculo básico e a necessidade de um pequena memória no processamento central, o que é realizado uma única vez, não sendo um elemento comprometedor de desempenho. Figura 4.6 - Máquina de estados decriptador 32 bits. 5.1. Dispositivo 128 bits 5. RESULTADOS A implementação usando o chip da Altera EPF10K250AGC599-1 apresenta uma ocupação irregular dos recursos do dispositivo. A memória é usada em sua totalidade, sendo pinagem é bastante exigida, mas há pouco uso de logic cells (LC's). Os resultados obtidos para os chips são os seguintes, para cada um dos dispositivos: Design Input Output Memory Bits LC's Throughput [MB/s] Período de CLK2 Mínimo [ns] ENC128 261 130 40960 4805 320 40 DEC128 261 130 40960 5016 256 50 Tabela 5.1. Resultados dos dispositivos de 128 bits Figura 4.5 - Máquina de estados encriptador 32 bits. O segundo estado é executado em todos os rounds. Consiste em realizar as funções Byte_Sub e Shift_Row sobre a variável de trabalho. Este estado, ainda, executa a formação da round_key para o round seguinte e aciona, via o processo Saída, o sinal DATA_OK, para avisar ao processador que um novo dado pode ser enviado ao barramento e que o dado processado seja lido. O terceiro estado é diferente para o encriptador e o decriptador. No primeiro caso, é executado em todos os rounds, a exceção do último, e consiste em realizar a função Mix_Column. No segundo caso, consiste na função Add_Key_F e é executado em todos os rounds. O quarto estado é executado em todos os rounds, mas a função a ser realizada varia para encriptador e decriptador. No primeiro caso, trata-se de uma Add_Key_F. Já no segundo, realiza-se uma função Mix_Column. A velocidade de processamento do dado depende do período de CLK2 (CLK não tem relevância direta para o desempenho), tendo em vista que há um número pré estabelecido de rodadas (dez etapas) e que cada round leva um período de CLK2. O melhor resultado obtido foi com o uso de um clock de 40 ns (25MHz) para o encriptador e de 50ns (20MHz) para o decriptador. Com o valor sugerido de CLK2, leva-se 400ns para uma encriptação completa de 128 bits. Estes valores permitem uma saída de dados de aproximadamente 320 MB/s. Já no decriptador, o ciclo leva 500ns, permitindo uma saída de 256 MB/s. 5.2. Dispositivo 32 bits A implementação com o chip da Altera EPF10K50VFC484-1 apresenta uma ocupação irregular no chip. A memória do dispositivo é usada em sua totalidade, a pinagem é bastante exigida, mas há muito pouco uso de logic cells (LC's). Os resultados obtidos para os chips são os seguintes, para cada um dos dispositivos: Design Input Output Memory Bits LC's Throughput [MB/s] Período de CLK Mínimo [ns] ENC32 38 129 16384 1980 26,4 40 DEC32 38 129 16384 2473 26,67 40 Tabela 5.2 Resultados dos dispositivos de 32 bits.
A velocidade de processamento do dado depende do período de CLK, tendo em vista que há um número pré estabelecido de rodadas e que cada etapa dura um período de clock. O melhor resultado obtido foi com uso de um clock de 40 ns (25MHz) para o encriptador e o decriptador. Com o valor sugerido de clock, leva-se 4,84us para um encriptação completa de 128 bits. Estes valores permitem uma saída de dados de aproximadamente 26,4 MB/s. Já no decriptador, o ciclo leva 4,8us, permitindo uma saída de aproximadamente 26,67 MB/s. 6. CONCLUSÃO O uso de alternativas de criptografia em hardware possui grande eficiência. Tanto resultados encontrados na literatura quanto os obtidos neste trabalho indicam um alto desempenho. A construção de uma arquitetura focada para economia de área parece ser pioneira e apresenta resultados satisfatórios com um custo pequeno. Tais alternativas podem constituir uma via promissora para aplicações que não exigem um desempenho crítico. A comparação dos resultados aferidos neste trabalho (e anteriores [18]) com os demais, encontrados na literatura, indicam um ótimo desempenho para a versão focada em poder de processamento, mostrando-se superior a todas as soluções propostas para dispositivos da família FLEX10KA. Após a implementação do código em famílias mais recentes, uma melhor análise será possível em relação a outros dispositivos FPGAs. O trabalho apresenta, ainda, diversas possibilidades a serem exploradas. Espera-se novos resultados em um futuro próximo. 7. REFERÊNCIAS [01] NIST. Advanced Encryption Standard (AES). Página oficial do NIST sobre o AES, disponível em http://csrc.nist.gov/encryption/aes [02] NIST. Overview of the AES Development Effort. Página oficial do NIST, discutindo a história do desenvolvimento, disponível em http://csrc.nist.gov/encryption/aes/index2.html#overview [03] NIST. AES Round 1 Information. Página oficial do NIST sobre os quinze (15) algoritmos selecionados para a primeira etapa do AES, disponível em http://csrc.nist.gov/encryption/aes/round1/round1.htm#algor ithms [04] NIST. AES Round 2 Information Página oficial do NIST sobre os cinco (5) algoritmos selecionados para a segunda etapa do AES, disponível em http://csrc.nist.gov/encryption/aes/round2/round2.htm#algor ithms (25 Ago. 2001) [05] IBM. The MARS cipher - IBM submission to AES. Página oficial do MARS, disponível em http://www.research.ibm.com/security/mars.html [06] RSA. RC6 Block Cipher. Página oficial do RC6, disponível em http://www.rsa.com/rsalabs/rc6/index.html [07] DAEMEN, Joan e RIJMEN, Pawel. The block cipher Rijndael. Página oficial do Rijndael, disponível em http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ [08] ANDERSON, Ross, BIHAM, Eli and KNUDSEN, Lars. Serpent - A Candidate Block Cipher for the Advanced Encryption Standard. Página oficial do SERPENT, disponível em http://www.cl.cam.ac.uk/~rja14/serpent.html [09] COUNTERPANE. Twofish: A New Block Cipher. Página oficial do TWOFISH, disponível em http://www.counterpane.com/twofish.html [10] NIST. Commerce Department Announces Winner of Global Information Security Competition. Comunicado oficial, informando que o Rijndael é o novo padrão AES, disponível em http://www.nist.gov/public_affairs/releases/g00-176.htm (25 Ago. 2001) [11] DAEMEN, Joan e RIJMEN, Pawel. AES Proposal: Rijndael. Arquivo ZIP, disponível em http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndaeldo cv2.zip (30 Jul. 2001) [12] GLADMAN, Brian. AES Algorithm Efficiency. Desempenho dos candidatos ao AES em software, disponível em http://fp.gladman.plus.com/cryptography_technology/aes (Ago. 2001). [13] DAI, Wei. Speed Comparation of Popular Crypto Algorithms. Desempenho de vários algoritmos de criptografia em software, disponível em http://www.eskimo.com/~weidai/benchmarks.html (Out. 2001). [14] MROCZKOWSKI, Piotr. Implementation of the block cipher Rijndael using Altera FPGA. Arquivo PDF, disponível em http://csrc.nist.gov/encryption/aes/round2/comments/20000 510-pmroczkowski.pdf [15] LOMONT, Chris. AES Advanced Encryption Standard. Desempenho do Rijndael em software, disponível em http://www.math.purdue.edu/~clomont/software/aes/aes. htm (Out. 2001). [16] GAJ, Kris e CHODOWIEC, Vincent. Comparison of the hardware performance of the AES candidates using reconfigurable hardware. Arquivo PDF, disponível em http://csrc.nist.gov/encryption/aes/round2/conf3/papers/22- kgaj.pdf [17] NSA. Hardware Performance Simulations of Round 2 Advanced Encryption Standard Algorithms. Arquivo em formato pdf disponível via WWW em http://csrc.nist.gov/encryption/aes/round2/nsa- AESfinalreport.pdf (Jul. 2001). [18] BARCELOS, Marcelo; PANATO, Alex e REIS, Ricardo. Design Case: optimized performance and area implementation of Advanced Encryption Standard in Altera devices. DesignCon 2002.Santa Clara, USA, 28 29 janeiro de 2002. (aceito para publicação)