Compatibilidad de AES256 con DCPcrypt

Continuando con las pruebas a mi implementación de AES256 (Rijndael), que empece aquí, hoy voy a probar su compatibilidad con la conocida colección de componentes DCPcrypt. Para hacerlo voy a utilizar el siguiente ejemplo que podemos encontrar el la wiki de freepascal: http://wiki.freepascal.org/DCPcrypt/es

  program ctst;
  {$mode objfpc}{$H+}
  uses
    {$IFDEF UNIX}{$IFDEF UseCThreads}
    cthreads,
    {$ENDIF}{$ENDIF}
    Sysutils, DCPrijndael;
  const
    InData: array[0..15] of byte=
      ($32,$43,$f6,$a8,$88,$5a,$30,$8d,$31,$31,$98,$a2,$e0,$37,$07,$34);
    Key1: array[0..19] of byte=
      ($2b,$7e,$15,$16,$28,$ae,$d2,$a6,$ab,$f7,$15,$88,$09,$cf,$4f,$3c,$76,$2e,$71,$60);
    Key2: array[0..31] of byte=
      ($2b,$7e,$15,$16,$28,$ae,$d2,$a6,$ab,$f7,$15,$88,$09,$cf,$4f,$3c,$76,$2e,$71,$60,
       $f3,$8b,$4d,$a5,$6a,$78,$4d,$90,$45,$19,$0c,$fe);
    OutData1: array[0..15] of byte=
      ($23,$1d,$84,$46,$39,$b3,$1b,$41,$22,$11,$cf,$e9,$37,$12,$b8,$80);
    OutData2: array[0..15] of byte=
      ($1a,$6e,$6c,$2c,$66,$2e,$7d,$a6,$50,$1f,$fb,$62,$bc,$9e,$93,$f3);
  var
    Cipher: TDCP_rijndael;
    Block: array[0..15] of byte;
  begin
  // lengths:  block = 16 bytes, key = 20 bytes
  // key     = 2b7e151628aed2a6abf7158809cf4f3c762e7160
  // input   = 3243f6a8885a308d313198a2e0370734
  // encrypt = 231d844639b31b412211cfe93712b880
  // decrypt = 3243f6a8885a308d313198a2e0370734
    Cipher:= TDCP_rijndael.Create(nil);
    Cipher.Init(Key1,Sizeof(Key1)*8,nil);
    Cipher.EncryptECB(InData,Block);
    writeln('128-bit block & 160-bit key results:');
    writeln(boolean(CompareMem(@Block,@OutData1,16)));
    Cipher.DecryptECB(Block,Block);
    writeln(boolean(CompareMem(@Block,@InData,16)));
  // lengths:  block = 16 bytes, key = 32 bytes
  // key     = 2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfe
  // input   = 3243f6a8885a308d313198a2e0370734
  // encrypt = 1a6e6c2c662e7da6501ffb62bc9e93f3
  // decrypt = 3243f6a8885a308d313198a2e0370734
    Cipher:= TDCP_rijndael.Create(nil);
    Cipher.Init(Key2,Sizeof(Key2)*8,nil);
    Cipher.EncryptECB(InData,Block);
    writeln('128-bit block & 256-bit key results:');
    writeln(boolean(CompareMem(@Block,@OutData2,16)));
    Cipher.DecryptECB(Block,Block);
    writeln(boolean(CompareMem(@Block,@InData,16)));
  end.

En concreto nos vamos a centrar en el tamaño de clave de 256bits y utilizar los mismo datos del ejemplo:

const
  InData: array[0..15] of byte=
    ($32,$43,$f6,$a8,$88,$5a,$30,$8d,$31,$31,$98,$a2,$e0,$37,$07,$34);
  KeyData: array[0..31] of byte=
    ($2b,$7e,$15,$16,$28,$ae,$d2,$a6,$ab,$f7,$15,$88,$09,$cf,$4f,$3c,$76,$2e,$71,$60,
     $f3,$8b,$4d,$a5,$6a,$78,$4d,$90,$45,$19,$0c,$fe);
  OutData: array[0..15] of byte=
    ($1a,$6e,$6c,$2c,$66,$2e,$7d,$a6,$50,$1f,$fb,$62,$bc,$9e,$93,$f3);
 
procedure AESSwapKey(var Key: TAESKey);
var
  i: Integer;
begin
  for i:= 0 to 7 do
  begin
    Key[i]:=
      ((Key[i] and $000000FF) shl 24) or
      ((Key[i] and $0000FF00) shl 8) or
      ((Key[i] and $00FF0000) shr 8) or
      ((Key[i] and $FF000000) shr 24);
  end;
end;
 
var
  Key: TAESKey;
  ExpandedKey: TAESExpandedKey;
  State: TAESState;
begin
   Key:= TAESKey(KeyData);
  // Ajustamos el orden de los bytes dentro del array 
   AESSwapKey(Key);
   AESExpandKey(ExpandedKey,Key);
   State:= TAESState(InData);
   AESEncrypt(State,ExpandedKey);
   Writeln(boolean(CompareMem(@State,@OutData,16)));
end; 

Si todo es correcto el código anterior debe mostrar por pantalla "TRUE", que es efectivamente lo que muestra. El único detalle a tener en cuenta es que hemos corregido el orden de los bytes en la clave, usando la función AESSwapKey, para que se ajuste al mismo orden que utilizamos nosotros.