2009. április 11., szombat
Bravion - Strong Encryption Algorithm
Problem/Question/Abstract:
Is there more to encryption than XORing output from Random(256) with a chars from a string? Yes there's allot more to it.
Answer:
ABOUT
The name Bravion is pronnounced brave-ion. It is an alegory for molecules undergoing chemical reactions. A molecule is separeted into its ions, which then regroup with ions from a reactant to form new ions. In this algorithm, the ions change properties as well: protons, neutrons and electrons are reconfigured by the reactant and make the resulting molecules unpredictable without knowing the original reactant. Indeed it takes a brave ion to undergo such abuse :)
The routines here aren't very straight forward, even for one who has studied ciphers. I will try to keep it in lamens terms to the best of my ability. Bravion uses a 256bit key and a 128bit block size. It is an iterated (multiple rounds) substitution/permutation network. It is fast, but not nearly the fastest I've seen. I encrypt around 3MB/sec on my system.
GLOSSARY - read carefully
block size:
Size in bits of the data to encrypt (fixed in all block ciphers)
plaintext:
Data that has not yet been encrypted.
ciphertext:
Data that has been encrypted.
key:
Data used to modify plaintext into an incomprehensible sate.
entropy:
Unpredicatble data.
permutation:
Transformation of data by displacements (of individual or grouped bits) or transformation of data by mathematical functions. Dependent permutations require another source of data, and once permutated, both data are required to reverse the permutation.
dependency:
Data required to inverse a permutation.
key size:
Size in bits of the data used as a key (this can be variable in *some* ciphers, but is limited to the dependency imposed by the block size)
xor:
Bitwise exclusive OR. xor has an important property: if A xor B = C, then C xor A = B, C xor B = A xor works wonders for permutations.
mul:
Multiplication modulo 2^32 where a factor of 0 is interpreted as 2^32+1.
add:
Addition modulo 2^32.
sub:
Subtraction modulo 2^32.
shr:
Bit-shift to the right covering the ENTIRE block of data rather than individual integers.
shl:
Same as shr, but the bit shift is to the left.
substitution:
Exchanging one group of bits for another. The result of a substitution depends on the bits that are being substituted. This process is always reversable, using irreversable substitution to change data is considered (by myself) a permutation.
S-BOX:
An array of values that are used to replace on block of data for another such as SBOX:array[0..255]of byte would be used to replace a byte for another:
B: byte;
B := SBOX[B];
To reverse the process S-BOXs can be structured such that SBOX[SBOX[B]]=B or (preferably) a compliment of the X-BOX can be created such that SBOX_1[SBOX_0[B]]=B An S-BOX's array must be of suitable size to accept any input data as an index (for a byte: 0..255, for a word: 0..65535). S-BOXs are very efficient substitution
mechanisms.
feistel network:
Data is divided into 2 halfs, one half is permutated (and/or substituted) and the second half is a product (usualy an xor) of the permuted first half and itself. To reverse the process the inverse of the product is obtained for to restore the second half (in the case of an xor, another xor does the trick) and the first half is then restored with the inserve of the permutation applied to it.
round:
An intteration of a set of functions. Almost all ciphers implement rounds. Some use as little as 8, others use as many as 32. A general rule of thumb is the more rounds, the harder it is to break the cipher (unless the rounds are very simple). The number of rounds is usualy a little bigger than the minimum needed to maintain a safe cihper. It is a compromise between security and speed.
round keys:
Data that contains entropy from the key used in sequencial order determined by the current round.
component:
A group of operations (permutations, substitutions etc..)
attacker:
Someone trying to decrypt ciphertext without the key.
satistical analysis:
Using probability theory to aid in *guessing* possible plaintext from ciphertext.
brute force:
Decrypting ciphertext with every possible key until the plaintext is found. If an attacker is unable to break a cipher, the only option is brute force (holding a gun to whomever knows the key's head is not considered brute force, it's considered social engineering)
ALGORITHM
The encryption process can be broken down into 5 components.
BEFORE ITTERATING THROUGH THE ROUNDS
[1]
B[0] := B[0] xor RK[PK[16], 0]; //PK holds the path keys
B[1] := B[1] xor RK[PK[17], 1]; //that determine the round
B[2] := B[2] xor RK[PK[18], 2]; //keys to use
B[3] := B[3] xor RK[PK[19], 3];
A key-dependent permutation by XOR with round keys. Which round keys are used depends on the original key. A set of path keys is extrapolated from the key. Which round keys are used is unknown to an attacker. This is done so that in the event that portions of the round keys have been recovered by an attacker, knowledge of the original key is inherently required. The original key cannot be found by solving all the round keys due to the initialization mechanism (discussed later). This is done to the plaintext before entering the first round and after finishing the last round. This dissolves linearity of repetited components (even though there should be none, I have taken no chances with Bravion. I have not seen this sort of permutation in any other algorithm, but I am confident that this component seriously impairs an attacker's chances at successful statistical analysis.
ROUND DESCRIPTION
This part is repeated 16 times.
[2]
CarryBit := (B[0] and 2147483648) shr 31;
B[0] := (B[0] shl 1) or ((B[1] and 2147483648) shr 31);
B[1] := (B[1] shl 1) or ((B[2] and 2147483648) shr 31);
B[2] := (B[2] shl 1) or ((B[3] and 2147483648) shr 31);
B[3] := (B[3] shl 1) or CarryBit;
the data put through a shl and the last bit of the block is put into the first bit. In most ciphers data is only re-ordered in bytes, word, or longwords, and this leads to statistical analysis of these groups of bits. Since each bit is shifted 1 bit, every byte/word/longword recieves 1 bit from the previous. After itterating through 16 rounds, each byte has been permuted with each bit twice. Their order does not change however, so the same statistical analysis can be accomplished. The solution to this problem lies in [4]. The reverse is a shr and the first bit of the block is put into the last bit.
[3]
B[3] := B[3] xor (B[2] - RK[i, 3]);
B[2] := B[2] xor Mul(B[1], RK[i, 2]);
B[1] := B[1] xor (B[0] + RK[i, 1]);
B[0] := B[0] xor RK[i, 0];
Taking out all the components designed to reinforce Bravion except [5], the heart of Bravion lies here. The Theory employed here lies in 3 algebraic [is that how it's spelt?] groups, add, mul, xor each having an etropy the same size as its inputs (in this case 32bits). Using a fixed parameter (the round key) and going through each possible value with the second parameter will never result in the same output with any of these 3 groups. The second important property of this component is that all but one longword of the block are dependent of the others. To solve B[1] you must solve B[0], to solve B[2] you have to have solved B[2] with B[0] and so on. Only B[0] is independent of the other longwords of the block. xor is used, because of the inefficiency (in speed) of calculating the inverses of these algebraic groups.
[4]
for i := 0 to 15 do
T[i] := B[P0[PK[i], 0]]
Move(T, B, 16);
//T,B:array[0..15]of byte
This is what I called a re-ordering matrix. Things get a little akward in this component. Have a look at the square matrix below:
P0: array[0..15, 0..15] of longword = (
($A, $3, $B, $C, $5, $E, $9, $F, $0, $7, $4, $6, $1, $D, $2, $8),
($9, $5, $F, $3, $1, $0, $A, $4, $7, $B, $E, $8, $2, $6, $D, $C),
($6, $D, $A, $4, $3, $5, $2, $8, $B, $F, $9, $C, $0, $E, $7, $1),
($E, $7, $0, $D, $8, $B, $1, $3, $9, $6, $C, $4, $A, $2, $F, $5),
($C, $A, $2, $5, $F, $D, $7, $9, $4, $E, $6, $B, $8, $3, $1, $0),
($5, $9, $3, $8, $D, $6, $4, $C, $1, $0, $7, $2, $E, $B, $A, $F),
($0, $6, $4, $A, $7, $3, $B, $E, $2, $8, $5, $1, $D, $F, $C, $9),
($D, $F, $9, $0, $6, $2, $3, $1, $E, $C, $A, $5, $B, $8, $4, $7),
($1, $0, $C, $2, $9, $7, $6, $D, $3, $5, $8, $E, $F, $A, $B, $4),
($3, $8, $5, $7, $2, $C, $E, $B, $A, $9, $D, $F, $4, $1, $0, $6),
($F, $B, $D, $1, $C, $8, $0, $6, $5, $2, $3, $7, $9, $4, $E, $A),
($8, $E, $1, $9, $4, $F, $C, $5, $6, $D, $2, $A, $7, $0, $3, $B),
($4, $C, $7, $6, $E, $1, $5, $2, $F, $A, $B, $0, $3, $9, $8, $D),
($7, $2, $6, $B, $0, $4, $D, $A, $8, $1, $F, $3, $5, $C, $9, $E),
($2, $1, $8, $E, $B, $A, $F, $7, $D, $4, $0, $9, $C, $5, $6, $3),
($B, $4, $E, $F, $A, $9, $8, $0, $C, $3, $1, $D, $6, $7, $5, $2));
Pay attention to the values in each rown and each column. In every row, values from 0 to 15 are assigned once, and in every column, values from 0 to 15 are assigned once. Each row represents an order to put the bytes of the block in. To demonstrate I will use the following block of plaintext:
B = 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
Using the first row for this demonstration value can be assigned to a temporary block through indexing:
T[0] := B[P0[0]]; //T[0]:=B[$A];
T[1] := B[P0[1]]; //T[1]:=B[$3];
T[2] := B[P0[2]]; //T[2]:=B[$B];
{...and so on... }
T[15] := B[P0[15]]; //T[15]:=B[$8];
T = 26, 19, 27, 28, 21, 30, 25, 31, 16, 23, 20, 22, 17, 29, 18, 24
T now contains all bytes of B, but in the new order. T is then copied into B and B has been re-ordered. There are 16 rows in all. A path key determines which row to use, hence which order to put B in. To reverse the permutation I have created a re-ordering matrix that is the inverse of this one such that T[0]=B[P0[0]], B[0]=T[P1[0]. There are 16! (=~2.09x10^13=~2^44) ways to re-order 16 bytes. This subsitution occurs 16 times, and since no 2 rows will put any byte in the same position (look at the columns), the number of possible orders is increased by a factor of 16 each time, for a total of 16^16. This means that we cover all the possible orders 4.2 million times in excess! This is only the theoretical boundary, the true boundary is still 16!, but we at least know that the resulting ciphertext could be in ANY of these 16! arrangements. The re-ordering matrix by itself helps, but does not do much against statistical analysis because the bits are still in 8bit groups. Combined with the re-ordering matrix, the 1bit shift, scatters bits independently from each-other in 16! orders. I have read papers stating that idealy, blocks should be permuted as one block and not sub-blocks, but that because of the data size required to achieve such a large permutation would be beyond the reach of our technology. To put things into context, an S-BOX of 8bits in 8bits out is 255bytes, 16bits-in 16bits-out is 131072bytes, 128bits-in 128bits-out would be 5.4x10^39bytes! Unfortunatly, this structure only allows for 2^44 different block-sized permutations, but it's still a great advantage.
[5]
for i := 0 to 15 B[i] := S0[B[i], j];
//B:array[0..15]of byte
This component substitutes each byte in B for another. There are 16 of these S-BOXs and an inversed S-BOX for each. One S-BOX is used for each round. I've added these S-BOXs as a precaution. I used my random number generator NoiseSpunge (article name "Cryptographic Random Numbers") to generate completly random S-BOXs. The result is the outputs are drastic permutations on 8bit groups.
INITIALIZATION
Initialization is done in 3 steps.
[1]
The key is divided into 32 bit groups. Each group serves as as seed to a pseudo random number generator (PRNG). This PRNG has a period of 2^32 implying that no 2 seeds will generate the same sequence and that it will no show signs of a pattern before ~4billion numbers have been output. Each of the 8 seeds are used to generate 256bits which are stored as the round keys.
[2]
Path keys are extrapolated directly from the key by means of this function:
for i := 0 to 15 do //SET 4BIT PATH KEYS
begin
PK[i] := (Key[i] xor Key[i + 16]) and $F;
j := 16 + (i mod 8);
PK[j] := PK[j] xor (Key[i] xor Key[i + 16]) and $F0) shr 4;
end; //Key is interpreted as array[0..31]of byte
[3]
The key is encrypted with the current round keys and the resulting ciphertext is used to replace 2 sets of round keys. This is repeated until each set of round keys has been overwritten 128 times. This may seem like obsessive paranoya, but that would be incorrect. This is a precaution against brute force. If initialization requires encrypting 256 blocks, then for every key an attacker wants to test will take the a little longer than it takes to decrypt 256 blocks! Of course to the end user this doesn't even put a dent in his processor usage, but to an attacker trying to test 2^256 keys, it will lengthen his search by a factor of 256. This is like adding 8bits of key data to his search. I haven't seen this form of initialization used as a brute force deterent before, but I'm certain I'm not the first to think about it.
I strongly recomend you read this article "256bit keys for strong encryption" as well use the unit included to produce the 256bit keys.
Below is the entire unit. Credit is as always well appreciated!
//BRAVION (C)Copyright DrMungkee 2001
unit Bravion;
interface
type
TBravionBlock8 = array[0..15] of byte;
TBravionBlock32 = array[0..3] of longword;
TBravionKey8 = array[0..31] of byte;
TBravionKey32 = array[0..7] of longword;
TBravionRoundKey32 = array[0..15] of TBravionBlock32;
TBravionPathKey8 = array[0..23] of longword;
TBravionContext = record
RK: TBravionRoundKey32;
PK: TBravionPathKey8;
end;
procedure BravionInit(var Context: TBravionContext; var Key: TBravionKey32);
procedure BravionDecrypt(var Context: TBravionContext; var B: TBravionBlock32);
procedure BravionEncrypt(var Context: TBravionContext; var B: TBravionBlock32);
implementation
const
//SUBSTITUTION BOXES FOR EACH ROUND
S0: array[0..15, 0..255] of longword = ((
$68, $9D, $A8, $7C, $0D, $E1, $C1, $21, $BC, $97, $84, $A2, $DE, $EE, $45, $BD,
$17, $D8, $32, $D5, $A7, $1A, $64, $23, $1B, $B8, $07, $A1, $3B, $6E, $DF, $8D,
$24, $50, $F4, $73, $C4, $59, $B7, $38, $D3, $47, $10, $E7, $93, $DD, $0A, $3C,
$36, $AA, $9A, $B1, $75, $8E, $5B, $9B, $49, $33, $C8, $A4, $1C, $06, $20, $46,
$88, $FA, $FC, $CC, $2E, $AD, $05, $1D, $86, $EF, $04, $3F, $6D, $0F, $D2, $5C,
$DB, $5F, $0C, $71, $E3, $87, $A3, $8F, $AC, $9E, $0B, $AB, $EA, $5E, $AF, $16,
$44, $E6, $39, $FB, $2A, $43, $3A, $F9, $48, $7E, $11, $08, $4C, $CB, $ED, $8B,
$95, $C0, $01, $29, $4E, $B6, $63, $5D, $A9, $52, $56, $C5, $BB, $12, $81, $91,
$F7, $7F, $4F, $3E, $2C, $F1, $EB, $54, $B5, $00, $6C, $8A, $26, $FF, $1E, $CA,
$83, $9F, $D7, $EC, $77, $85, $B3, $F2, $CF, $28, $6B, $BF, $02, $96, $B0, $27,
$F8, $F6, $DC, $D6, $7B, $65, $78, $60, $70, $82, $B9, $98, $BA, $62, $30, $61,
$19, $B2, $09, $E9, $18, $79, $22, $14, $D9, $D1, $B4, $15, $E5, $F5, $92, $51,
$80, $6A, $53, $89, $D4, $E0, $0E, $31, $76, $55, $4D, $9C, $94, $E4, $A0, $FE,
$CD, $F3, $4A, $2F, $03, $1F, $69, $D0, $72, $F0, $AE, $8C, $E2, $41, $5A, $7D,
$13, $74, $35, $42, $A6, $90, $25, $C7, $58, $2B, $6F, $C2, $66, $99, $E8, $3D,
$C6, $C9, $57, $CE, $37, $67, $7A, $BE, $40, $2D, $34, $4B, $A5, $C3, $DA, $FD), (
$78, $8D, $66, $CD, $1A, $9C, $0A, $FB, $D8, $3B, $9E, $6B, $73, $54, $45, $75,
$15, $4C, $B5, $B1, $1B, $E0, $A3, $17, $2A, $57, $F0, $82, $07, $C5, $0C, $27,
$88, $12, $A5, $1F, $8F, $D2, $18, $7B, $D3, $D9, $56, $F9, $05, $5C, $06, $68,
$41, $6F, $94, $60, $C6, $C3, $6E, $E2, $D6, $11, $34, $19, $3D, $E5, $E1, $3E,
$47, $B2, $DB, $F4, $B6, $CF, $F5, $10, $4B, $FA, $AB, $7F, $1C, $37, $46, $EE,
$D7, $A6, $E9, $53, $FD, $CE, $EA, $8C, $84, $C7, $6C, $85, $9A, $D5, $28, $DC,
$2B, $FF, $32, $EB, $77, $F2, $24, $4E, $9D, $03, $20, $81, $59, $DE, $C4, $6A,
$A7, $89, $AE, $2E, $3A, $40, $86, $F8, $E4, $D1, $0B, $E8, $E7, $90, $D0, $08,
$02, $B0, $4F, $B3, $C0, $92, $1D, $97, $7D, $E6, $99, $21, $9B, $83, $70, $AC,
$C1, $80, $5E, $23, $5B, $4A, $65, $A8, $63, $61, $6D, $95, $16, $F1, $C2, $52,
$96, $7C, $FE, $3F, $BD, $0D, $B4, $44, $ED, $42, $A0, $2C, $35, $22, $04, $0E,
$D4, $51, $A2, $EC, $43, $AF, $B9, $EF, $39, $49, $2F, $69, $7E, $F3, $BF, $71,
$67, $25, $8B, $8A, $01, $2D, $76, $79, $5F, $E3, $87, $3C, $31, $5A, $36, $1E,
$9F, $98, $58, $CA, $A9, $BB, $DD, $AD, $A1, $50, $09, $33, $A4, $CB, $0F, $B8,
$13, $14, $26, $29, $30, $38, $62, $FC, $72, $64, $DF, $00, $F7, $C8, $8E, $4D,
$AA, $5D, $CC, $C9, $55, $74, $48, $DA, $91, $7A, $B7, $BC, $F6, $93, $BA, $BE), (
$74, $8B, $4E, $20, $AC, $E8, $7A, $EF, $E2, $D6, $80, $BE, $A7, $05, $AA, $55,
$C6, $DE, $1A, $5E, $1D, $30, $DA, $4B, $3D, $6D, $49, $4D, $5C, $9F, $77, $D1,
$0E, $B3, $A5, $28, $0A, $F6, $E0, $83, $63, $7D, $3A, $E7, $E1, $C4, $7C, $27,
$53, $54, $AD, $D3, $87, $F9, $FE, $A9, $1B, $F8, $99, $79, $43, $A1, $04, $46,
$B2, $B4, $67, $CD, $F5, $14, $64, $BA, $16, $4F, $AE, $6A, $5B, $02, $DD, $32,
$BF, $A4, $4C, $36, $2F, $10, $A6, $FA, $01, $8D, $ED, $FF, $7F, $93, $9A, $6F,
$1C, $A3, $92, $B0, $97, $2B, $AF, $6B, $2D, $41, $FB, $EB, $78, $22, $C1, $91,
$51, $15, $F1, $BC, $42, $6E, $70, $CB, $71, $C0, $25, $86, $8A, $18, $85, $98,
$39, $F4, $E5, $00, $D5, $0F, $17, $45, $C3, $5F, $58, $2E, $C5, $7B, $B9, $40,
$1F, $A0, $9C, $3E, $F2, $21, $31, $0B, $9B, $EA, $72, $5D, $76, $13, $3B, $52,
$C8, $61, $09, $D2, $96, $75, $11, $94, $CF, $D0, $29, $06, $CC, $DF, $CE, $33,
$62, $B5, $2C, $1E, $81, $88, $90, $A2, $26, $19, $84, $E3, $D8, $08, $3F, $F3,
$8F, $AB, $B1, $BD, $50, $60, $23, $FC, $3C, $65, $EC, $07, $FD, $A8, $03, $E9,
$DC, $95, $CA, $47, $35, $69, $0D, $38, $DB, $E4, $D4, $C9, $9D, $F0, $5A, $37,
$B8, $6C, $C7, $4A, $68, $82, $66, $24, $7E, $89, $0C, $12, $2A, $34, $44, $48,
$56, $57, $59, $73, $8C, $B6, $E6, $D7, $8E, $EE, $F7, $C2, $D9, $9E, $B7, $BB), (
$DE, $9A, $C5, $FB, $93, $3E, $4E, $99, $68, $CC, $2E, $34, $07, $4F, $D1, $AB,
$36, $50, $73, $19, $57, $F5, $16, $F8, $64, $D7, $37, $CA, $48, $62, $A9, $25,
$3C, $3F, $0C, $C3, $A0, $DF, $D3, $C0, $3D, $66, $B2, $52, $94, $5E, $0E, $4D,
$F0, $69, $8D, $AD, $EF, $4C, $29, $A1, $7C, $02, $23, $5D, $9E, $AC, $03, $97,
$B5, $D6, $6B, $BA, $DC, $83, $C6, $AF, $F6, $9F, $F2, $09, $75, $76, $54, $15,
$00, $DA, $8F, $71, $7B, $6F, $3A, $CE, $C1, $F1, $0F, $67, $B8, $C8, $ED, $45,
$32, $1A, $2B, $6E, $B1, $BE, $85, $C7, $28, $BB, $C2, $82, $5F, $FD, $B0, $5B,
$D5, $44, $61, $63, $7A, $0D, $1C, $E3, $F7, $A6, $8A, $98, $31, $7D, $11, $80,
$A7, $EB, $A8, $22, $51, $E2, $F4, $47, $74, $A3, $14, $FF, $E6, $33, $42, $DD,
$D8, $92, $01, $1D, $9C, $90, $EA, $BD, $8B, $B9, $E9, $24, $65, $7F, $D2, $6A,
$81, $30, $9B, $B7, $E4, $60, $B3, $4A, $8C, $18, $B6, $53, $5A, $41, $B4, $3B,
$D0, $F3, $2D, $87, $27, $26, $2A, $9D, $A4, $D4, $CF, $BC, $17, $72, $43, $46,
$2F, $08, $91, $E0, $1F, $13, $88, $6C, $89, $8E, $38, $A2, $40, $C4, $AE, $FA,
$FE, $E7, $EC, $78, $04, $84, $39, $E5, $77, $E8, $BF, $F9, $55, $59, $12, $21,
$10, $86, $1B, $C9, $05, $A5, $FC, $49, $EE, $CB, $E1, $79, $DB, $96, $5C, $CD,
$D9, $06, $0A, $0B, $1E, $20, $2C, $35, $4B, $56, $58, $6D, $70, $7E, $95, $AA), (
$AE, $02, $85, $29, $A7, $FB, $64, $1C, $77, $78, $69, $F4, $D7, $27, $0F, $41,
$54, $17, $A0, $03, $BB, $72, $E8, $3E, $C6, $3C, $65, $7D, $5E, $DD, $F7, $6B,
$E1, $E9, $2A, $EC, $B0, $34, $35, $73, $BA, $6D, $32, $7A, $50, $2E, $8A, $3D,
$12, $E6, $A6, $4A, $14, $8F, $31, $E2, $5D, $21, $CA, $8C, $48, $63, $8B, $92,
$87, $BC, $16, $61, $E3, $5B, $08, $A5, $E7, $DA, $93, $3B, $94, $13, $0D, $9E,
$07, $CE, $96, $38, $BE, $4F, $60, $66, $B3, $81, $F0, $B2, $36, $FE, $04, $FD,
$C4, $0A, $75, $BF, $A4, $2C, $1D, $83, $42, $C1, $BD, $49, $C9, $B5, $9C, $79,
$A1, $D8, $1B, $47, $D4, $74, $19, $24, $01, $51, $53, $EA, $ED, $1F, $67, $1E,
$71, $D0, $6A, $2F, $62, $3A, $11, $AF, $B1, $57, $26, $43, $9A, $CB, $1A, $70,
$C7, $7B, $39, $2B, $AB, $F2, $A9, $0B, $CC, $B9, $4B, $10, $DE, $E4, $FC, $D2,
$AC, $CD, $EE, $00, $20, $AD, $68, $56, $D3, $AA, $6F, $15, $30, $7C, $28, $E5,
$95, $25, $55, $5F, $0C, $D9, $C0, $A2, $59, $91, $C5, $82, $CF, $9B, $37, $A3,
$F9, $F5, $C2, $22, $A8, $23, $4D, $B7, $FA, $40, $C3, $FF, $D5, $0E, $05, $97,
$5C, $99, $18, $33, $D6, $F1, $B4, $DC, $B6, $D1, $09, $86, $8E, $F3, $52, $06,
$2D, $7E, $EB, $C8, $7F, $3F, $44, $45, $46, $4C, $4E, $58, $88, $DF, $80, $84,
$F8, $90, $9D, $9F, $F6, $8D, $B8, $89, $98, $EF, $5A, $DB, $E0, $6C, $6E, $76), (
$5E, $63, $73, $A1, $FE, $6A, $8E, $C1, $5C, $D8, $1F, $D7, $B1, $97, $FB, $91,
$78, $EB, $1C, $FA, $2C, $D5, $95, $B0, $40, $48, $89, $CE, $3C, $34, $43, $BF,
$4A, $32, $9C, $5B, $71, $AF, $FD, $D2, $29, $18, $C0, $20, $72, $2B, $45, $0E,
$C8, $55, $83, $15, $E5, $A7, $DB, $A5, $8D, $E7, $4F, $7D, $C3, $00, $D3, $85,
$B5, $B4, $C2, $D9, $04, $88, $B8, $AE, $80, $C4, $99, $BB, $61, $13, $0C, $60,
$6F, $9D, $AD, $56, $AA, $F1, $46, $8B, $F2, $8C, $F5, $F7, $51, $E4, $E6, $2F,
$37, $12, $82, $67, $CA, $DF, $A6, $B3, $0F, $AB, $53, $44, $7F, $E9, $10, $1A,
$7A, $9B, $92, $26, $81, $03, $DD, $C5, $11, $DA, $65, $BD, $4C, $42, $86, $E0,
$31, $50, $84, $1D, $B2, $B6, $27, $14, $CF, $49, $D1, $30, $23, $52, $9E, $7C,
$7E, $4B, $BA, $38, $BC, $3F, $EE, $6E, $02, $16, $74, $CB, $2A, $96, $E1, $E3,
$35, $58, $06, $3D, $09, $3E, $E2, $93, $E8, $9A, $8F, $D4, $94, $F4, $47, $CD,
$33, $3A, $A4, $05, $21, $66, $87, $22, $39, $70, $69, $1E, $F9, $75, $24, $79,
$1B, $2E, $5A, $A2, $C6, $C7, $6B, $A8, $54, $D6, $5F, $F6, $EA, $08, $57, $FF,
$28, $6D, $DC, $EF, $41, $BE, $0D, $FC, $7B, $DE, $76, $A9, $CC, $62, $01, $A3,
$EC, $25, $59, $3B, $F8, $07, $0A, $0B, $17, $19, $2D, $36, $A0, $ED, $4E, $B7,
$C9, $5D, $9F, $68, $AC, $64, $F3, $6C, $98, $4D, $D0, $8A, $77, $90, $F0, $B9), (
$4D, $B2, $3C, $E6, $96, $B9, $9D, $C3, $A3, $9E, $FE, $1B, $76, $ED, $46, $31,
$60, $C8, $3E, $98, $FF, $D0, $E2, $F8, $7D, $B8, $99, $FD, $64, $68, $BB, $40,
$8B, $25, $2A, $DE, $4F, $E5, $88, $DB, $2B, $44, $32, $EB, $15, $C5, $5E, $F1,
$3D, $01, $A4, $11, $BA, $5B, $8F, $0A, $37, $7F, $E0, $23, $7A, $2D, $EE, $1E,
$A6, $29, $F7, $F0, $35, $4C, $63, $8A, $93, $92, $34, $B4, $4A, $89, $C4, $F6,
$33, $9C, $FA, $0B, $38, $EA, $2F, $AD, $80, $E1, $1F, $BD, $91, $16, $5C, $9A,
$12, $0D, $26, $82, $6C, $DF, $19, $1A, $54, $45, $F3, $D8, $A1, $3A, $65, $86,
$77, $02, $B1, $74, $97, $BC, $6E, $CF, $F4, $7C, $B0, $8D, $50, $48, $FC, $41,
$09, $81, $95, $6A, $D5, $59, $0E, $E3, $05, $C0, $78, $51, $A8, $87, $84, $D6,
$C9, $E8, $C2, $14, $21, $49, $7E, $0C, $EC, $66, $13, $07, $C1, $10, $9B, $CD,
$C7, $E9, $94, $5F, $B7, $B3, $AB, $3B, $FB, $06, $0F, $F9, $D1, $39, $53, $08,
$6F, $CE, $D2, $61, $E7, $A0, $79, $55, $52, $30, $47, $B5, $04, $58, $75, $F5,
$DD, $73, $71, $67, $BE, $43, $D4, $D9, $1D, $AC, $20, $DA, $A5, $70, $6B, $BF,
$AF, $CC, $3F, $D3, $9F, $24, $DC, $28, $03, $17, $18, $1C, $22, $27, $85, $2E,
$83, $56, $C6, $A9, $2C, $5A, $62, $72, $36, $00, $69, $8E, $CB, $42, $4E, $AE,
$D7, $4B, $57, $A7, $A2, $EF, $E4, $CA, $5D, $6D, $F2, $7B, $8C, $90, $AA, $B6), (
$0C, $56, $BF, $EE, $4F, $AB, $7D, $3E, $73, $98, $A8, $85, $05, $F4, $95, $3D,
$C8, $D3, $67, $CA, $D2, $8C, $0D, $75, $47, $65, $CB, $63, $A2, $8F, $24, $C0,
$18, $5A, $3B, $FA, $16, $77, $31, $A5, $71, $34, $E4, $66, $42, $FC, $EF, $E3,
$DA, $D6, $92, $F1, $79, $EC, $C7, $4B, $99, $2D, $74, $12, $CD, $A9, $1B, $FF,
$B2, $7F, $8A, $1F, $F3, $D0, $B1, $09, $8B, $59, $22, $DB, $D5, $84, $91, $57,
$FE, $68, $C1, $C4, $6B, $87, $F0, $39, $17, $B7, $B0, $E8, $27, $1E, $9F, $2C,
$BE, $1D, $E0, $7B, $E2, $94, $69, $20, $03, $64, $02, $4D, $ED, $7E, $AF, $19,
$5D, $3C, $07, $6E, $36, $CC, $0E, $01, $51, $FD, $3F, $F5, $14, $DF, $0A, $93,
$60, $40, $CF, $26, $53, $81, $2B, $B3, $43, $A6, $C6, $B4, $DD, $52, $A4, $61,
$F6, $08, $28, $76, $7A, $46, $50, $7C, $C3, $A7, $9A, $13, $11, $4E, $04, $4A,
$4C, $33, $6A, $A1, $2E, $83, $BA, $B8, $49, $44, $6F, $E1, $29, $C5, $88, $E9,
$58, $90, $1A, $F7, $8D, $D8, $41, $15, $AC, $37, $F8, $E7, $89, $DC, $BC, $5B,
$E6, $8E, $D7, $23, $1C, $9B, $48, $38, $97, $B6, $55, $2F, $E5, $5F, $B9, $80,
$EA, $C9, $78, $6C, $30, $D1, $82, $AE, $D4, $9E, $00, $C2, $6D, $B5, $86, $DE,
$9D, $45, $54, $AA, $D9, $BD, $5C, $96, $FB, $35, $0F, $CE, $9C, $10, $72, $0B,
$70, $A3, $62, $A0, $25, $EB, $06, $21, $2A, $32, $3A, $5E, $AD, $BB, $F2, $F9), (
$9F, $7E, $36, $84, $96, $8F, $B9, $F9, $32, $71, $93, $A7, $CB, $FA, $8E, $BA,
$D3, $34, $7A, $6A, $E3, $B8, $90, $A5, $52, $A2, $48, $67, $CA, $02, $97, $E7,
$F6, $40, $7C, $BF, $9A, $CD, $DB, $27, $5B, $1B, $63, $AC, $0A, $F3, $B6, $31,
$C7, $80, $53, $4E, $ED, $C0, $CF, $19, $E1, $AA, $41, $E0, $07, $94, $57, $DD,
$9E, $EF, $1E, $25, $74, $FF, $30, $33, $EB, $D5, $FD, $06, $99, $B4, $EE, $98,
$1A, $47, $C1, $7D, $2C, $10, $51, $F0, $5D, $20, $38, $72, $EA, $43, $4D, $23,
$FE, $87, $DA, $0E, $15, $14, $BB, $01, $6C, $8A, $85, $56, $82, $05, $BE, $16,
$76, $2B, $EC, $D2, $44, $21, $61, $C8, $83, $49, $70, $F7, $F2, $AB, $37, $AF,
$9C, $60, $E8, $E5, $7B, $4F, $AE, $39, $04, $CE, $3A, $03, $D1, $54, $7F, $50,
$FB, $5E, $64, $24, $D7, $18, $86, $0D, $4B, $73, $A6, $3C, $69, $E6, $E4, $92,
$E9, $AD, $F4, $28, $6F, $91, $0B, $D8, $2D, $9B, $62, $45, $2A, $6E, $6D, $8C,
$59, $5C, $D9, $F8, $17, $66, $77, $A8, $8B, $DF, $78, $DE, $B3, $42, $79, $4C,
$A3, $89, $D0, $55, $1F, $A4, $C6, $00, $75, $A9, $09, $0C, $81, $B5, $3D, $B7,
$B2, $DC, $6B, $D6, $26, $9D, $3E, $95, $D4, $35, $3B, $E2, $65, $08, $4A, $13,
$1C, $2E, $FC, $0F, $F5, $88, $C9, $BC, $12, $F1, $22, $3F, $B1, $68, $C5, $B0,
$11, $1D, $29, $2F, $46, $58, $5A, $5F, $8D, $A0, $A1, $BD, $C3, $C4, $C2, $CC), (
$EF, $8D, $10, $2A, $79, $42, $8C, $85, $D9, $83, $24, $12, $E9, $9F, $38, $67,
$B2, $5C, $1A, $28, $36, $16, $B7, $11, $A5, $D2, $2E, $06, $1C, $FD, $E5, $41,
$4F, $F4, $20, $AF, $3F, $3B, $05, $35, $9C, $A1, $DA, $3E, $7A, $CD, $F2, $B1,
$FA, $7B, $E3, $F5, $5D, $FE, $ED, $1E, $26, $40, $F9, $BF, $46, $BE, $22, $4A,
$EE, $5F, $6E, $77, $DE, $E8, $D0, $7D, $F6, $31, $2B, $B9, $99, $F3, $9D, $93,
$A3, $A2, $7C, $68, $0A, $07, $6A, $C5, $03, $4C, $27, $C8, $3C, $0B, $4D, $56,
$54, $CF, $73, $72, $49, $A8, $B5, $BC, $F1, $C4, $53, $69, $14, $9B, $47, $C0,
$E0, $C2, $43, $13, $A6, $0C, $84, $E2, $29, $A7, $63, $D5, $2C, $74, $19, $0F,
$CE, $1F, $0D, $DF, $C1, $97, $BB, $65, $C3, $61, $01, $7F, $6F, $3D, $5B, $FC,
$87, $CA, $08, $B8, $09, $CC, $A9, $25, $86, $6D, $AE, $9A, $8A, $15, $66, $EA,
$C7, $37, $58, $BD, $DD, $DC, $60, $91, $B3, $95, $B4, $33, $EC, $D7, $A0, $64,
$2D, $98, $EB, $AD, $4B, $FB, $3A, $44, $71, $F8, $52, $A4, $9E, $E7, $89, $7E,
$39, $B0, $D3, $94, $8F, $45, $E6, $B6, $CB, $0E, $92, $18, $5E, $30, $57, $AA,
$02, $55, $D4, $48, $82, $6B, $E1, $D6, $8B, $21, $78, $75, $32, $90, $76, $70,
$6C, $DB, $C6, $88, $04, $17, $1B, $1D, $23, $2F, $34, $4E, $50, $FF, $8E, $AB,
$D8, $5A, $59, $AC, $00, $C9, $51, $BA, $F7, $D1, $62, $81, $80, $E4, $96, $F0), (
$88, $DF, $B7, $A7, $8A, $CE, $44, $6C, $4F, $4D, $FD, $92, $4A, $56, $A4, $4B,
$58, $D5, $FC, $E8, $F8, $F4, $3A, $43, $EF, $3E, $01, $AC, $36, $2E, $F2, $28,
$09, $C3, $67, $D3, $A1, $29, $DE, $50, $79, $14, $78, $97, $26, $9C, $24, $AD,
$15, $E9, $6B, $7B, $96, $87, $2D, $30, $9B, $8D, $89, $21, $4E, $20, $C8, $5A,
$6E, $71, $06, $33, $74, $E2, $9F, $85, $BD, $EB, $34, $DB, $BE, $B1, $A0, $1B,
$93, $CF, $1A, $E0, $5D, $59, $52, $46, $2C, $2B, $37, $CB, $FB, $38, $95, $9A,
$BC, $32, $AF, $8B, $DA, $11, $68, $B2, $5E, $23, $D8, $22, $7C, $91, $E4, $C2,
$41, $EE, $ED, $17, $05, $3D, $1C, $08, $83, $80, $4C, $D2, $5B, $9D, $3B, $02,
$C4, $C1, $7E, $F3, $BA, $12, $51, $72, $FE, $E5, $62, $70, $60, $EA, $35, $99,
$8C, $65, $BF, $45, $6D, $8E, $DD, $A9, $CA, $F0, $98, $53, $66, $D4, $AE, $B3,
$10, $5C, $F7, $0E, $18, $A8, $0F, $B0, $EC, $76, $AA, $A6, $F5, $3F, $D6, $F6,
$E7, $55, $82, $C9, $AB, $B6, $D0, $04, $C5, $7F, $86, $77, $07, $0C, $5F, $16,
$81, $63, $C7, $40, $31, $54, $B5, $49, $90, $FF, $27, $75, $7A, $CD, $48, $13,
$1D, $03, $D9, $D1, $E6, $0A, $84, $69, $C6, $B9, $B8, $C0, $A3, $B4, $94, $A2,
$D7, $F9, $9E, $6A, $1F, $1E, $0D, $DC, $E3, $CC, $3C, $0B, $6F, $2A, $00, $7D,
$39, $42, $BB, $19, $73, $61, $25, $2F, $47, $57, $64, $8F, $A5, $E1, $F1, $FA), (
$61, $C1, $70, $D5, $26, $07, $09, $EB, $8B, $5F, $28, $E5, $64, $91, $46, $32,
$E0, $72, $9A, $11, $C0, $45, $66, $99, $1D, $8D, $40, $62, $55, $EE, $BB, $5C,
$94, $E6, $1F, $00, $A2, $76, $1B, $34, $78, $0F, $2C, $F6, $97, $4D, $3F, $21,
$6E, $BA, $83, $8F, $B0, $9B, $9E, $2E, $F0, $C4, $FF, $71, $A4, $35, $D8, $69,
$88, $4C, $DB, $1A, $BD, $30, $C7, $47, $80, $90, $17, $A5, $50, $0A, $C3, $57,
$18, $03, $49, $37, $D4, $F8, $CE, $20, $CB, $65, $85, $02, $4A, $DA, $14, $24,
$75, $7A, $48, $A1, $CC, $98, $73, $FD, $C2, $FA, $E7, $68, $AB, $B3, $0C, $D2,
$FC, $53, $5A, $81, $2D, $63, $D3, $33, $DE, $95, $BC, $F2, $44, $4B, $B7, $5D,
$AE, $EC, $B4, $1E, $9C, $DC, $7E, $9D, $8A, $25, $B1, $A8, $22, $D9, $B8, $D0,
$82, $BF, $67, $6A, $01, $0D, $C9, $6B, $AA, $CA, $AC, $A9, $DD, $3C, $8E, $3B,
$F5, $F9, $C8, $23, $C5, $6F, $3A, $08, $51, $E4, $C6, $D6, $84, $87, $A6, $0E,
$FB, $A0, $0B, $E2, $8C, $1C, $15, $E1, $60, $B9, $10, $E8, $74, $5B, $9F, $ED,
$2B, $B2, $29, $7F, $E9, $F7, $36, $F4, $3D, $A3, $D1, $58, $38, $93, $04, $6D,
$B5, $AF, $05, $27, $31, $CF, $E3, $7B, $4F, $5E, $2F, $B6, $52, $7D, $42, $39,
$06, $12, $13, $59, $D7, $16, $CD, $3E, $4E, $BE, $92, $A7, $F3, $77, $EA, $79,
$89, $43, $AD, $86, $DF, $19, $41, $FE, $6C, $7C, $2A, $96, $54, $56, $EF, $F1), (
$99, $09, $EE, $E3, $4B, $6E, $04, $D0, $F6, $76, $8F, $EA, $A7, $2F, $EB, $D8,
$A9, $83, $96, $C8, $F7, $64, $B3, $54, $28, $9B, $B2, $9E, $41, $DF, $CD, $06,
$33, $65, $1F, $80, $4C, $E0, $0C, $B6, $39, $90, $7C, $50, $3C, $B8, $73, $91,
$92, $A2, $C5, $51, $C7, $1A, $4F, $21, $08, $A8, $36, $8B, $6A, $82, $86, $7E,
$59, $95, $D6, $B5, $FC, $37, $02, $B1, $16, $6C, $B0, $C9, $55, $B9, $DE, $F5,
$61, $98, $D4, $63, $C6, $FE, $BA, $C2, $24, $4A, $97, $5F, $67, $ED, $01, $2C,
$46, $9F, $3D, $A0, $23, $58, $62, $13, $2B, $34, $D2, $8E, $D1, $00, $70, $68,
$15, $2E, $31, $45, $A4, $EC, $81, $F4, $F3, $A3, $1C, $75, $07, $F0, $DA, $27,
$CB, $CE, $0F, $1B, $BB, $5B, $F2, $CF, $77, $D9, $18, $7B, $29, $EF, $FB, $D5,
$BE, $3F, $5E, $52, $8D, $26, $A1, $0E, $A5, $1D, $93, $43, $B7, $20, $F1, $38,
$57, $5C, $94, $A6, $79, $E9, $7D, $40, $F9, $0B, $DC, $25, $FD, $BC, $49, $BD,
$44, $AA, $6B, $12, $22, $4D, $0A, $53, $6D, $2D, $7A, $F8, $42, $C3, $4E, $7F,
$60, $E8, $19, $AF, $D7, $71, $78, $1E, $AD, $CA, $6F, $AC, $11, $0D, $8C, $C1,
$5A, $E7, $E2, $CC, $17, $30, $74, $3A, $BF, $3E, $88, $D3, $84, $66, $B4, $9A,
$87, $03, $05, $10, $14, $2A, $32, $69, $9C, $5D, $9D, $85, $E6, $AB, $48, $E1,
$FA, $3B, $72, $AE, $DD, $35, $89, $E5, $8A, $47, $C0, $56, $FF, $C4, $DB, $E4), (
$81, $13, $59, $92, $52, $E4, $BF, $02, $B7, $19, $FD, $87, $53, $2E, $F2, $80,
$CF, $12, $4F, $0A, $9B, $63, $9A, $E3, $68, $CB, $36, $EC, $C8, $2D, $34, $D3,
$31, $56, $F4, $62, $A4, $D4, $71, $ED, $DB, $B0, $B3, $8C, $5A, $D8, $2C, $8D,
$90, $B6, $91, $1C, $7D, $E7, $C5, $65, $F0, $21, $FA, $17, $57, $64, $B2, $75,
$38, $6D, $10, $16, $C9, $E5, $A2, $6A, $0B, $09, $94, $54, $C0, $BE, $42, $95,
$1A, $44, $66, $6B, $30, $73, $7C, $50, $99, $9D, $9E, $A9, $FB, $C4, $E2, $AD,
$6E, $A3, $9C, $55, $EE, $72, $84, $8A, $46, $D2, $28, $A6, $6F, $AE, $74, $F3,
$48, $BB, $35, $1F, $D7, $CC, $AC, $D1, $DD, $5D, $A7, $AA, $76, $3D, $8E, $D0,
$24, $2F, $EB, $DC, $41, $8F, $97, $0F, $3A, $DF, $B9, $DE, $D9, $BD, $7E, $47,
$5B, $14, $40, $FC, $4D, $58, $26, $C3, $29, $11, $4A, $43, $77, $EF, $33, $3B,
$A5, $3E, $88, $1E, $B5, $7F, $4E, $E0, $61, $F8, $DA, $E6, $7A, $03, $A0, $C1,
$BA, $78, $9F, $EA, $E8, $AB, $69, $07, $F9, $E9, $82, $93, $51, $D6, $F1, $FF,
$39, $89, $E1, $1D, $A1, $C7, $F7, $37, $CD, $96, $6C, $67, $D5, $B4, $BC, $60,
$B1, $70, $3F, $27, $85, $83, $7B, $C6, $20, $0C, $B8, $CE, $86, $F6, $0E, $AF,
$5F, $01, $04, $15, $23, $0D, $32, $F5, $22, $00, $18, $4B, $A8, $98, $FE, $2B,
$45, $8B, $5C, $5E, $79, $06, $25, $1B, $05, $CA, $49, $2A, $08, $3C, $C2, $4C), (
$41, $EB, $7F, $0F, $02, $6F, $C4, $47, $D9, $04, $37, $4C, $EF, $A3, $BC, $B6,
$17, $5B, $E4, $11, $1C, $18, $96, $6C, $AF, $58, $87, $50, $0A, $59, $E9, $3E,
$49, $90, $DF, $07, $F1, $D7, $CD, $AE, $82, $2A, $34, $C8, $E0, $7C, $19, $C0,
$9C, $D1, $BE, $31, $E7, $D6, $51, $AA, $EE, $F3, $28, $27, $8F, $A8, $05, $21,
$B7, $78, $E8, $33, $A6, $4D, $DE, $7D, $16, $2B, $9F, $67, $CF, $65, $3B, $BB,
$25, $C3, $6E, $72, $6A, $DD, $C2, $06, $C1, $10, $AD, $EC, $CE, $5F, $F6, $00,
$03, $EA, $29, $FF, $83, $A9, $92, $A7, $53, $71, $7E, $61, $35, $43, $5D, $B8,
$D4, $A4, $A2, $F2, $2D, $30, $DC, $1E, $5C, $88, $57, $24, $E2, $7A, $E1, $48,
$4A, $98, $38, $CA, $5E, $13, $62, $A0, $D5, $F9, $C7, $8B, $54, $80, $BA, $81,
$66, $A5, $F5, $1A, $CB, $6D, $D0, $E3, $F7, $C5, $09, $C6, $23, $20, $55, $94,
$B5, $74, $2C, $26, $1B, $01, $BF, $14, $93, $56, $42, $40, $D3, $B9, $39, $FE,
$8D, $E5, $12, $3A, $3F, $AB, $0B, $ED, $FC, $44, $85, $5A, $DB, $DA, $FB, $7B,
$B1, $63, $9D, $0C, $B3, $8E, $46, $45, $F8, $68, $BD, $77, $FA, $9B, $69, $75,
$76, $36, $99, $79, $FD, $91, $70, $3D, $08, $22, $95, $B0, $F4, $B4, $0E, $64,
$89, $F0, $C9, $2F, $97, $52, $86, $D8, $CC, $4E, $60, $8A, $8C, $4F, $B2, $4B,
$84, $2E, $AC, $A1, $32, $E6, $0D, $9A, $3C, $1D, $15, $1F, $6B, $73, $9E, $D2), (
$BE, $B5, $90, $5C, $C9, $3A, $23, $DF, $78, $00, $F1, $E7, $B8, $ED, $FB, $B3,
$1F, $F6, $6C, $12, $88, $32, $E8, $1C, $C8, $07, $5A, $C2, $25, $65, $B7, $CE,
$47, $CD, $70, $4B, $FC, $53, $DB, $93, $EF, $AB, $6A, $92, $39, $02, $56, $81,
$5E, $51, $1D, $30, $35, $7C, $5F, $A9, $BF, $29, $0A, $76, $DA, $DC, $67, $46,
$96, $19, $10, $0C, $9F, $C1, $43, $3F, $57, $74, $F3, $44, $79, $F7, $BA, $E4,
$6D, $F9, $4A, $34, $8D, $D5, $D8, $2A, $63, $05, $0B, $0E, $2D, $CC, $01, $18,
$D4, $EA, $E9, $31, $94, $15, $AA, $F8, $E1, $C3, $E6, $59, $91, $69, $48, $6E,
$20, $4D, $55, $45, $8A, $11, $66, $16, $F5, $1E, $03, $B1, $21, $9A, $38, $8B,
$D6, $CB, $F2, $D2, $B4, $4E, $3E, $D3, $2E, $EE, $24, $FE, $C5, $77, $33, $E2,
$54, $2C, $C6, $41, $BD, $17, $A0, $13, $D0, $40, $F0, $50, $A3, $EC, $CF, $FF,
$99, $DD, $D1, $09, $61, $AD, $1A, $AF, $89, $CA, $EB, $A5, $84, $8E, $3C, $3B,
$A4, $B0, $82, $8F, $83, $A1, $1B, $E5, $9C, $C0, $7A, $95, $3D, $52, $26, $9B,
$C4, $42, $7F, $F4, $9E, $08, $AC, $72, $D9, $0D, $AE, $FD, $FA, $49, $A7, $D7,
$B6, $62, $36, $68, $4F, $0F, $C7, $2F, $22, $BB, $9D, $04, $BC, $B2, $A8, $27,
$E3, $14, $A6, $7B, $06, $64, $28, $6B, $80, $A2, $97, $87, $73, $7D, $75, $8C,
$60, $85, $7E, $5D, $5B, $58, $37, $2B, $E0, $6F, $4C, $71, $86, $98, $B9, $DE));
//SUBSTITUTION BOXES' INVERSE FOR EACH ROUND
S1: array[0..15, 0..255] of longword = ((
$89, $72, $9C, $D4, $4A, $46, $3D, $1A, $6B, $B2, $2E, $5A, $52, $04, $C6, $4D,
$2A, $6A, $7D, $E0, $B7, $BB, $5F, $10, $B4, $B0, $15, $18, $3C, $47, $8E, $D5,
$3E, $07, $B6, $17, $20, $E6, $8C, $9F, $99, $73, $64, $E9, $84, $F9, $44, $D3,
$AE, $C7, $12, $39, $FA, $E2, $30, $F4, $27, $62, $66, $1C, $2F, $EF, $83, $4B,
$F8, $DD, $E3, $65, $60, $0E, $3F, $29, $68, $38, $D2, $FB, $6C, $CA, $74, $82,
$21, $BF, $79, $C2, $87, $C9, $7A, $F2, $E8, $25, $DE, $36, $4F, $77, $5D, $51,
$A7, $AF, $AD, $76, $16, $A5, $EC, $F5, $00, $D6, $C1, $9A, $8A, $4C, $1D, $EA,
$A8, $53, $D8, $23, $E1, $34, $C8, $94, $A6, $B5, $F6, $A4, $03, $DF, $69, $81,
$C0, $7E, $A9, $90, $0A, $95, $48, $55, $40, $C3, $8B, $6F, $DB, $1F, $35, $57,
$E5, $7F, $BE, $2C, $CC, $70, $9D, $09, $AB, $ED, $32, $37, $CB, $01, $59, $91,
$CE, $1B, $0B, $56, $3B, $FC, $E4, $14, $02, $78, $31, $5B, $58, $45, $DA, $5E,
$9E, $33, $B1, $96, $BA, $88, $75, $26, $19, $AA, $AC, $7C, $08, $0F, $F7, $9B,
$71, $06, $EB, $FD, $24, $7B, $F0, $E7, $3A, $F1, $8F, $6D, $43, $D0, $F3, $98,
$D7, $B9, $4E, $28, $C4, $13, $A3, $92, $11, $B8, $FE, $50, $A2, $2D, $0C, $1E,
$C5, $05, $DC, $54, $CD, $BC, $61, $2B, $EE, $B3, $5C, $86, $93, $6E, $0D, $49,
$D9, $85, $97, $D1, $22, $BD, $A1, $80, $A0, $67, $41, $63, $42, $FF, $CF, $8D), (
$EB, $C4, $80, $69, $AE, $2C, $2E, $1C, $7F, $DA, $06, $7A, $1E, $A5, $AF, $DE,
$47, $39, $21, $E0, $E1, $10, $9C, $17, $26, $3B, $04, $14, $4C, $86, $CF, $23,
$6A, $8B, $AD, $93, $66, $C1, $E2, $1F, $5E, $E3, $18, $60, $AB, $C5, $73, $BA,
$E4, $CC, $62, $DB, $3A, $AC, $CE, $4D, $E5, $B8, $74, $09, $CB, $3C, $3F, $A3,
$75, $30, $A9, $B4, $A7, $0E, $4E, $40, $F6, $B9, $95, $48, $11, $EF, $67, $82,
$D9, $B1, $9F, $53, $0D, $F4, $2A, $19, $D2, $6C, $CD, $94, $2D, $F1, $92, $C8,
$33, $99, $E6, $98, $E9, $96, $02, $C0, $2F, $BB, $6F, $0B, $5A, $9A, $36, $31,
$8E, $BF, $E8, $0C, $F5, $0F, $C6, $64, $00, $C7, $F9, $27, $A1, $88, $BC, $4B,
$91, $6B, $1B, $8D, $58, $5B, $76, $CA, $20, $71, $C3, $C2, $57, $01, $EE, $24,
$7D, $F8, $85, $FD, $32, $9B, $A0, $87, $D1, $8A, $5C, $8C, $05, $68, $0A, $D0,
$AA, $D8, $B2, $16, $DC, $22, $51, $70, $97, $D4, $F0, $4A, $8F, $D7, $72, $B5,
$81, $13, $41, $83, $A6, $12, $44, $FA, $DF, $B6, $FE, $D5, $FB, $A4, $FF, $BE,
$84, $90, $9E, $35, $6E, $1D, $34, $59, $ED, $F3, $D3, $DD, $F2, $03, $55, $45,
$7E, $79, $25, $28, $B0, $5D, $38, $50, $08, $29, $F7, $42, $5F, $D6, $6D, $EA,
$15, $3E, $37, $C9, $78, $3D, $89, $7C, $7B, $52, $56, $63, $B3, $A8, $4F, $B7,
$1A, $9D, $65, $BD, $43, $46, $FC, $EC, $77, $2B, $49, $07, $E7, $54, $A2, $61), (
$83, $58, $4D, $CE, $3E, $0D, $AB, $CB, $BD, $A2, $24, $97, $EA, $D6, $20, $85,
$55, $A6, $EB, $9D, $45, $71, $48, $86, $7D, $B9, $12, $38, $60, $14, $B3, $90,
$03, $95, $6D, $C6, $E7, $7A, $B8, $2F, $23, $AA, $EC, $65, $B2, $68, $8B, $54,
$15, $96, $4F, $AF, $ED, $D4, $53, $DF, $D7, $80, $2A, $9E, $C8, $18, $93, $BE,
$8F, $69, $74, $3C, $EE, $87, $3F, $D3, $EF, $1A, $E3, $17, $52, $1B, $02, $49,
$C4, $70, $9F, $30, $31, $0F, $F0, $F1, $8A, $F2, $DE, $4C, $1C, $9B, $13, $89,
$C5, $A1, $B0, $28, $46, $C9, $E6, $42, $E4, $D5, $4B, $67, $E1, $19, $75, $5F,
$76, $78, $9A, $F3, $00, $A5, $9C, $1E, $6C, $3B, $06, $8D, $2E, $29, $E8, $5C,
$0A, $B4, $E5, $27, $BA, $7E, $7B, $34, $B5, $E9, $7C, $01, $F4, $59, $F8, $C0,
$B6, $6F, $62, $5D, $A7, $D1, $A4, $64, $7F, $3A, $5E, $98, $92, $DC, $FD, $1D,
$91, $3D, $B7, $61, $51, $22, $56, $0C, $CD, $37, $0E, $C1, $04, $32, $4A, $66,
$63, $C2, $40, $21, $41, $B1, $F5, $FE, $E0, $8E, $47, $FF, $73, $C3, $0B, $50,
$79, $6E, $FB, $88, $2D, $8C, $10, $E2, $A0, $DB, $D2, $77, $AC, $43, $AE, $A8,
$A9, $1F, $A3, $33, $DA, $84, $09, $F7, $BC, $FC, $16, $D8, $D0, $4E, $11, $AD,
$26, $2C, $08, $BB, $D9, $82, $F6, $2B, $05, $CF, $99, $6B, $CA, $5A, $F9, $07,
$DD, $72, $94, $BF, $81, $44, $25, $FA, $39, $35, $57, $6A, $C7, $CC, $36, $5B), (
$50, $92, $39, $3E, $D4, $E4, $F1, $0C, $C1, $4B, $F2, $F3, $22, $75, $2E, $5A,
$E0, $7E, $DE, $C5, $8A, $4F, $16, $BC, $A9, $13, $61, $E2, $76, $93, $F4, $C4,
$F5, $DF, $83, $3A, $9B, $1F, $B5, $B4, $68, $36, $B6, $62, $F6, $B2, $0A, $C0,
$A1, $7C, $60, $8D, $0B, $F7, $10, $1A, $CA, $D6, $56, $AF, $20, $28, $05, $21,
$CC, $AD, $8E, $BE, $71, $5F, $BF, $87, $1C, $E7, $A7, $F8, $35, $2F, $06, $0D,
$11, $84, $2B, $AB, $4E, $DC, $F9, $14, $FA, $DD, $AC, $6F, $EE, $3B, $2D, $6C,
$A5, $72, $1D, $73, $18, $9C, $29, $5B, $08, $31, $9F, $42, $C7, $FB, $63, $55,
$FC, $53, $BD, $12, $88, $4C, $4D, $D8, $D3, $EB, $74, $54, $38, $7D, $FD, $9D,
$7F, $A0, $6B, $45, $D5, $66, $E1, $B3, $C6, $C8, $7A, $98, $A8, $32, $C9, $52,
$95, $C2, $91, $04, $2C, $FE, $ED, $3F, $7B, $07, $01, $A2, $94, $B7, $3C, $49,
$24, $37, $CB, $89, $B8, $E5, $79, $80, $82, $1E, $FF, $0F, $3D, $33, $CE, $47,
$6E, $64, $2A, $A6, $AE, $40, $AA, $A3, $5C, $99, $43, $69, $BB, $97, $65, $DA,
$27, $58, $6A, $23, $CD, $02, $46, $67, $5D, $E3, $1B, $E9, $09, $EF, $57, $BA,
$B0, $0E, $9E, $26, $B9, $70, $41, $19, $90, $F0, $51, $EC, $44, $8F, $00, $25,
$C3, $EA, $85, $77, $A4, $D7, $8C, $D1, $D9, $9A, $96, $81, $D2, $5E, $E8, $34,
$30, $59, $4A, $B1, $86, $15, $48, $78, $17, $DB, $CF, $03, $E6, $6D, $D0, $8B), (
$A3, $78, $01, $13, $5E, $CE, $DF, $50, $46, $DA, $61, $97, $B4, $4E, $CD, $0E,
$9B, $86, $30, $4D, $34, $AB, $42, $11, $D2, $76, $8E, $72, $07, $66, $7F, $7D,
$A4, $39, $C3, $C5, $77, $B1, $8A, $0D, $AE, $03, $22, $93, $65, $E0, $2D, $83,
$AC, $36, $2A, $D3, $25, $26, $5C, $BE, $53, $92, $85, $4B, $19, $2F, $17, $E5,
$C9, $0F, $68, $8B, $E6, $E7, $E8, $73, $3C, $6B, $33, $9A, $E9, $C6, $EA, $55,
$2C, $79, $DE, $7A, $10, $B2, $A7, $89, $EB, $B8, $FA, $45, $D0, $38, $1C, $B3,
$56, $43, $84, $3D, $06, $1A, $57, $7E, $A6, $0A, $82, $1F, $FD, $29, $FE, $AA,
$8F, $80, $15, $27, $75, $62, $FF, $08, $09, $6F, $2B, $91, $AD, $1B, $E1, $E4,
$EE, $59, $BB, $67, $EF, $02, $DB, $40, $EC, $F7, $2E, $3E, $3B, $F5, $DC, $35,
$F1, $B9, $3F, $4A, $4C, $B0, $52, $CF, $F8, $D1, $8C, $BD, $6E, $F2, $4F, $F3,
$12, $70, $B7, $BF, $64, $47, $32, $04, $C4, $96, $A9, $94, $A0, $A5, $00, $87,
$24, $88, $5B, $58, $D6, $6D, $D8, $C7, $F6, $99, $28, $14, $41, $6A, $54, $63,
$B6, $69, $C2, $CA, $60, $BA, $18, $90, $E3, $6C, $3A, $8D, $98, $A1, $51, $BC,
$81, $D9, $9F, $A8, $74, $CC, $D4, $0C, $71, $B5, $49, $FB, $D7, $1D, $9C, $ED,
$FC, $20, $37, $44, $9D, $AF, $31, $48, $16, $21, $7B, $E2, $23, $7C, $A2, $F9,
$5A, $D5, $95, $DD, $0B, $C1, $F4, $1E, $F0, $C0, $C8, $05, $9E, $5F, $5D, $CB), (
$3D, $DE, $98, $75, $44, $B3, $A2, $E5, $CD, $A4, $E6, $E7, $4E, $D6, $2F, $68,
$6E, $78, $61, $4D, $87, $33, $99, $E8, $29, $E9, $6F, $C0, $12, $83, $BB, $0A,
$2B, $B4, $B7, $8C, $BE, $E1, $73, $86, $D0, $28, $9C, $2D, $14, $EA, $C1, $5F,
$8B, $80, $21, $B0, $1D, $A0, $EB, $60, $93, $B8, $B1, $E3, $1C, $A3, $A5, $95,
$18, $D4, $7D, $1E, $6B, $2E, $56, $AE, $19, $89, $20, $91, $7C, $F9, $EE, $3A,
$81, $5C, $8D, $6A, $C8, $31, $53, $CE, $A1, $E2, $C2, $23, $08, $F1, $00, $CA,
$4F, $4C, $DD, $01, $F5, $7A, $B5, $63, $F3, $BA, $05, $C6, $F7, $D1, $97, $50,
$B9, $24, $2C, $02, $9A, $BD, $DA, $FC, $10, $BF, $70, $D8, $8F, $3B, $90, $6C,
$48, $74, $62, $32, $82, $3F, $7E, $B6, $45, $1A, $FB, $57, $59, $38, $06, $AA,
$FD, $0F, $72, $A7, $AC, $16, $9D, $0D, $F8, $4A, $A9, $71, $22, $51, $8E, $F2,
$EC, $03, $C3, $DF, $B2, $37, $66, $35, $C7, $DB, $54, $69, $F4, $52, $47, $25,
$17, $0C, $84, $67, $41, $40, $85, $EF, $46, $FF, $92, $4B, $94, $7B, $D5, $1F,
$2A, $07, $42, $3C, $49, $77, $C4, $C5, $30, $F0, $64, $9B, $DC, $AF, $1B, $88,
$FA, $8A, $27, $3E, $AB, $15, $C9, $0B, $09, $43, $79, $36, $D2, $76, $D9, $65,
$7F, $9E, $A6, $9F, $5D, $34, $5E, $39, $A8, $6D, $CC, $11, $E0, $ED, $96, $D3,
$FE, $55, $58, $F6, $AD, $5A, $CB, $5B, $E4, $BC, $13, $0E, $D7, $26, $04, $CF), (
$E9, $31, $71, $D8, $BC, $88, $A9, $9B, $AF, $80, $37, $53, $97, $61, $86, $AA,
$9D, $33, $60, $9A, $93, $2C, $5D, $D9, $DA, $66, $67, $0B, $DB, $C8, $3F, $5A,
$CA, $94, $DC, $3B, $D5, $21, $62, $DD, $D7, $41, $22, $28, $E4, $3D, $DF, $56,
$B9, $0F, $2A, $50, $4A, $44, $E8, $38, $54, $AD, $6D, $A7, $02, $30, $12, $D2,
$1F, $7F, $ED, $C5, $29, $69, $0E, $BA, $7D, $95, $4C, $F1, $45, $00, $EE, $24,
$7C, $8B, $B8, $AE, $68, $B7, $E1, $F2, $BD, $85, $E5, $35, $5E, $F8, $2E, $A3,
$10, $B3, $E6, $46, $1C, $6E, $99, $C3, $1D, $EA, $83, $CE, $64, $F9, $76, $B0,
$CD, $C2, $E7, $C1, $73, $BE, $0C, $70, $8A, $B6, $3C, $FB, $79, $18, $96, $39,
$58, $81, $63, $E0, $8E, $DE, $6F, $8D, $26, $4D, $47, $20, $FC, $7B, $EB, $36,
$FD, $5C, $49, $48, $A2, $82, $04, $74, $13, $1A, $5F, $9E, $51, $06, $09, $D4,
$B5, $6C, $F4, $08, $32, $CC, $40, $F3, $8C, $E3, $FE, $A6, $C9, $57, $EF, $D0,
$7A, $72, $01, $A5, $4B, $BB, $FF, $A4, $19, $05, $34, $1E, $75, $5B, $C4, $CF,
$89, $9C, $92, $07, $4E, $2D, $E2, $A0, $11, $90, $F7, $EC, $D1, $9F, $B1, $77,
$15, $AC, $B2, $D3, $C6, $84, $8F, $F0, $6B, $C7, $CB, $27, $D6, $C0, $23, $65,
$3A, $59, $16, $87, $F6, $25, $03, $B4, $91, $A1, $55, $2B, $98, $0D, $3E, $F5,
$43, $2F, $FA, $6A, $78, $BF, $4F, $42, $17, $AB, $52, $A8, $7E, $1B, $0A, $14), (
$DA, $77, $6A, $68, $9E, $0C, $F6, $72, $91, $47, $7E, $EF, $00, $16, $76, $EA,
$ED, $9C, $3B, $9B, $7C, $B7, $24, $58, $20, $6F, $B2, $3E, $C4, $61, $5D, $43,
$67, $F7, $4A, $C3, $1E, $F4, $83, $5C, $92, $AC, $F8, $86, $5F, $39, $A4, $CB,
$D4, $26, $F9, $A1, $29, $E9, $74, $B9, $C7, $57, $FA, $22, $71, $0F, $07, $7A,
$81, $B6, $2C, $88, $A9, $E1, $95, $18, $C6, $A8, $9F, $37, $A0, $6B, $9D, $04,
$96, $78, $8D, $84, $E2, $CA, $01, $4F, $B0, $49, $21, $BF, $E6, $70, $FB, $CD,
$80, $8F, $F2, $1B, $69, $19, $2B, $12, $51, $66, $A2, $54, $D3, $DC, $73, $AA,
$F0, $28, $EE, $08, $3A, $17, $93, $25, $D2, $34, $94, $63, $97, $06, $6D, $41,
$CF, $85, $D6, $A5, $4D, $0B, $DE, $55, $AE, $BC, $42, $48, $15, $B4, $C1, $1D,
$B1, $4E, $32, $7F, $65, $0E, $E7, $C8, $09, $38, $9A, $C5, $EC, $E0, $D9, $5E,
$F3, $A3, $1C, $F1, $8E, $27, $89, $99, $0A, $3D, $E3, $05, $B8, $FC, $D7, $6E,
$5A, $46, $40, $87, $8B, $DD, $C9, $59, $A7, $CE, $A6, $FD, $BE, $E5, $60, $02,
$1F, $52, $DB, $98, $53, $AD, $8A, $36, $10, $D1, $13, $1A, $75, $3C, $EB, $82,
$45, $D5, $14, $11, $D8, $4C, $31, $C2, $B5, $E4, $30, $4B, $BD, $8C, $DF, $7D,
$62, $AB, $64, $2F, $2A, $CC, $C0, $BB, $5B, $AF, $D0, $F5, $35, $6C, $03, $2E,
$56, $33, $FE, $44, $0D, $7B, $90, $B3, $BA, $FF, $23, $E8, $2D, $79, $50, $3F), (
$C7, $67, $1D, $8B, $88, $6D, $4B, $3C, $DD, $CA, $2C, $A6, $CB, $97, $63, $E3,
$55, $F0, $E8, $DF, $65, $64, $6F, $B4, $95, $37, $50, $29, $E0, $F1, $42, $C4,
$59, $75, $EA, $5F, $93, $43, $D4, $27, $A3, $F2, $AC, $71, $54, $A8, $E1, $F3,
$46, $2F, $08, $47, $11, $D9, $02, $7E, $5A, $87, $8A, $DA, $9B, $CE, $D6, $EB,
$21, $3A, $BD, $5D, $74, $AB, $F4, $51, $1A, $79, $DE, $98, $BF, $5E, $33, $85,
$8F, $56, $18, $32, $8D, $C3, $6B, $3E, $F5, $B0, $F6, $28, $B1, $58, $91, $F7,
$81, $76, $AA, $2A, $92, $DC, $B5, $1B, $ED, $9C, $13, $D2, $68, $AE, $AD, $A4,
$7A, $09, $5B, $99, $44, $C8, $70, $B6, $BA, $BE, $12, $84, $22, $53, $01, $8E,
$31, $CC, $6C, $78, $03, $6A, $96, $61, $E5, $C1, $69, $B8, $AF, $F8, $0E, $05,
$16, $A5, $9F, $0A, $3D, $D7, $04, $1E, $4F, $4C, $24, $A9, $80, $D5, $40, $00,
$F9, $FA, $19, $C0, $C5, $17, $9A, $0B, $B7, $C9, $39, $7D, $2B, $A1, $86, $7F,
$EF, $EC, $D0, $BC, $4D, $CD, $2E, $CF, $15, $06, $0F, $66, $E7, $FB, $6E, $23,
$35, $52, $FE, $FC, $FD, $EE, $C6, $30, $77, $E6, $1C, $0C, $FF, $25, $89, $36,
$C2, $8C, $73, $10, $D8, $49, $D3, $94, $A7, $B2, $62, $26, $D1, $3F, $BB, $B9,
$3B, $38, $DB, $14, $9E, $83, $9D, $1F, $82, $A0, $5C, $48, $72, $34, $4E, $41,
$57, $E9, $7C, $2D, $A2, $E4, $20, $7B, $B3, $07, $0D, $90, $E2, $4A, $60, $45), (
$F4, $8A, $D0, $58, $E4, $26, $1B, $55, $92, $94, $54, $5D, $75, $82, $C9, $7F,
$02, $17, $0B, $73, $6C, $9D, $15, $E5, $CB, $7E, $12, $E6, $1C, $E7, $37, $81,
$22, $D9, $3E, $E8, $0A, $97, $38, $5A, $13, $78, $03, $4A, $7C, $B0, $1A, $E9,
$CD, $49, $DC, $AB, $EA, $27, $14, $A1, $0E, $C0, $B6, $25, $5C, $8D, $2B, $24,
$39, $1F, $05, $72, $B7, $C5, $3C, $6E, $D3, $64, $3F, $B4, $59, $5E, $EB, $20,
$EC, $F6, $BA, $6A, $60, $D1, $5F, $CE, $A2, $F2, $F1, $8E, $11, $34, $CC, $41,
$A6, $89, $FA, $7A, $AF, $87, $9E, $0F, $53, $6B, $56, $D5, $E0, $99, $42, $8C,
$DF, $B8, $63, $62, $7D, $DB, $DE, $43, $DA, $04, $2C, $31, $52, $47, $BF, $8B,
$FC, $FB, $D4, $09, $76, $07, $98, $90, $E3, $BE, $9C, $D8, $06, $01, $EE, $C4,
$DD, $A7, $CA, $4F, $C3, $A9, $FE, $85, $B1, $4C, $9B, $6D, $28, $4E, $BC, $0D,
$AE, $29, $51, $50, $BB, $18, $74, $79, $65, $96, $CF, $EF, $F3, $B3, $9A, $23,
$C1, $2F, $10, $A8, $AA, $66, $C7, $16, $93, $4B, $F7, $86, $67, $A3, $3D, $3B,
$6F, $84, $71, $88, $69, $57, $E2, $A0, $5B, $F5, $91, $C8, $95, $2D, $80, $61,
$46, $F9, $19, $C2, $D2, $7B, $D7, $AD, $F0, $08, $2A, $E1, $A5, $A4, $44, $83,
$70, $D6, $77, $32, $FD, $1E, $C6, $BD, $45, $0C, $9F, $B2, $AC, $36, $40, $00,
$FF, $68, $2E, $4D, $21, $33, $48, $F8, $B9, $3A, $30, $B5, $8F, $1D, $35, $ED), (
$EE, $1A, $7F, $D1, $B7, $74, $42, $BC, $77, $20, $D5, $EB, $BD, $E6, $A3, $A6,
$A0, $65, $85, $CF, $29, $30, $BF, $73, $A4, $F3, $52, $4F, $76, $D0, $E5, $E4,
$3D, $3B, $6B, $69, $2E, $F6, $2C, $CA, $1F, $25, $ED, $59, $58, $36, $1D, $F7,
$37, $C4, $61, $43, $4A, $8E, $1C, $5A, $5D, $F0, $16, $7E, $EA, $75, $19, $AD,
$C3, $70, $F1, $17, $06, $93, $57, $F8, $CE, $C7, $0C, $0F, $7A, $09, $3C, $08,
$27, $86, $56, $9B, $C5, $B1, $0D, $F9, $10, $55, $3F, $7C, $A1, $54, $68, $BE,
$8C, $F5, $8A, $C1, $FA, $91, $9C, $22, $66, $D7, $E3, $32, $07, $94, $40, $EC,
$8B, $41, $87, $F4, $44, $CB, $A9, $BB, $2A, $28, $CC, $33, $6C, $EF, $82, $B9,
$79, $C0, $B2, $78, $D6, $47, $BA, $35, $00, $3A, $04, $63, $90, $39, $95, $FB,
$C8, $6D, $0B, $50, $DE, $5E, $34, $2B, $9A, $8F, $5F, $38, $2D, $7D, $E2, $46,
$4E, $24, $DF, $DC, $0E, $FC, $AB, $03, $A5, $97, $AA, $B4, $1B, $2F, $9E, $62,
$A7, $4D, $67, $9F, $DD, $C6, $B5, $02, $DA, $D9, $84, $F2, $60, $48, $4C, $92,
$DB, $81, $6F, $21, $80, $B8, $D8, $C2, $3E, $B3, $98, $5B, $E9, $CD, $05, $51,
$B6, $D3, $7B, $23, $9D, $11, $AE, $E0, $6A, $D2, $64, $4B, $E7, $96, $26, $01,
$53, $FD, $45, $E8, $6E, $89, $D4, $B0, $13, $31, $8D, $49, $A8, $72, $71, $18,
$99, $FE, $1E, $83, $15, $AC, $AF, $A2, $14, $E1, $FF, $5C, $12, $0A, $88, $C9), (
$23, $94, $5B, $51, $CE, $D2, $E0, $05, $A7, $06, $4D, $B2, $6E, $95, $AF, $29,
$BA, $13, $E1, $E2, $5E, $B6, $E5, $4A, $50, $F5, $43, $26, $B5, $18, $83, $22,
$57, $2F, $8C, $A3, $5F, $89, $04, $D3, $0A, $C2, $FA, $C0, $2A, $74, $37, $DA,
$45, $D4, $0F, $77, $27, $3D, $C6, $53, $CC, $DF, $A6, $9F, $9D, $C8, $E7, $2E,
$1A, $F6, $DE, $F1, $7C, $15, $0E, $47, $62, $52, $5C, $7D, $41, $2D, $E8, $D8,
$4C, $A8, $DC, $71, $FC, $1C, $FD, $4F, $CB, $E3, $72, $BD, $1F, $7F, $D9, $09,
$B8, $00, $1B, $75, $0C, $59, $16, $92, $6B, $3F, $93, $97, $F8, $CF, $30, $A5,
$02, $3B, $11, $66, $BC, $60, $25, $ED, $28, $EF, $61, $D7, $F9, $DD, $86, $C3,
$48, $73, $90, $32, $AC, $5A, $F3, $AD, $40, $F0, $88, $08, $B4, $19, $9E, $33,
$49, $0D, $EA, $CD, $20, $79, $FB, $2C, $65, $17, $12, $35, $84, $87, $36, $BE,
$B1, $63, $24, $C9, $3C, $4B, $AE, $EB, $8B, $9B, $98, $6C, $9A, $F2, $80, $D1,
$34, $8A, $C1, $6D, $82, $D0, $DB, $7E, $8E, $B9, $31, $1E, $7A, $44, $E9, $91,
$14, $01, $68, $4E, $39, $A4, $AA, $46, $A2, $96, $99, $58, $64, $E6, $56, $D5,
$8F, $CA, $6F, $76, $54, $03, $AB, $E4, $3E, $8D, $5D, $42, $85, $9C, $78, $F4,
$10, $B7, $B3, $D6, $A9, $0B, $21, $6A, $BB, $C4, $EE, $07, $81, $BF, $1D, $FE,
$38, $FF, $7B, $EC, $C7, $A0, $2B, $C5, $55, $A1, $69, $B0, $70, $67, $F7, $3A), (
$6D, $5E, $46, $E1, $06, $E2, $1F, $7C, $38, $01, $B6, $A9, $26, $CD, $97, $82,
$E3, $CC, $B3, $67, $E4, $70, $48, $D4, $8A, $C2, $35, $83, $7A, $99, $C7, $22,
$9D, $37, $B4, $64, $58, $AB, $95, $7F, $18, $8C, $E5, $68, $5F, $B9, $71, $0D,
$D5, $72, $E6, $20, $69, $F5, $3A, $45, $9F, $28, $D7, $F1, $2C, $62, $D9, $91,
$A7, $1C, $BC, $9B, $B0, $73, $60, $F9, $EE, $AE, $59, $04, $24, $B5, $BE, $36,
$2B, $33, $93, $B7, $17, $4C, $FB, $A0, $65, $40, $D0, $85, $A1, $E9, $92, $5B,
$C0, $50, $66, $53, $15, $21, $DD, $5C, $6F, $E7, $3C, $B2, $49, $B8, $05, $CA,
$6E, $C5, $F2, $2E, $D6, $7B, $09, $88, $C6, $A4, $BA, $8B, $2A, $A6, $3F, $BF,
$23, $76, $3D, $11, $DC, $EB, $3E, $E0, $DA, $F6, $F8, $3B, $CE, $94, $6B, $0A,
$29, $2F, $30, $9A, $A2, $41, $12, $5A, $51, $00, $DF, $19, $E8, $EA, $1B, $61,
$63, $96, $31, $79, $74, $98, $A3, $0C, $39, $10, $B1, $ED, $CB, $C8, $F3, $C3,
$4A, $47, $1A, $16, $DE, $43, $27, $9C, $2D, $4D, $56, $84, $AD, $AF, $90, $D8,
$FA, $CF, $57, $BD, $FD, $32, $54, $34, $13, $4B, $C9, $80, $D3, $1E, $81, $87,
$07, $6C, $6A, $DB, $52, $8F, $42, $C4, $0F, $89, $7E, $FE, $AA, $F4, $4E, $1D,
$25, $EF, $D2, $03, $FF, $F7, $EC, $D1, $C1, $A5, $0B, $0E, $75, $5D, $02, $8D,
$7D, $9E, $86, $78, $77, $4F, $08, $14, $BB, $A8, $F0, $8E, $44, $AC, $55, $FC), (
$E9, $E1, $07, $AD, $E2, $F8, $F5, $B7, $FC, $49, $13, $48, $D9, $E5, $DE, $87,
$42, $99, $11, $01, $91, $E3, $43, $3B, $EA, $09, $50, $F7, $33, $C3, $A3, $73,
$D8, $39, $E8, $E4, $80, $F6, $96, $D3, $6A, $98, $FB, $EF, $2E, $1D, $0D, $81,
$54, $20, $E6, $9E, $1E, $72, $1A, $C7, $40, $C0, $88, $9F, $FD, $7D, $A1, $D2,
$92, $84, $4E, $9B, $51, $F0, $68, $8F, $70, $FA, $9A, $EB, $FF, $94, $A6, $12,
$57, $BC, $04, $0C, $4B, $63, $21, $3C, $95, $02, $2C, $90, $F2, $79, $F3, $E0,
$CF, $A8, $23, $15, $3D, $37, $52, $CB, $18, $B6, $47, $53, $CA, $41, $60, $6C,
$D1, $26, $65, $55, $6E, $3F, $7C, $9C, $B1, $F4, $AC, $D6, $56, $34, $8E, $A5,
$0F, $00, $BA, $D5, $66, $D4, $DC, $0B, $A2, $C1, $67, $F1, $2B, $2F, $7E, $85,
$30, $32, $03, $BB, $4A, $4F, $C9, $86, $ED, $58, $16, $14, $62, $59, $5A, $B2,
$AE, $C4, $46, $61, $24, $A0, $6B, $7A, $EC, $5B, $7B, $B5, $76, $5F, $6D, $DF,
$29, $D0, $3E, $2A, $CD, $A4, $31, $08, $DA, $8A, $B0, $71, $CE, $8D, $4D, $06,
$4C, $AF, $FE, $97, $5D, $36, $D7, $C5, $1C, $44, $F9, $19, $75, $C8, $DB, $10,
$7F, $77, $69, $1F, $25, $CC, $BD, $74, $2D, $8C, $AA, $28, $83, $78, $8B, $89,
$A7, $C2, $5E, $17, $05, $45, $AB, $35, $B4, $B9, $B3, $82, $1B, $27, $64, $9D,
$38, $BE, $0E, $6F, $22, $E7, $DD, $C6, $A9, $B8, $3A, $5C, $93, $0A, $EE, $BF), (
$5F, $A5, $04, $60, $09, $3E, $57, $23, $D8, $9A, $1C, $B6, $C3, $F6, $DE, $03,
$59, $13, $B2, $85, $A7, $FA, $48, $10, $15, $2E, $93, $A4, $14, $F9, $77, $FB,
$9D, $3F, $D9, $9C, $7B, $50, $A3, $3B, $3A, $62, $29, $49, $A2, $74, $F1, $E3,
$75, $33, $F4, $43, $2A, $6C, $D1, $0A, $82, $AE, $B3, $4E, $F8, $D7, $1F, $B4,
$AB, $00, $AA, $6D, $B9, $C7, $C6, $07, $7F, $20, $80, $EF, $0B, $45, $E9, $ED,
$1B, $36, $E5, $68, $8C, $9E, $A9, $7A, $19, $1D, $BB, $11, $78, $6E, $84, $5D,
$EA, $6B, $86, $C1, $DF, $4D, $90, $4B, $C9, $CE, $54, $FC, $17, $95, $52, $05,
$D6, $69, $53, $FD, $A1, $CF, $D0, $CB, $41, $D3, $7D, $BF, $2D, $47, $6A, $02,
$8D, $8F, $28, $64, $F0, $BA, $E6, $1A, $79, $E0, $EB, $8B, $EC, $B0, $C5, $3C,
$21, $D5, $66, $A8, $9F, $DA, $16, $E4, $81, $D2, $F7, $CD, $30, $C2, $FE, $4A,
$87, $F3, $72, $0D, $71, $91, $44, $67, $3D, $65, $37, $B5, $F2, $5A, $27, $18,
$DB, $C0, $EE, $C4, $DD, $A0, $0F, $40, $6F, $AD, $8E, $4F, $0E, $CA, $32, $A6,
$2F, $58, $56, $51, $06, $99, $9B, $8A, $2B, $E2, $83, $94, $E8, $26, $5C, $4C,
$96, $31, $FF, $AC, $70, $88, $35, $25, $E7, $08, $BD, $BC, $76, $55, $46, $22,
$2C, $7E, $7C, $97, $12, $B1, $F5, $34, $42, $1E, $61, $01, $5B, $B7, $38, $0C,
$E1, $24, $73, $39, $DC, $92, $5E, $98, $C8, $89, $CC, $BE, $B8, $D4, $AF, $63), (
$09, $5E, $2D, $7A, $DB, $59, $E4, $19, $C5, $A3, $3A, $5A, $43, $C9, $5B, $D5,
$42, $75, $13, $97, $E1, $65, $77, $95, $5F, $41, $A6, $B6, $17, $32, $79, $10,
$70, $7C, $D8, $06, $8A, $1C, $BE, $DF, $E6, $39, $57, $F7, $91, $5C, $88, $D7,
$33, $63, $15, $8E, $53, $34, $D2, $F6, $7E, $2C, $05, $AF, $AE, $BC, $86, $47,
$99, $93, $C1, $46, $4B, $73, $3F, $20, $6E, $CD, $52, $23, $FA, $71, $85, $D4,
$9B, $31, $BD, $25, $90, $72, $2E, $48, $F5, $6B, $1A, $F4, $03, $F3, $30, $36,
$F0, $A4, $D1, $58, $E5, $1D, $76, $3E, $D3, $6D, $2A, $E7, $12, $50, $6F, $F9,
$22, $FB, $C7, $EC, $49, $EE, $3B, $8D, $08, $4C, $BA, $E3, $35, $ED, $F2, $C2,
$E8, $2F, $B2, $B4, $AC, $F1, $FC, $EB, $14, $A8, $74, $7F, $EF, $54, $AD, $B3,
$02, $6C, $2B, $27, $64, $BB, $40, $EA, $FD, $A0, $7D, $BF, $B8, $DA, $C4, $44,
$96, $B5, $E9, $9C, $B0, $AB, $E2, $CE, $DE, $37, $66, $29, $C6, $A5, $CA, $A7,
$B1, $7B, $DD, $0F, $84, $01, $D0, $1E, $0C, $FE, $4E, $D9, $DC, $94, $00, $38,
$B9, $45, $1B, $69, $C0, $8C, $92, $D6, $18, $04, $A9, $81, $5D, $21, $1F, $9E,
$98, $A2, $83, $87, $60, $55, $80, $CF, $56, $C8, $3C, $26, $3D, $A1, $FF, $07,
$F8, $68, $8F, $E0, $4F, $B7, $6A, $0B, $16, $62, $61, $AA, $9D, $0D, $89, $28,
$9A, $0A, $82, $4A, $C3, $78, $11, $4D, $67, $51, $CC, $0E, $24, $CB, $8B, $9F));
//RE-ORDERING MATRIX
P0: array[0..15, 0..15] of longword = (
($A, $3, $B, $C, $5, $E, $9, $F, $0, $7, $4, $6, $1, $D, $2, $8),
($9, $5, $F, $3, $1, $0, $A, $4, $7, $B, $E, $8, $2, $6, $D, $C),
($6, $D, $A, $4, $3, $5, $2, $8, $B, $F, $9, $C, $0, $E, $7, $1),
($E, $7, $0, $D, $8, $B, $1, $3, $9, $6, $C, $4, $A, $2, $F, $5),
($C, $A, $2, $5, $F, $D, $7, $9, $4, $E, $6, $B, $8, $3, $1, $0),
($5, $9, $3, $8, $D, $6, $4, $C, $1, $0, $7, $2, $E, $B, $A, $F),
($0, $6, $4, $A, $7, $3, $B, $E, $2, $8, $5, $1, $D, $F, $C, $9),
($D, $F, $9, $0, $6, $2, $3, $1, $E, $C, $A, $5, $B, $8, $4, $7),
($1, $0, $C, $2, $9, $7, $6, $D, $3, $5, $8, $E, $F, $A, $B, $4),
($3, $8, $5, $7, $2, $C, $E, $B, $A, $9, $D, $F, $4, $1, $0, $6),
($F, $B, $D, $1, $C, $8, $0, $6, $5, $2, $3, $7, $9, $4, $E, $A),
($8, $E, $1, $9, $4, $F, $C, $5, $6, $D, $2, $A, $7, $0, $3, $B),
($4, $C, $7, $6, $E, $1, $5, $2, $F, $A, $B, $0, $3, $9, $8, $D),
($7, $2, $6, $B, $0, $4, $D, $A, $8, $1, $F, $3, $5, $C, $9, $E),
($2, $1, $8, $E, $B, $A, $F, $7, $D, $4, $0, $9, $C, $5, $6, $3),
($B, $4, $E, $F, $A, $9, $8, $0, $C, $3, $1, $D, $6, $7, $5, $2));
//RE-ORDERING MATRIX INVERSE
P1: array[0..15, 0..15] of longword = (
($8, $C, $E, $1, $A, $4, $B, $9, $F, $6, $0, $2, $3, $D, $5, $7),
($5, $4, $C, $3, $7, $1, $D, $8, $B, $0, $6, $9, $F, $E, $A, $2),
($C, $F, $6, $4, $3, $5, $0, $E, $7, $A, $2, $8, $B, $1, $D, $9),
($2, $6, $D, $7, $B, $F, $9, $1, $4, $8, $C, $5, $A, $3, $0, $E),
($F, $E, $2, $D, $8, $3, $A, $6, $C, $7, $1, $B, $0, $5, $9, $4),
($9, $8, $B, $2, $6, $0, $5, $A, $3, $1, $E, $D, $7, $4, $C, $F),
($0, $B, $8, $5, $2, $A, $1, $4, $9, $F, $3, $6, $E, $C, $7, $D),
($3, $7, $5, $6, $E, $B, $4, $F, $D, $2, $A, $C, $9, $0, $8, $1),
($1, $0, $3, $8, $F, $9, $6, $5, $A, $4, $D, $E, $2, $7, $B, $C),
($E, $D, $4, $0, $C, $2, $F, $3, $1, $9, $8, $7, $5, $A, $6, $B),
($6, $3, $9, $A, $D, $8, $7, $B, $5, $C, $F, $1, $4, $2, $E, $0),
($D, $2, $A, $E, $4, $7, $8, $C, $0, $3, $B, $F, $6, $9, $1, $5),
($B, $5, $7, $C, $0, $6, $3, $2, $E, $D, $9, $A, $1, $F, $4, $8),
($4, $9, $1, $B, $5, $C, $2, $0, $8, $E, $7, $3, $D, $6, $F, $A),
($A, $1, $0, $F, $9, $D, $E, $7, $2, $B, $5, $4, $C, $8, $3, $6),
($7, $A, $F, $9, $1, $E, $C, $D, $6, $5, $4, $0, $8, $B, $2, $3));
function Mul(const Factor1, Factor2: longword): longword;
var
Product: Int64;
Lhalf, Rhalf: longword;
begin
Product := Factor1 * Factor2;
if Product = 0 then
Result := 1 - Factor1 - Factor2
else
begin
Lhalf := Product shr 32;
Rhalf := Product and $FFFFFFFF;
Result := Rhalf - Lhalf;
if Rhalf < Lhalf then
Inc(Result);
end;
end;
procedure BravionEncrypt(var Context: TBravionContext; var B: TBravionBlock32);
var
Temp: array[0..15] of longword;
pB: ^TBravionBlock8;
CarryBit: longword;
i: integer;
begin
pB := @B;
with Context do
begin
//ALGORITHM PERMUTATION
B[0] := B[0] xor RK[PK[16], 0];
B[1] := B[1] xor RK[PK[17], 1];
B[2] := B[2] xor RK[PK[18], 2];
B[3] := B[3] xor RK[PK[19], 3];
for i := 0 to 15 do //16 ROUNDS
begin
//IRRATIONALIZE 8BIT GROUPS
CarryBit := (B[0] and 2147483648) shr 31;
B[0] := (B[0] shl 1) or ((B[1] and 2147483648) shr 31);
B[1] := (B[1] shl 1) or ((B[2] and 2147483648) shr 31);
B[2] := (B[2] shl 1) or ((B[3] and 2147483648) shr 31);
B[3] := (B[3] shl 1) or CarryBit;
//PERMUTATION
B[3] := B[3] xor (B[2] - RK[i, 3]);
B[2] := B[2] xor Mul(B[1], RK[i, 2]);
B[1] := B[1] xor (B[0] + RK[i, 1]);
B[0] := B[0] xor RK[i, 0];
//SUBSTITUTION
{if anyone can optimize the following 20 lines please post it as a comment.
Bellow may seem slow, but it's MUCH faster than using Temp as a byte array
and Move(Temp,B,16). This is probably because the compiler is optimized for 32bit integers. An assembly version would be VERY fast.}
Temp[0] := S0[i, pB^[P0[PK[i], 0]]];
Temp[1] := S0[i, pB^[P0[PK[i], 1]]];
Temp[2] := S0[i, pB^[P0[PK[i], 2]]];
Temp[3] := S0[i, pB^[P0[PK[i], 3]]];
Temp[4] := S0[i, pB^[P0[PK[i], 4]]];
Temp[5] := S0[i, pB^[P0[PK[i], 5]]];
Temp[6] := S0[i, pB^[P0[PK[i], 6]]];
Temp[7] := S0[i, pB^[P0[PK[i], 7]]];
Temp[8] := S0[i, pB^[P0[PK[i], 8]]];
Temp[9] := S0[i, pB^[P0[PK[i], 9]]];
Temp[10] := S0[i, pB^[P0[PK[i], 10]]];
Temp[11] := S0[i, pB^[P0[PK[i], 11]]];
Temp[12] := S0[i, pB^[P0[PK[i], 12]]];
Temp[13] := S0[i, pB^[P0[PK[i], 13]]];
Temp[14] := S0[i, pB^[P0[PK[i], 14]]];
Temp[15] := S0[i, pB^[P0[PK[i], 15]]];
B[0] := (Temp[3] shl 24) or (Temp[2] shl 16) or (Temp[1] shl 8) or Temp[0];
B[1] := (Temp[7] shl 24) or (Temp[6] shl 16) or (Temp[5] shl 8) or Temp[4];
B[2] := (Temp[11] shl 24) or (Temp[10] shl 16) or (Temp[9] shl 8) or Temp[8];
B[3] := (Temp[15] shl 24) or (Temp[14] shl 16) or (Temp[13] shl 8) or Temp[12];
end;
//ALGORITHM PERMUTATION
B[0] := B[0] xor RK[PK[20], 0];
B[1] := B[1] xor RK[PK[21], 1];
B[2] := B[2] xor RK[PK[22], 2];
B[3] := B[3] xor RK[PK[23], 3];
end;
end;
procedure BravionDecrypt(var Context: TBravionContext; var B: TBravionBlock32);
var
Temp: array[0..15] of longword;
pB: ^TBravionBlock8;
CarryBit: longword;
i: integer;
begin
pB := @B;
with Context do
begin
B[3] := B[3] xor RK[PK[23], 3];
B[2] := B[2] xor RK[PK[22], 2];
B[1] := B[1] xor RK[PK[21], 1];
B[0] := B[0] xor RK[PK[20], 0];
for i := 15 downto 0 do
begin
Temp[0] := S1[i, pB^[P1[PK[i], 0]]];
Temp[1] := S1[i, pB^[P1[PK[i], 1]]];
Temp[2] := S1[i, pB^[P1[PK[i], 2]]];
Temp[3] := S1[i, pB^[P1[PK[i], 3]]];
Temp[4] := S1[i, pB^[P1[PK[i], 4]]];
Temp[5] := S1[i, pB^[P1[PK[i], 5]]];
Temp[6] := S1[i, pB^[P1[PK[i], 6]]];
Temp[7] := S1[i, pB^[P1[PK[i], 7]]];
Temp[8] := S1[i, pB^[P1[PK[i], 8]]];
Temp[9] := S1[i, pB^[P1[PK[i], 9]]];
Temp[10] := S1[i, pB^[P1[PK[i], 10]]];
Temp[11] := S1[i, pB^[P1[PK[i], 11]]];
Temp[12] := S1[i, pB^[P1[PK[i], 12]]];
Temp[13] := S1[i, pB^[P1[PK[i], 13]]];
Temp[14] := S1[i, pB^[P1[PK[i], 14]]];
Temp[15] := S1[i, pB^[P1[PK[i], 15]]];
B[0] := (Temp[3] shl 24) or (Temp[2] shl 16) or (Temp[1] shl 8) or Temp[0];
B[1] := (Temp[7] shl 24) or (Temp[6] shl 16) or (Temp[5] shl 8) or Temp[4];
B[2] := (Temp[11] shl 24) or (Temp[10] shl 16) or (Temp[9] shl 8) or Temp[8];
B[3] := (Temp[15] shl 24) or (Temp[14] shl 16) or (Temp[13] shl 8) or Temp[12];
B[0] := B[0] xor RK[i, 0];
B[1] := B[1] xor (B[0] + RK[i, 1]);
B[2] := B[2] xor Mul(B[1], RK[i, 2]);
B[3] := B[3] xor (B[2] - RK[i, 3]);
CarryBit := (B[3] and 1) shl 31;
B[3] := (B[3] shr 1) or ((B[2] and 1) shl 31);
B[2] := (B[2] shr 1) or ((B[1] and 1) shl 31);
B[1] := (B[1] shr 1) or ((B[0] and 1) shl 31);
B[0] := (B[0] shr 1) or CarryBit;
end;
B[3] := B[3] xor RK[PK[19], 3];
B[2] := B[2] xor RK[PK[18], 2];
B[1] := B[1] xor RK[PK[17], 1];
B[0] := B[0] xor RK[PK[16], 0];
end;
end;
procedure BravionInit(var Context: TBravionContext; var Key: TBravionKey32);
const
M1 = longword(259200);
M2 = longword(134456);
M3 = longword(243000);
I1 = longword(7141);
I2 = longword(8121);
I3 = longword(4561);
C1 = longword(54773);
C2 = longword(28411);
C3 = longword(51349);
var
X1, X2, X3: longword;
R: array[1..97] of real;
Temp: TBravionBlock32;
i, j, k: integer;
begin
with Context do
begin
FillChar(PK, Sizeof(TBravionPathKey8), 0);
FillChar(RK, Sizeof(TBravionRoundKey32), 0);
i := 0;
repeat //KEY EXPANSION
{I'm actualy using a PRNG with 2^32 period for the expansion}
X1 := (Key[i] + C1) mod M1;
X1 := (X1 * I1 + C1) mod M1;
X2 := X1 mod M2;
X1 := (X1 * I1 + C1) mod M1;
X3 := X1 mod M3;
for j := 1 to 97 do
begin
X1 := (X1 * I1 + C1) mod M1;
X2 := (X2 * I2 + C2) mod M2;
R[j] := (X1 + X2 / M2) / M1;
end;
for j := 0 to 3 do
begin
X1 := (X1 * I1 + C1) mod M1;
X2 := (X2 * I2 + C2) mod M2;
X3 := (X3 * I3 + C3) mod M3;
k := 1 + (97 * X3) div M3;
RK[i * 2, j] := trunc($FFFFFFFF * R[k]);
R[k] := (X1 + X2 / M2) / M1;
X1 := (X1 * I1 + C1) mod M1;
X2 := (X2 * I2 + C2) mod M2;
X3 := (X3 * I3 + C3) mod M3;
k := 1 + (97 * X3) div M3;
RK[(i * 2) + 1, j] := trunc($FFFFFFFF * r[k]);
R[k] := (X1 + X2 / M2) / M1;
end;
Inc(i, 1);
until i = 8;
for i := 0 to 15 do //SET 4BIT PATH KEYS
begin
PK[i] := (TBravionKey8(Key)[i] xor TBravionKey8(Key)[i + 16]) and $F;
j := 16 + (i and 7);
PK[j] := PK[j] xor ((TBravionKey8(Key)[i] xor TBravionKey8(Key)[i + 16]) and $F0)
shr 4;
end;
end;
for i := 0 to 127 do //PERMUTE ROUND KEYS
begin
j := 0;
repeat
Move(Key[0], Temp, Sizeof(TBravionBlock32));
BravionEncrypt(Context, Temp);
Move(Temp, Context.RK[j], Sizeof(TBravionBlock32));
Move(Key[4], Temp, Sizeof(TBravionBlock32));
BravionEncrypt(Context, Temp);
Move(Temp, Context.RK[j + 1], Sizeof(TBravionBlock32));
Inc(j, 2);
until j = 16;
end;
end;
end.
Using the encryption is very simple:
procedure TForm1.Button1Click(Sender: TObject);
var
k: TBravionKey32;
b: TBravionBlock32;
c: TBravionContext;
s: string;
i: longword;
begin
randomize;
for i := 0 to 7 do
k[i] := Random(MaxInt);
for i := 0 to 3 do
b[i] := Random(MaxInt);
BravionInit(c, k);
s := 'Key: {';
for i := 0 to 15 do
s := s + inttohex(TBravionKey8(k)[i], 2);
memo1.lines.add(s + ',');
s := ' ';
for i := 16 to 31 do
s := s + inttohex(TBravionKey8(k)[i], 2);
memo1.lines.add(s + '}');
s := 'Plaintext: {';
for i := 0 to 15 do
s := s + inttohex(TBravionBlock8(b)[i], 2);
memo1.lines.add(s + '}');
BravionEncrypt(c, b);
s := 'Ciphertext: {';
for i := 0 to 15 do
s := s + inttohex(TBravionBlock8(b)[i], 2);
memo1.lines.add(s + '}');
BravionDecrypt(c, b);
s := 'Plaintext: {';
for i := 0 to 15 do
s := s + inttohex(TBravionBlock8(b)[i], 2);
memo1.lines.add(s + '}');
memo1.lines.add('');
end;
this example requires a form, button and memo. it's pretty self explanatory.
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése