In addition to Perl and PDL, one of my favourite topics is cryptography, specifically cryptanalysis.
One 'common' cryptanalytical attack, for which modern ciphers are designed against is differential cryptanalysis. Some older ciphers are vulnerable to this attack and various tutorials exist to teach differential cryptanalysis. One of these is by Jon King against the FEAL cipher and is located here.
One aspect of the differential cryptanalysis attack is to enumerate all potential differentials against the non-linear round function. The below code performs this analysis against the FEAL-4 cipher's round sub-function 'G'. It successfully identifies the two fixed input differentials.
Enjoy!
#!/usr/bin/env perl
use 5.020;
use warnings;
use autodie;
use PDL;
use PDL::NiceSlice;
# This code attempts to find all differential characteristics in the
# FEAL-4 cipher round subfunction 'G'.
#
# Reference: http://theamazingking.com/crypto-feal.php
#
#
# 'G' function is addition of a, b and x, then bitwise rotate left
# by 2 bits
# a, b, x and the final value are all 8 bits.
# For our purposes, x can be ignored, as it's constant 0 or 1
#
# a
# |
# x -> [+] <- b
# |
# [<<<]
# |
# OUT
#
# Perform addition
my $G = sequence( byte, 256 ) + sequence( byte, 256 )->transpose;
# Bitwise rotation
$G = ( $G << 2 ) | ( $G >> 6 );
# At this point, $G contains all possible inputs for a and b, and
# the associated output value
#
# Now we wish to find all differentials throughout this function
#
# To do this, we need to find differentials between each possible
# inputs to 'a', and 'b' and observe the differential in the result
#
# There are two known differentials for this function. A differential
# value of 0 and 0x80 (128) for 'a' will always return a constant
# differential output (0 and 2) respectively.
# Calculate the differential table
my $diffs = $G ^ $G ( (0) );
# Find the minimum and maximum value for each differential
my ( $min, $max ) = minmaxover($diffs);
# Print index of differentials where minimum and maximum value are
# equal. As the index is also in the input value, this returns the
# actual differential:
print "Contant differentials for input differentials of: ",
which( $min == $max ), "\n";