Created
March 31, 2015 22:14
-
-
Save swenson/4cf2156e1ea7259457f1 to your computer and use it in GitHub Desktop.
Code samples from Modern Cryptanalysis by Christopher Swenson
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The number of bits in the S-box | |
sbits = 6 | |
# Calculate the maximum value / differential | |
ssize = 2**6 | |
# Generate the matrix of differences, starting | |
# at all zeros | |
count = [] | |
for i in range(ssize): | |
count.append([0 for j in range(ssize)]) | |
# Take every possible value for the first plaintext | |
for x1 in range(0, ssize): | |
# Calculate the corresponding ciphertext | |
y1 = s[x1] | |
# Now, for each possible differential | |
for dx in range(0, ssize): | |
# Calculate the other plaintext and ciphertext | |
x2 = x1 ^ dx | |
y2 = s[x2] | |
# Calculate the output differential | |
dy = y1 ^ y2 | |
# Increment the count of the characteristic | |
# in the table corresponding to the two | |
# differentials | |
count[dx][dy] = count[dx][dy] + 1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Import the random library | |
import random | |
# Seed it with a fixed value (for repeatability) | |
random.seed(12345) | |
# Set the number of rounds in the encryption function | |
rounds = 3 | |
# Set the number of bits in a plaintext or ciphertext | |
bits = 36 | |
# Set the plaintext differential | |
pdiff = 0x280000000L | |
# Set the number of pairs to generate | |
numpairs = 1000 | |
# Store the plaintexts and ciphertexts | |
plaintext1 = [] | |
plaintext2 = [] | |
ciphertext1 = [] | |
ciphertext2 = [] | |
for i in range(0, numpairs): | |
# Create a random plaintext | |
r = random.randint(0, 2**bits) | |
# Create a paired plaintext with a fixed differential | |
r2 = r ^ pdiff | |
# Save them | |
plaintext1.append(r) | |
plaintext2.append(r2) | |
# Create the associated ciphertexts | |
# Assume that the encryption algorithm has already | |
# been defined | |
c = encrypt(r,rounds) | |
c2 = encrypt(r2,rounds) | |
ciphertext1.append(c) | |
ciphertext2.append(c2) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
keys = 64 # number of keys we need to analyze | |
count = [0 for i in range(keys)] # count for each key | |
maxcount = -1 # best count found so far | |
maxkey = -1 # key for the best differential | |
cdiff = 2 # the ciphertext differential we are looking for | |
# Brute force the subkeys | |
for k1 in range(0,keys): | |
# Adjust the key to match up with the correct S-box | |
k = k1 << 18 | |
# For each p/c pair | |
for j in range(numpairs): | |
c1 = ciphertext1[j] | |
c2 = ciphertext2[j] | |
# Calculate whatever needs to be done using | |
# key bits, storing the results as u1 and u2 | |
v = mix(demux(apbox(c)), k) | |
u = asbox(v[3]) | |
v2 = mix(demux(apbox(c2)), k) | |
u2 = asbox(v2[3]) | |
# If the differential holds, increment count | |
if u1 ^ u2 == cdiff: count[k1] = count[k1] + 1 | |
# If this was the best key so far, then save it | |
# Otherwise, ignore it for now | |
if count[k1] >= maxcount: | |
maxcount = count[k1] | |
maxkey = k1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment