AES-BitDist.mws

AES - Bit Distribution

İMike May, S.J., 2002, maymk@slu.edu

>    restart:

Following the same pattern we used with Baby DES and DES, we would like to look at the distribution of zeroes and ones from a collection of words encrypted with AES.  The digits should behave like independent random variables.  First we need to load in the procedures created in AES-Encryption.mws.

>    read `AES.m`:

We want a procedure for turning a 32 character hex string into a list of 128 binary digits.

>    hex1 := "66E94BD4EF8A2C3B884CFA59CA342B2E";
hexStringToBinList := hexString -> [seq(parse(substring(
    convert(convert(convert(hexString,decimal,hex)+2^128,binary),string),
    i)),i=2..129)]:
hexStringToBinList(hex1);

hex1 :=

[0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0,...
[0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0,...
[0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0,...

We return to our favorite example.  For the key we will use the zero word.  For our plaintexts, we will use words that are all zeroes except for a single bit that is turned on.  In this situation it makes sense to expand the key only once.
The list bitChangeCounter gives us a place to record the number of times each bit is used.

>    keyHex := intTo128Bits(0);
expandedKey := hexKeyExpander(hexkey):
bitChangeCounter := [seq(0,i=1..128)]:
testLine2 := intVal ->
   encryptAESExpanded(intTo128Bits(2^(intVal-1)),expandedKey):

keyHex :=

We are ready to count the number of times a bit is used in each of the first 30 test words.

>    for i from 1 to 30 do
  bitChangeCounter := zip(`+`,bitChangeCounter,
      hexStringToBinList(testLine2(i))):
end do:
bitChangeCounter;

[12, 20, 11, 20, 14, 14, 17, 11, 17, 14, 14, 15, 14, 13, 20, 12, 14, 20, 16, 18, 15, 13, 12, 14, 14, 17, 12, 17, 15, 16, 18, 13, 11, 17, 12, 15, 15, 12, 18, 12, 16, 13, 15, 20, 12, 15, 13, 13, 16, 14, ...
[12, 20, 11, 20, 14, 14, 17, 11, 17, 14, 14, 15, 14, 13, 20, 12, 14, 20, 16, 18, 15, 13, 12, 14, 14, 17, 12, 17, 15, 16, 18, 13, 11, 17, 12, 15, 15, 12, 18, 12, 16, 13, 15, 20, 12, 15, 13, 13, 16, 14, ...
[12, 20, 11, 20, 14, 14, 17, 11, 17, 14, 14, 15, 14, 13, 20, 12, 14, 20, 16, 18, 15, 13, 12, 14, 14, 17, 12, 17, 15, 16, 18, 13, 11, 17, 12, 15, 15, 12, 18, 12, 16, 13, 15, 20, 12, 15, 13, 13, 16, 14, ...
[12, 20, 11, 20, 14, 14, 17, 11, 17, 14, 14, 15, 14, 13, 20, 12, 14, 20, 16, 18, 15, 13, 12, 14, 14, 17, 12, 17, 15, 16, 18, 13, 11, 17, 12, 15, 15, 12, 18, 12, 16, 13, 15, 20, 12, 15, 13, 13, 16, 14, ...

>    stats[transform,tally](bitChangeCounter);
evalf(stats[describe, mean](bitChangeCounter));
evalf(stats[describe, standarddeviation](bitChangeCounter));

[Weight(10,5), Weight(11,8), Weight(12,11), Weight(13,12), Weight(14,22), Weight(15,20), Weight(16,16), Weight(17,13), Weight(18,8), Weight(19,3), Weight(20,9), 21]
[Weight(10,5), Weight(11,8), Weight(12,11), Weight(13,12), Weight(14,22), Weight(15,20), Weight(16,16), Weight(17,13), Weight(18,8), Weight(19,3), Weight(20,9), 21]

14.94531250

2.608006284

The expected mean is 30*.5 = 15.  The expected standard deviation is sqrt(30*.5*.5)=2.7386.

The behavior looks like what we expect from a  random distribution of bits.

>   

>