AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Advanced Encryption Standard 128 bit Eigenimplementierung - key schedule
Thema durchsuchen
Ansicht
Themen-Optionen

Advanced Encryption Standard 128 bit Eigenimplementierung - key schedule

Ein Thema von qwertz543221 · begonnen am 27. Dez 2012 · letzter Beitrag vom 7. Feb 2013
Antwort Antwort
qwertz543221
(Gast)

n/a Beiträge
 
#1

Advanced Encryption Standard 128 bit Eigenimplementierung - key schedule

  Alt 27. Dez 2012, 17:58
bei der implementierung des keyschedule beim AES bin ich auf probleme gestossen.

folgende quellen nutze ich http://www.cs.bc.edu/~straubin/cs381...ingles2004.swf
http://en.wikipedia.org/wiki/Rijndael_key_schedule
http://cboard.cprogramming.com/c-pro...-standard.html

Frage 1:
der algorithmus zur generierung der rundenschlüssel weist fehler auf, die rundenschlüssel werden nicht richtig erstellt.(http://en.wikipedia.org/wiki/Rijndael_key_schedule)

Frage 2: nutzung der rundenschlüssel /allgemeiner ablauf

ich habe die befürchgung, dass die rundenschlüssel nicht richtig genutzt werden. evtl beim entshclpsseln falsche reihenfolge?


habe bereits einige quellen gesucht, die den algorithmus verständlich widergeben.

quellcode im anhang, wäre es mlgich ein paar erläuterungen zu geben?
Angehängte Dateien
Dateityp: pas aes.pas (2,7 KB, 48x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von cookie22
cookie22

Registriert seit: 28. Jun 2006
Ort: Düsseldorf
936 Beiträge
 
Delphi XE2 Professional
 
#2

AW: Advanced Encryption Standard 128 bit Eigenimplementierung - key schedule

  Alt 27. Dez 2012, 18:17
Darf ich fragen warum du dir die Mühe machst, das ganze neu zu implementieren?
Gruß
Cookie
  Mit Zitat antworten Zitat
qwertz543221
(Gast)

n/a Beiträge
 
#3

AW: Advanced Encryption Standard 128 bit Eigenimplementierung - key schedule

  Alt 27. Dez 2012, 18:20
ja gut man könnte es auch einfacher haben^^

aber ich schreibe eigentlich gerne die dinge selbst. jetzt ist es ja auch schon fast fertig (erstentwurf für die allg. struktur, soll später noch optimiert werden)
  Mit Zitat antworten Zitat
qwertz543221
(Gast)

n/a Beiträge
 
#4

AW: Advanced Encryption Standard 128 bit Eigenimplementierung - key schedule

  Alt 28. Dez 2012, 21:36
habe es nun wie folgt:

Delphi-Quellcode:
type
 Tkey128 = Array [1 .. 176] Of Byte;

Function Taes.Expandkey(Var Key: Tinput; Var Expandedkey: Tkey128): Byte;
//expands given key (128,192,256 bit, determined by bitlen variable) to (176,208,240 bytes)
//blocksize=16=>keysize 128 bit
//result:= the number of rounds (10,12,14) determined by new keylength
//SRC= http://www.samiam.org/key-schedule.html
//http://cboard.cprogramming.com/c-programming/87805-%5Btutorial%5D-implementing-advanced-encryption-standard.html
Var
  I, Rconiterator, A, C: Integer;
  Temp: Tword;
Begin

  I := 1;
  While I <= Length(Key) Do
  Begin
    Expandedkey[I] := Key[I];
    Inc(I);
  End;

  Rconiterator := 1;
  C := 17;
  While C <= 176 Do
  Begin
    { Copy the temporary variable over from the last 4-byte- block }
    A := 1;
    While A <= 4 Do
    Begin
      //showmessage(inttostr(a)+';'+inttostr(c));
      Temp[A] := Expandedkey[A + C - 4];
      Inc(A);
    End;
    //Every four blocks (of four bytes) run keyschedule_core
    If C Mod 16 = 0 Then
    Begin
      Keyschedule_core(Temp, Rconiterator, 0);
      Inc(Rconiterator);
    End;
    A := 1;
    While A <= 4 Do
    Begin
      Expandedkey[C] := Expandedkey[C - 16] Xor Temp[A];
      Inc(C);
      Inc(A);
    End;

  End;

  Result := 11; //number of rounds for 128 bit keys
End;
hier von diesem code generierte output (expanded key) für input
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00


00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 58 00 00 58 00 00 58 00 58 58 00 58 0E
00 58 0E C2 58 0E 9A 0E 0E C2 0E 53 9A 0E 0B 7A
0E 53 74 C7 0B 7A 5D 0E 74 9F 00 53 05 0E 58 2A
00 0B 5E C7 00 24 9A B6 50 05 B6 53 00 B8 0B 0A
B8 00 54 CC 00 70 56 B6 20 53 00 EB 53 B8 E0 F4
00 E0 A0 CC E0 D0 9A B6 F0 C9 B6 13 9A 0E F3 B4
0E 13 14 98 F3 C4 02 96 34 CB 20 65 51 2E 96 B4
20 85 A0 98 76 64 9A 96 50 51 B6 D5 00 98 43 7E
B8 C6 DE 28 B0 BA B2 96 EA E3 20 D5 E3 B8 96 B4
00 50 6A 98 E0 D0 2A F2 3A C9 D2 F5 2A 6A 63 8C




laut http://www.samiam.org/key-schedule.html sollte der key allerdings lauten (ich hoffe das stimmt)

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
62 63 63 63 62 63 63 63 62 63 63 63 62 63 63 63
9b 98 98 c9 f9 fb fb aa 9b 98 98 c9 f9 fb fb aa
90 97 34 50 69 6c cf fa f2 f4 57 33 0b 0f ac 99
ee 06 da 7b 87 6a 15 81 75 9e 42 b2 7e 91 ee 2b
7f 2e 2b 88 f8 44 3e 09 8d da 7c bb f3 4b 92 90
ec 61 4b 85 14 25 75 8c 99 ff 09 37 6a b4 9b a7
21 75 17 87 35 50 62 0b ac af 6b 3c c6 1b f0 9b
0e f9 03 33 3b a9 61 38 97 06 0a 04 51 1d fa 9f
b1 d4 d8 e2 8a 7d b9 da 1d 7b b3 de 4c 66 49 41
b4 ef 5b cb 3e 92 e2 11 23 e9 51 cf 6f 8f 18 8e
  Mit Zitat antworten Zitat
qwertz543221
(Gast)

n/a Beiträge
 
#5

AW: Advanced Encryption Standard 128 bit Eigenimplementierung - key schedule

  Alt 28. Dez 2012, 23:06
Habe es hinbekommen:

Delphi-Quellcode:
Function Taes.Expandkey(Key: Tinput; Var Expandedkey: Tkey128): Byte;
//expands given key (128,192,256 bit, determined by bitlen variable) to (176,208,240 bytes)
//blocksize=16=>keysize 128 bit
//result:= the number of rounds (10,12,14) determined by new keylength
//SRC= http://www.samiam.org/key-schedule.html
//http://cboard.cprogramming.com/c-programming/87805-%5Btutorial%5D-implementing-advanced-encryption-standard.html
Var
  I, Rconiterator, A, C: Integer;
  Temp: Tword;
Begin
  I := 1;
  While I <= Length(Key) Do
  Begin
    Expandedkey[I] := Key[I];
    Inc(I);
  End;
  { inc(i);
    while i<=length(expandedkey) do
    begin
    expandedkey[i]:=0;
    inc(i);
    end; }


  Rconiterator := 1;

  C := Length(Key) + 1; //17
  While C <= 176 Do
  Begin
    { Copy the temporary variable over from the last 4-byte- block }
    A := 1;
    While A <= 4 Do
    Begin
      //showmessage(inttostr(a)+';'+inttostr(c));
      Temp[A] := Expandedkey[A + C - 5]; //ok
      Inc(A);
    End;
    //Every four blocks (of four bytes) do a complex calculation
    If ((C - 1) Mod 16 = 0) Then
    Begin
      Keyschedule_core(Temp, Rconiterator, 0);
      Inc(Rconiterator);
    End;
    A := 1;
    While A <= 4 Do
    Begin
      //Expandedkey[C+1] := Expandedkey[C - 16] Xor Temp[A];
      Expandedkey[C] := Expandedkey[C - 16] Xor Temp[A];
      Inc(C);
      Inc(A);
    End;

  End;

  Result := 11; //number of rounds for 128 bit keys
End;
  Mit Zitat antworten Zitat
qwertz543221
(Gast)

n/a Beiträge
 
#6

AW: Advanced Encryption Standard 128 bit Eigenimplementierung - key schedule

  Alt 29. Dez 2012, 21:01
Könnte jemand testvektoren für aes 128 (text,key,chiffre) zur überprüfung angeben?

ich habe jetzt den algorithmus in zwei unterschiedlichen programmen(einmal gesondert in einer unit, und einmal mit anderen algorithmen zusammen) und habe bei beiden differente ausgaben.

kann es an der klassendefinition und den jeweiligen zugriffsrechten zusammenhängen?

hier sind zwei ausgabebeispiele bei gleichem input:

BenutzerSchlüssel: test01af5
Eingabe: Testvektor
Ausgabe 1: cLffabrarTFxNvtjTNYDHG (base64)
Ausgabe 2: dnwm0e+gYhWhRaVn1X2GX0 (~)

anbei der quelltext für ausgabe 1

Delphi-Quellcode:
Unit Mainprogram;

Interface

Uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, StdCtrls, Crypto, ExtCtrls,Advanced_Encryption_Standard;

Type


  TForm1 = Class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    LabeledEdit1: TLabeledEdit;
    Button2: TButton;
    Procedure Button1Click(Sender: TObject);
    Procedure Button2Click(Sender: TObject);

  Private

  Public
    { Public declarations }
  End;

Var
  Form1: TForm1;
  Aes: Taes;
  Data: Tdata; //datenverarbeitung und ausgabe


Implementation

{$R *.dfm}


Procedure TForm1.Button1Click(Sender: TObject);
Var
  Text, Key: String;

Begin
  Text := Memo1.Text;

  Key := Labelededit1.Text;
  Text := Aes.Aes_text(Text, Key, Aes.Keysize128, 0);
  Text := Data.Base64(Text, 0); // Text := Data.Str_tohex(Text, Length(Text));
  Memo1.Text := Text;
End;

Procedure TForm1.Button2Click(Sender: TObject);
Var
  Text, Key: String;

Begin
  Text := Memo1.Text;
  Key := Labelededit1.Text;
  // Text := Data.Str_fromhex(Text);
  Text := Data.Base64(Text, 1);
  Text := Aes.Aes_text(Text, Key, Aes.Keysize128, 1);
  Memo1.Text := Text;
End;

Initialization

Data := Tdata.Create;
Aes := Taes.Create;

Finalization

Aes.Free;
Data.Free;

End.


Unit Advanced_Encryption_Standard;

Interface

{$RANGECHECKS on}
{$OPTIMIZATION ON}
{$OVERFLOWCHECKS on}

Uses
  Messages, SysUtils, Classes, StdCtrls;

Type
  // 128 bit /16 byte /4*4 blocks for 128 bit key
  Trow = Array [1 .. 4] Of Byte;
  Tcolumn = Array [1 .. 4] Of Byte;
  Tstate = Array [1 .. 4] Of Trow;
  Tword = Array [1 .. 4] Of Byte;
  Tinput = Array [1 .. 16] Of Byte; //to fill a custom state

  { expanded key arrays
    128 bit input block =>176 bytes=>11 16 byte blocks
    192 bit input block=>208 bytes=> 8 24 byte bocks
    256 bit input block=>240 bytes=> 7 32 byte blocks }

  Tkey128 = Array [1 .. 176] Of Byte;
  Tkey192 = Array [1 .. 208] Of Byte;
  Tkey256 = Array [1 .. 240] Of Byte;

  Tsubkeys128 = Array [1 .. 11] Of Tstate;

  //counters i,j:=1<= 4
  Taes = Class
    // Public
  Var
    Testroundkey: Tstate;
    //for initalization keyschedule test
    Testexpandedkey128: Tkey128;
    Testcount: Integer;

  Const
    Keysize128 = 128;
    Keysize192 = 192;
    Keysize256 = 256;

    Function Aes_text(Var Text, Key: String; Bitlen: Integer; Mode: Byte): String;

  Private

  Var
    Mixcolstate: Tstate;
    Mixcolinvstate: Tstate;
    Expandedkey128: Tkey128;
    Expandedkey192: Tkey192;
    Expandedkey256: Tkey256;
    Keys: Array Of String;

  Const

    Teststatearray: Tinput = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);

    Sbox: Array [0 .. 255] Of Byte =

    // 0 1 2 3 4 5 6 7 8 9 A B C D E F
      ($63, $7C, $77, $7B, $F2, $6B, $6F, $C5, $30, $01, $67, $2B, $FE, $D7, $AB, $76, //0
      $CA, $82, $C9, $7D, $FA, $59, $47, $F0, $AD, $D4, $A2, $AF, $9C, $A4, $72, $C0, //1
      $B7, $FD, $93, $26, $36, $3F, $F7, $CC, $34, $A5, $E5, $F1, $71, $D8, $31, $15, //2
      $04, $C7, $23, $C3, $18, $96, $05, $9A, $07, $12, $80, $E2, $EB, $27, $B2, $75, //3
      $09, $83, $2C, $1A, $1B, $6E, $5A, $A0, $52, $3B, $D6, $B3, $29, $E3, $2F, $84, //4
      $53, $D1, $00, $ED, $20, $FC, $B1, $5B, $6A, $CB, $BE, $39, $4A, $4C, $58, $CF, //5
      $D0, $EF, $AA, $FB, $43, $4D, $33, $85, $45, $F9, $02, $7F, $50, $3C, $9F, $A8, //6
      $51, $A3, $40, $8F, $92, $9D, $38, $F5, $BC, $B6, $DA, $21, $10, $FF, $F3, $D2, //7
      $CD, $0C, $13, $EC, $5F, $97, $44, $17, $C4, $A7, $7E, $3D, $64, $5D, $19, $73, //8
      $60, $81, $4F, $DC, $22, $2A, $90, $88, $46, $EE, $B8, $14, $DE, $5E, $0B, $DB, //9
      $E0, $32, $3A, $0A, $49, $06, $24, $5C, $C2, $D3, $AC, $62, $91, $95, $E4, $79, //A
      $E7, $C8, $37, $6D, $8D, $D5, $4E, $A9, $6C, $56, $F4, $EA, $65, $7A, $AE, $08, //B
      $BA, $78, $25, $2E, $1C, $A6, $B4, $C6, $E8, $DD, $74, $1F, $4B, $BD, $8B, $8A, //C
      $70, $3E, $B5, $66, $48, $03, $F6, $0E, $61, $35, $57, $B9, $86, $C1, $1D, $9E, //D
      $E1, $F8, $98, $11, $69, $D9, $8E, $94, $9B, $1E, $87, $E9, $CE, $55, $28, $DF, //E
      $8C, $A1, $89, $0D, $BF, $E6, $42, $68, $41, $99, $2D, $0F, $B0, $54, $BB, $16); //F

    Invsbox: Array [0 .. 255] Of Byte =
    // 0 1 2 3 4 5 6 7 8 9 A B C D E F
      ($52, $09, $6A, $D5, $30, $36, $A5, $38, $BF, $40, $A3, $9E, $81, $F3, $D7, $FB, //0
      $7C, $E3, $39, $82, $9B, $2F, $FF, $87, $34, $8E, $43, $44, $C4, $DE, $E9, $CB, //1
      $54, $7B, $94, $32, $A6, $C2, $23, $3D, $EE, $4C, $95, $0B, $42, $FA, $C3, $4E, //2
      $08, $2E, $A1, $66, $28, $D9, $24, $B2, $76, $5B, $A2, $49, $6D, $8B, $D1, $25, //3
      $72, $F8, $F6, $64, $86, $68, $98, $16, $D4, $A4, $5C, $CC, $5D, $65, $B6, $92, //4
      $6C, $70, $48, $50, $FD, $ED, $B9, $DA, $5E, $15, $46, $57, $A7, $8D, $9D, $84, //5
      $90, $D8, $AB, $00, $8C, $BC, $D3, $0A, $F7, $E4, $58, $05, $B8, $B3, $45, $06, //6
      $D0, $2C, $1E, $8F, $CA, $3F, $0F, $02, $C1, $AF, $BD, $03, $01, $13, $8A, $6B, //7
      $3A, $91, $11, $41, $4F, $67, $DC, $EA, $97, $F2, $CF, $CE, $F0, $B4, $E6, $73, //8
      $96, $AC, $74, $22, $E7, $AD, $35, $85, $E2, $F9, $37, $E8, $1C, $75, $DF, $6E, //9
      $47, $F1, $1A, $71, $1D, $29, $C5, $89, $6F, $B7, $62, $0E, $AA, $18, $BE, $1B, //A
      $FC, $56, $3E, $4B, $C6, $D2, $79, $20, $9A, $DB, $C0, $FE, $78, $CD, $5A, $F4, //B
      $1F, $DD, $A8, $33, $88, $07, $C7, $31, $B1, $12, $10, $59, $27, $80, $EC, $5F, //C
      $60, $51, $7F, $A9, $19, $B5, $4A, $0D, $2D, $E5, $7A, $9F, $93, $C9, $9C, $EF, //D
      $A0, $E0, $3B, $4D, $AE, $2A, $F5, $B0, $C8, $EB, $BB, $3C, $83, $53, $99, $61, //E
      $17, $2B, $04, $7E, $BA, $77, $D6, $26, $E1, $69, $14, $63, $55, $21, $0C, $7D); //F

    Procedure Aes128_Keyschedule_test(Var Keys: Array Of String);

    Procedure Keyschedule_core(Var Word: Tword; Iteration: Integer; Mode: Byte);
    Function Multcolumn(Column: Tcolumn; Mode: Byte): Tcolumn;
    Function Galois_mult(A, B: Byte): Byte; //http://en.wikipedia.org/wiki/Rijndael_mix_columns
    Procedure Shiftrows(Var State: Tstate; Mode: Byte);
    Procedure Rotate(Var Value: Tword; Mode: Byte); // rotate(1d 2c 3a 4f) = 2c 3a 4f 1d
    Procedure AddRoundKey(Var State: Tstate; Roundkey: Tstate);
    Function Getsboxvalue(Index: Byte): Byte;
    Function Getinvsboxvalue(Index: Byte): Byte;
    Function Rcon(Index: Byte): Integer;
    Function Expandkey(Key: Tinput; Var Expandedkey: Tkey128): Byte; Overload;
    //result=number of rounds
    Function Generatesubkeys(Expandedkey: Tkey128): Tsubkeys128;
    Function Expandkey(Key: Tinput; Var Expandedkey: Tkey192): Byte; Overload;
    //result=number of rounds
    Function Expandkey(Key: Tinput; Var Expandedkey: Tkey256): Byte; Overload;
    //result=number of rounds

    Procedure Mixcolumns(Var State: Tstate; Mode: Byte);
    Procedure Subbytes(Var State: Tstate; Mode: Byte); Overload;
    Procedure Subbytes(Var Word: Tword)Overload;
    Procedure Showstate(State: Tstate; Memo: Tmemo);
    Function Texttostate(Substr: String): Tstate;
    Function Texttokey(Key: String): Tinput;
    Function Keytostate(Data: Tinput): Tstate;
    Function Statetotext(State: Tstate): String;
    Procedure Aes(Roundcount: Byte; Var State: Tstate; Keys: Tsubkeys128; Mode: Byte);

  End;

Implementation

{ src: http://en.wikipedia.org/wiki/Rijndael_mix_columns: A c# example
  Multiplication in Rijndael's galois field is a little more complicated. The procedure is as follows:

  * Take two eight-bit numbers, a and b, and an eight-bit product p
  * Set the product to zero.
  * Make a copy of a and b, which we will simply call a and b in the rest of this algorithm
  * Run the following loop eight times:
  1. If the low bit of b is set, exclusive or the product p by the value of a
  2. Keep track of whether the high (eighth from left) bit of a is set to one
  3. Rotate a one bit to the left, discarding the high bit, and making the low bit have a value of zero
  4. If a's hi bit had a value of one prior to this rotation, exclusive or a with the hexadecimal number 0x1b
  5. Rotate b one bit to the right, discarding the low bit, and making the high (eighth from left) bit have a value of zero.
  6. The product p now has the product of a and b
}


//------------------------------------------------------------------------------
{
  The Key Schedule is responsible for expanding a short key into a larger key,
  whose parts are used during the different iterations. Each key size is expanded
  to a different size:

  An 128 bit key is expanded to an 176 byte key.
  An 192 bit key is expanded to an 208 byte key.
  An 256 bit key is expanded to an 240 byte key.

  There is a relation between the cipher key size,
  the number of rounds and the ExpandedKey size.
  For an 128-bit key, there is one initial AddRoundKey operation
  plus there are 10 rounds and each rounds need a new 16 byte key,
  therefor we require 10+1 RoundKeys of 16 byte, which equals 176 byte.
  The same logic can be applied to the two other cipher key sizes.
  The general formula is that: ExpandedKeySize = (nbrRounds+1) * BlockSize
  }


Procedure Taes.Aes128_Keyschedule_test(Var Keys: Array Of String);
Var
  I, J, K: Integer;
  Aes128: Array Of Tkey128;
Begin
  Setlength(Aes128, Length(Keys));
  J := 0;
  While J < 3 Do
  Begin
    Keys[J] := '';
    I := 1;
    While I <= 16 Do
    Begin
      Case J Of
        1:
          Keys[J] := Keys[J] + Chr(0);
        {
          should be:
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
          62 63 63 63 62 63 63 63 62 63 63 63 62 63 63 63
          9B 98 98 C9 F9 FB FB AA 9B 98 98 C9 F9 FB FB AA
          90 97 34 50 69 6C CF FA F2 F4 57 33 0B 0F AC 99
          EE 06 DA 7B 87 6A 15 81 75 9E 42 B2 7E 91 EE 2B
          7F 2E 2B 88 F8 44 3E 09 8D DA 7C BB F3 4B 92 90
          EC 61 4B 85 14 25 75 8C 99 FF 09 37 6A B4 9B A7
          21 75 17 87 35 50 62 0B AC AF 6B 3C C6 1B F0 9B
          0E F9 03 33 3B A9 61 38 97 06 0A 04 51 1D FA 9F
          B1 D4 D8 E2 8A 7D B9 DA 1D 7B B3 DE 4C 66 49 41
          B4 EF 5B CB 3E 92 E2 11 23 E9 51 CF 6F 8F 18 8E
          }

        2:
          Keys[J] := Keys[J] + Chr(Strtoint('$FF'));
        {
          should be:
          FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
          E8 E9 E9 E9 17 16 16 16 E8 E9 E9 E9 17 16 16 16
          AD AE AE 19 BA B8 B8 0F 52 51 51 E6 45 47 47 F0
          09 0E 22 77 B3 B6 9A 78 E1 E7 CB 9E A4 A0 8C 6E
          E1 6A BD 3E 52 DC 27 46 B3 3B EC D8 17 9B 60 B6
          E5 BA F3 CE B7 66 D4 88 04 5D 38 50 13 C6 58 E6
          71 D0 7D B3 C6 B6 A9 3B C2 EB 91 6B D1 2D C9 8D
          E9 0D 20 8D 2F BB 89 B6 ED 50 18 DD 3C 7D D1 50
          96 33 73 66 B9 88 FA D0 54 D8 E2 0D 68 A5 33 5D
          8B F0 3F 23 32 78 C5 F3 66 A0 27 FE 0E 05 14 A3
          D6 0A 35 88 E4 72 F0 7B 82 D2 D7 85 8C D7 C3 26
          }

        3:
          Keys[J] := Keys[J] + Chr(I - 1);
        { should be:
          00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          D6 AA 74 FD D2 AF 72 FA DA A6 78 F1 D6 AB 76 FE
          B6 92 CF 0B 64 3D BD F1 BE 9B C5 00 68 30 B3 FE
          B6 FF 74 4E D2 C2 C9 BF 6C 59 0C BF 04 69 BF 41
          47 F7 F7 BC 95 35 3E 03 F9 6C 32 BC FD 05 8D FD
          3C AA A3 E8 A9 9F 9D EB 50 F3 AF 57 AD F6 22 AA
          5E 39 0F 7D F7 A6 92 96 A7 55 3D C1 0A A3 1F 6B
          14 F9 70 1A E3 5F E2 8C 44 0A DF 4D 4E A9 C0 26
          47 43 87 35 A4 1C 65 B9 E0 16 BA F4 AE BF 7A D2
          54 99 32 D1 F0 85 57 68 10 93 ED 9C BE 2C 97 4E
          13 11 1D 7F E3 94 4A 17 F3 07 A7 8B 4D 2B 30 C5
          }

      End;
      Inc(I);
    End;

    Expandkey(Texttokey(Keys[J]), Aes128[J]);

    Keys[J] := '';
    K := 1;
    While K <= Length(Aes128[J]) Do
    Begin
      Keys[J] := Keys[J] + Inttohex(Aes128[J][K], 2) + Chr(32);
      If K Mod 16 = 0 Then
        Keys[J] := Keys[J] + #13#10;
      Inc(K);
    End;
    Inc(J);
  End;
End;

Procedure Taes.Keyschedule_core(Var Word: Tword; Iteration: Integer; Mode: Byte);
Begin
  Rotate(Word, Mode);
  Subbytes(Word);
  Word[1] := Word[1] Xor Byte(Rcon(Iteration));

End;

Function Taes.Galois_mult(A, B: Byte): Byte; //http://en.wikipedia.org/wiki/Rijndael_mix_columns
Var
  P, Counter, Hi_bit_set: Byte;
  Aa, Bb: Byte;

Begin
  Aa := A;
  Bb := B;
  P := 0;
  Counter := 0;
  While Counter < 8 Do
  Begin
    If (Bb And 1) <> 0 Then
      P := P Xor Aa;

    Hi_bit_set := Byte(Aa And $80); //Mod 256;
    Aa := Byte(Aa Shl 1);
    If Hi_bit_set <> 0 Then
      Aa := Byte(Aa Xor $1b); //x^8+x^4+x^3+x^2+x+1
    Bb := Bb Shr 1;
    Inc(Counter);
  End;
  Result := P;
End;

Function Taes.Multcolumn(Column: Tcolumn; Mode: Byte): Tcolumn;
//multiplies a column with the MDS matrix
{
  mds=
  2  3  1  1
  1  2  3  1
  1  1  2  3
  3  1  1  2

  mdsinv=
  14 11 13 9
  9  14 11 13
  13  9 14 11
  11 13  9 14

  where + = xor, x = galois-multiplication }


Begin
  Case Mode Of
    0:
      Begin

        Result[1] := (((Galois_mult(2, Column[1]) Xor Galois_mult(3, Column[2])) Xor Galois_mult
              (1, Column[3])) Xor Galois_mult(1, Column[4]));
        Result[2] := (((Galois_mult(1, Column[1]) Xor Galois_mult(2, Column[2])) Xor Galois_mult
              (3, Column[3])) Xor Galois_mult(1, Column[4]));
        Result[3] := (((Galois_mult(1, Column[1]) Xor Galois_mult(1, Column[2])) Xor Galois_mult
              (2, Column[3])) Xor Galois_mult(3, Column[4]));
        Result[4] := (((Galois_mult(3, Column[1]) Xor Galois_mult(1, Column[2])) Xor Galois_mult
              (1, Column[3])) Xor Galois_mult(2, Column[4]));
      End;
    1:
      Begin
        Result[1] := (((Galois_mult(14, Column[1]) Xor Galois_mult(11, Column[2])) Xor Galois_mult
              (13, Column[3])) Xor Galois_mult(9, Column[4]));
        Result[2] := (((Galois_mult(9, Column[1]) Xor Galois_mult(14, Column[2])) Xor Galois_mult
              (11, Column[3])) Xor Galois_mult(13, Column[4]));
        Result[3] := (((Galois_mult(13, Column[1]) Xor Galois_mult(9, Column[2])) Xor Galois_mult
              (14, Column[3])) Xor Galois_mult(11, Column[4]));
        Result[4] := (((Galois_mult(11, Column[1]) Xor Galois_mult(13, Column[2])) Xor Galois_mult
              (9, Column[3])) Xor Galois_mult(14, Column[4]));
      End;
  End;
End;

Procedure Taes.Mixcolumns(Var State: Tstate; Mode: Byte);

Var
  Column: Tcolumn;
  I, J: Integer;

Begin
  //identify columns
  J := 1;
  While J <= 4 Do
  Begin
    I := 1;
    While I <= 4 Do
    Begin
      Column[I] := State[I][J];
      Inc(I);
    End;
    Column := Multcolumn(Column, Mode);
    I := 1;
    While I <= 4 Do
    Begin
      State[I][J] := Column[I];
      Inc(I);
    End;
    Inc(J);
  End;
End;

Procedure Taes.Subbytes(Var State: Tstate; Mode: Byte); //ok
Var
  X: Byte;
  I, J: Integer;

Begin
  I := 1;
  While I <= 4 Do
  Begin
    J := 1;
    While J <= 4 Do
    Begin
      X := State[I][J];
      Case Mode Of
        0:
          X := Sbox[X];
        1:
          X := Invsbox[X];
      End;
      State[I][J] := X;
      Inc(J);
    End;
    Inc(I);
  End;
End;

Procedure Taes.Subbytes(Var Word: Tword);
Var
  I: Integer;
Begin
  I := 1;
  While I <= 4 Do
  Begin
    Word[I] := GetSBoxValue(Word[I]);
    Inc(I);
  End;
End;

Function Taes.Rcon(Index: Byte): Integer;
Var
  C, B: Integer;

Begin
  If Index = 0 Then
    Result := $8d
  Else
  Begin
    C := 1;
    While Index <> 1 Do
    Begin
      B := C And $80;
      C := C Shl 1;
      If B = $80 Then
        C := C Xor $1b;
      Dec(Index);
    End;
    Result := C;
  End;
End;

(* orig c code:
  -----------------
  {
  unsigned char c=1;
  if(in == 0)
  return 0;
  while(in != 1) {
  unsigned char b;
  b = c & 0x80;
  c <<= 1;
  if(b == 0x80) {
  c ^= 0x1b;
  }
  in--;
  }
  return c;
  }
  -----------------
  *)


Function Taes.Expandkey(Key: Tinput; Var Expandedkey: Tkey128): Byte; //correct!
//expands given key (128,192,256 bit, determined by bitlen variable) to (176,208,240 bytes)
//blocksize=16=>keysize 128 bit
//result:= the number of rounds (10,12,14) determined by new keylength
//SRC= http://www.samiam.org/key-schedule.html
//http://cboard.cprogramming.com/c-programming/87805-%5Btutorial%5D-implementing-advanced-encryption-standard.html
Var
  I, Rconiterator, A, C: Integer;
  Temp: Tword;
Begin
  I := 1;
  While I <= Length(Key) Do
  Begin
    Expandedkey[I] := Key[I];
    Inc(I);
  End;

  Rconiterator := 1;
  C := Length(Key) + 1; //17
  While C <= 176 Do
  Begin
    { Copy the temporary variable over from the last 4-byte- block }
    A := 1;
    While A <= 4 Do
    Begin
      Temp[A] := Expandedkey[A + C - 5];
      Inc(A);
    End;

    If ((C - 1) Mod 16 = 0) Then
    Begin
      Keyschedule_core(Temp, Rconiterator, 0);
      Inc(Rconiterator);
    End;
    A := 1;
    While A <= 4 Do
    Begin
      Expandedkey[C] := Expandedkey[C - 16] Xor Temp[A];
      Inc(C);
      Inc(A);
    End;
  End;

  Result := 11; //number of rounds for 128 bit keys
End;

Function Taes.Generatesubkeys(Expandedkey: Tkey128): Tsubkeys128;
Var
  I, J, K: Byte;
  X: Byte;
  Subkeystate: Tstate;
  Subkey: Tinput;
Begin
  I := 1;
  X := 1;
  While I < Length(Expandedkey) Do
  Begin
    J := I;
    K := 1;
    While K <= 16 Do
    Begin
      Subkey[K] := Expandedkey[J];
      Inc(K);
      Inc(J);
    End;

    Subkeystate := Keytostate(Subkey);
    Result[X] := Subkeystate;
    Inc(X);
    I := J;
  End;
End;

Function Taes.Expandkey(Key: Tinput; Var Expandedkey: Tkey192): Byte;
//expands given key (128,192,256 bit, determined by bitlen variable) to (176,208,240 bytes)
//blocksize=16=>keysize 128 bit
//result:=new keylength(determines the number of rounds (10,12,14)
//SRC= http://www.samiam.org/key-schedule.html
//http://cboard.cprogramming.com/c-programming/87805-%5Btutorial%5D-implementing-advanced-encryption-standard.html
Var
  I: Integer;
  Currentsize, Size: Integer;
  Rconiteration: Integer;
  Temp: Tword;
Begin
  Rconiteration := 1;
  Size := Length(Key);
  I := 1;
  While I <= 4 Do
  Begin
    Temp[I] := 0;
    Inc(I);
  End;
  Currentsize := 0;
  I := 1;
  While I <= Size Do
  Begin
    Expandedkey[I] := Key[I];
    Inc(I);
  End;
  Currentsize := Currentsize + Size;
  // assign the previous 4 bytes to the temporary value t
  While Currentsize < Length(Expandedkey) Do
  Begin
    I := 1;
    While I <= 4 Do
    Begin
      Temp[I] := Expandedkey[(Currentsize - 4) + I];
      Inc(I);
    End;
    //every 16,24,32 bytes (respective length of tinput) we apply the core schedule to t and increment rconIteration afterwards

    If Currentsize Mod Size = 0 Then
    Begin
      Keyschedule_core(Temp, Rconiteration + 1, 0);
      Inc(Rconiteration);
    End;

    {
      We XOR t with the four-byte block 16,24,32 bytes before the new expanded key.
      * This becomes the next four bytes in the expanded key.
      }


    I := 1;
    While I <= 4 Do
    Begin
      Expandedkey[Currentsize] := Expandedkey[Currentsize - Size] Xor Temp[I];
      Inc(Currentsize);
      Inc(I);
    End;

  End;
  Result := 12; //number of rounds for 192 bit keys
End;

Function Taes.Expandkey(Key: Tinput; Var Expandedkey: Tkey256): Byte;
//expands given key (128,192,256 bit, determined by bitlen variable) to (176,208,240 bytes)
//blocksize=16=>keysize 128 bit
//result:=new keylength(determines the number of rounds (10,12,14)
//SRC= http://www.samiam.org/key-schedule.html
//http://cboard.cprogramming.com/c-programming/87805-%5Btutorial%5D-implementing-advanced-encryption-standard.html
Var
  I: Integer;
  Currentsize, Size: Integer;
  Rconiteration: Integer;
  Temp: Tword;
Begin
  Rconiteration := 1;
  Size := Length(Key);
  I := 1;
  While I <= 4 Do
  Begin
    Temp[I] := 0;
    Inc(I);
  End;
  Currentsize := 0;
  I := 1;
  While I <= Size Do
  Begin
    Expandedkey[I] := Key[I];
    Inc(I);
  End;
  Currentsize := Currentsize + Size;
  // assign the previous 4 bytes to the temporary value t
  While Currentsize < Length(Expandedkey) Do
  Begin
    I := 1;
    While I <= 4 Do
    Begin
      Temp[I] := Expandedkey[(Currentsize - 4) + I];
      Inc(I);
    End;
    //every 16,24,32 bytes (respective length of tinput) we apply the core schedule to t and increment rconIteration afterwards

    If Currentsize Mod Size = 0 Then
    Begin
      Keyschedule_core(Temp, Rconiteration + 1, 0);
      Inc(Rconiteration);
    End;

    //applies only to 256 bit keys: For 256-bit keys, we add an extra sbox to the calculation
    If (Size = 32) And (Currentsize Mod Size = 16) Then
    Begin
      I := 1;
      While I <= 4 Do
      Begin
        Temp[I] := Getsboxvalue(Temp[I]);
        Inc(I);
      End;

    End;

    {
      We XOR t with the four-byte block 16,24,32 bytes before the new expanded key.
      * This becomes the next four bytes in the expanded key.
      }


    I := 1;
    While I <= 4 Do
    Begin
      Expandedkey[Currentsize] := Expandedkey[Currentsize - Size] Xor Temp[I];
      Inc(Currentsize);
      Inc(I);
    End;

  End;
  Result := 14; //number of rounds for 256 bit keys
End;

Function Taes.Texttostate(Substr: String): Tstate;
//max length 16!!
Var
  I, J: Integer;
  Row: Trow;

Begin
  If Length(Substr) > 16 Then
  Begin
    Raise Exception.Create('No valid substring length');
    Exit;
  End;

  I := 1;
  While I <= 4 Do
  Begin
    J := 1;
    While J <= 4 Do
    Begin
      Row[J] := Ord(Substr[J + 4 * (I - 1)]);
      Inc(J);

    End;
    Result[I] := Row;
    Inc(I);
  End;

End;

Function Taes.Keytostate(Data: Tinput): Tstate;
Var
  I, J: Integer;
  Row: Trow;

Begin

  I := 1;
  While I <= 4 Do
  Begin
    J := 1;
    While J <= 4 Do
    Begin
      Row[J] := Ord(Data[J + 4 * (I - 1)]);
      Inc(J);

    End;
    Result[I] := Row;
    Inc(I);
  End;
End;

Function Taes.Statetotext(State: Tstate): String;
Var
  I, J: Int64;

Begin
  Result := '';
  I := 1;
  While I <= 4 Do
  Begin
    J := 1;
    While J <= 4 Do
    Begin
      Result := Result + Chr(State[I][J]);
      Inc(J);
    End;
    Inc(I);
  End;
End;

Function Taes.Texttokey(Key: String): Tinput;
Var
  I: Byte;
Begin
  If Length(Key) > 16 Then
    Raise Exception.Create('Keylength not accepted. Must be <=16')
  Else
  Begin

    I := 1;
    While I <= Length(Key) Do
    Begin
      Result[I] := Ord(Key[I]);
      Inc(I);
    End;
    While I < 16 Do
    Begin
      Result[I] := 0;
      Inc(I);
    End;

  End;

End;

Procedure Taes.Showstate(State: Tstate; Memo: Tmemo);
Var
  I, J: Integer;
  Row: Trow;
  R: String;

Begin
  I := 1;
  While I <= 4 Do
  Begin
    J := 1;
    R := '';
    While J <= 4 Do
    Begin
      Row[J] := State[I][J];
      R := R + Inttostr(Row[J]) + Chr(32);
      Inc(J);
    End;
    Memo.Lines.Add(R);
    Inc(I);
  End;
End;

Procedure Taes.Shiftrows(Var State: Tstate; Mode: Byte); //ok
  Function Rowshift(Row: Trow; Count, Mode: Byte): Trow;
  Var
    I, K: Integer;

  Begin
    I := 1;
    While I <= 4 Do
    Begin
      If Mode = 0 Then
      Begin
        K := (I + Count);
        If K > 4 Then
          K := K - 4;
      End
      Else If Mode = 1 Then
      Begin
        K := (I - Count);
        If K < 1 Then
          K := K + 4;
      End;
      Result[I] := Row[K];
      Inc(I);
    End;
  End;

Var
  I: Integer;
Begin
  If (Mode = 0) Or (Mode = 1) Then
  Begin
    I := 1;
    While I <= 4 Do
    Begin
      State[I] := Rowshift(State[I], I - 1, Mode);
      Inc(I);
    End;
  End
  Else
    Exit;
End;

// rotate(1d 2c 3a 4f) = 2c 3a 4f 1d
//tword is 4byte long, Rotation 8 bit (=1byte) to the left=shifting one entry to the left
Procedure Taes.Rotate(Var Value: Tword; Mode: Byte);
Var
  I, J: Byte;
  Result: Tword;

Begin
  Case Mode Of

    0:
      Begin
        I := 1;
        While I <= 4 Do
        Begin
          J := I + 1;
          If J > 4 Then
            J := J - 4;

          Result[I] := Value[J];
          Inc(I);
        End;
      End;

    1:
      Begin
        I := 1;
        While I <= 4 Do
        Begin
          J := I - 1;
          If J <= 0 Then
            J := J + 4;

          Result[I] := Value[J];
          Inc(I);
        End;
      End;
  End;
  Value := Result;
End;

Procedure Taes.AddRoundKey(Var State: Tstate; Roundkey: Tstate);
Var
  I, J: Integer;

Begin
  I := 1;
  While I <= 4 Do
  Begin
    J := 1;
    While J <= 4 Do //one row
    Begin
      State[I][J] := State[I][J] Xor Roundkey[I][J];
      Inc(J);
    End;
    Inc(I);
  End;
End;

Function Taes.Getsboxvalue(Index: Byte): Byte;
Begin
  Result := Sbox[Index];
End;

Function Taes.Getinvsboxvalue(Index: Byte): Byte;
Begin
  Result := Invsbox[Index];
End;

Procedure Taes.Aes(Roundcount: Byte; Var State: Tstate; Keys: Tsubkeys128; Mode: Byte);
Var
  I: Integer;

Begin
  If Mode = 0 Then
  Begin
    I := 1;
    Addroundkey(State, Keys[I]);
    Inc(I);
    While I <= Roundcount - 1 Do
    Begin
      Subbytes(State, Mode);
      Shiftrows(State, Mode);
      Mixcolumns(State, Mode);
      Addroundkey(State, Keys[I]);
      Inc(I);
    End;
    // final round :
    Subbytes(State, Mode);
    Shiftrows(State, Mode);
    Addroundkey(State, Keys[I]);
  End

  Else
  Begin
    I := Roundcount;
    //decryption= go backwards from last step on
    Addroundkey(State, Keys[I]);
    Shiftrows(State, Mode);
    Subbytes(State, Mode);
    I := I - 1;
    While I >= 2 Do
    Begin
      Addroundkey(State, Keys[I]);
      Mixcolumns(State, Mode);
      Shiftrows(State, Mode);
      Subbytes(State, Mode);
      Dec(I);

    End;
    Addroundkey(State, Keys[I]);
  End;
End;

Function Taes.Aes_text(Var Text, Key: String; Bitlen: Integer; Mode: Byte): String;
Var
  Substr: String;
  I, J, Textlen: Int64;
  State: Tstate;
  Keystate: Tinput;
  Roundcount: Integer;
  Subkeys: Tsubkeys128;

Begin
  Textlen := Length(Text);
  //padding
  While Textlen Mod 16 <> 0 Do
  Begin
    Text := Text + Chr(0);
    Inc(Textlen);
  End;

  Keystate := Texttokey(Key);
  Case Bitlen Of
    128:
      Roundcount := Expandkey(Keystate, Expandedkey128);
    192:
      Roundcount := Expandkey(Keystate, Expandedkey192);
    256:
      Roundcount := Expandkey(Keystate, Expandedkey256);
  Else
    Begin
      Result := Text;
      Raise Exception.Create('Keysize not accepted.');
    End;

  End;

  Subkeys := Generatesubkeys(Expandedkey128);

  If Roundcount <> -1 Then
  Begin
    I := 1;
    While I <= Textlen Do
    Begin
      J := I;
      Substr := '';
      While J < I + 16 Do
      Begin
        Substr := Substr + Text[J];
        Inc(J);
      End;
      State := Texttostate(Substr);
      Aes(Roundcount, State, Subkeys, Mode);
      Substr := Statetotext(State);
      Result := Result + Substr;
      I := J;
    End;
  End

  Else
    Result := Text; //an error occurred
End;

End.

besten dank
  Mit Zitat antworten Zitat
BlackSeven

Registriert seit: 25. Sep 2004
79 Beiträge
 
Delphi XE7 Professional
 
#7

AW: Advanced Encryption Standard 128 bit Eigenimplementierung - key schedule

  Alt 29. Dez 2012, 21:30
Zitat:
Könnte jemand testvektoren für aes 128 (text,key,chiffre) zur überprüfung angeben?
Ich hoffe, es hilft weiter.
Angehängte Dateien
Dateityp: zip AES-Vectors.zip (177,8 KB, 46x aufgerufen)
  Mit Zitat antworten Zitat
qwertz543221
(Gast)

n/a Beiträge
 
#8

AW: Advanced Encryption Standard 128 bit Eigenimplementierung - key schedule

  Alt 13. Jan 2013, 16:43
vielen dank
noch eine andere frage, in welcher reihenfolge werden die blöcke eingelesen, zeilen oder spaltenweise?

beispiel

16 inputbits 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f

wie folgt?
(reihenweise)
00 01 02 03
04 05 06 07
08 09 0a 0b
0c 0d 0e 0f

oder so (spaltenweise)

00 04 08 0c
01 05 09 0d
02 06 0a 0e
03 07 0b 0f
  Mit Zitat antworten Zitat
qwertz543221
(Gast)

n/a Beiträge
 
#9

AW: Advanced Encryption Standard 128 bit Eigenimplementierung - key schedule

  Alt 13. Jan 2013, 18:09
ok danke an alle. ich habe nun die von blackseven zur verfügung gestellten testwerte erlangt
  Mit Zitat antworten Zitat
obed onda

Registriert seit: 6. Feb 2013
1 Beiträge
 
#10

AW: Advanced Encryption Standard 128 bit Eigenimplementierung - key schedule

  Alt 7. Feb 2013, 01:59
ob TDATA Variable im Skript oben ist eine Klasse und wo bekomme ich seinen Crypto-Einheit? danke
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:21 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz