All my life I thought crypto is hard. Well, it is, but it is not that bad if you only focus on existing attacks. I realized this after watching HackerOne video lessons at https://www.hacker101.com/videos. After that i dived into coding solutions for cryptopals challenges and naturally used an approach as universal as possible. The result of my (still incomplete) work is now accessible on Github and is known as Langdon framework (which is a reference to famous symbologist Robert Langdon). Let’s see how Langdon works.
Basic usage
You can run Langdon interactively or from the command line with limited set of the most useful commands. Let’s use Langdon in interactive mode first – that happens when no argument is provided. You can then use help command to show implicit documentation.
Variable definition
Naturally you will want to define some data to use crypto on. This is quite straightforward:
a1 = Hello
Now new variable a1 is created and holds 5 bytes of data. We can print it just by specifying variable name:
*** a1 Bin: 0100100001100101011011000110110001101111 Int: 310939249775 Hex: 0x48656c6c6f Raw: b'Hello' Base64: SGVsbG8=
As you can see, Langdon happily shows multiple representations of the same, which is useful. Of course, you can define data with different formats:
a2 = 'Hello' a3 = 310939249775 a4 = 0x48656c6c6f a5 = base64:SGVsbG8= a6 = 0100100001100101011011000110110001101111 a7 = He\x6clo
and all variables are equal. Use quotes as with a2 to ensure variable is given as unescaped string.
You can also load files directly. Let’s assume you have /tmp/hello file with ‘Hello’ string in it. Then you can run:
a8 = file:/tmp/hello
Printing
Print all variables using vars command. This will show the best form, but you can override it by specifying desired type, e.g. vars hex.
*** vars a1 Hello a2 Hello a3 310939249775 a4 0x48656c6c6f a5 Hello a6 Hello a7 Hello a8 Hello *** vars hex a1 0x48656c6c6f a2 0x48656c6c6f a3 0x48656c6c6f a4 0x48656c6c6f a5 0x48656c6c6f a6 0x48656c6c6f a7 0x48656c6c6f a8 0x48656c6c6f
Currently valid types are int, bin, hex, raw, base64 and escaped.
To see just specify type of one variable, use ~ which works like grep.
*** a1~Hex Hex: 0x48656c6c6f
You can use grep on all commands that yield some output. Note that one tilde character looks for exact match, but you can use ~~ to search for regular expressions as well:
*** a1~~(Hex|Int) Int: 310939249775 Hex: 0x48656c6c6f
Finally you can print your variables as hexdump using hexdump or hd command:
*** hd a1 00000000 4865 6c6c 6f |Hello|
Exporting
You can export variables into files like this:
export a1 /tmp/a1
or force datatype:
export a1 /tmp/a1 int
or export all variables:
export all /tmp/variables
which will create files /tmp/variables_a1, /tmp/variables_a2 etc. Again, you can force desired datatype.
Sequences
Sometimes you do not want to specify variables manually, for example when you need random data or long boring sequences. A number of commands exist solely for this purpose:
b1 = random 0x30 0x39 10 b2 = zeros 10 b3 = prime 80 b4 = timestamp b5 = debruijn 10
I should explain this. The b1 variable will hold 10 random bytes from interval <0x30; 0x39> – these are ASCII codes for numbers. Next we create a simple stream of NULL (0x00) bytes. The b3 will hold a 80-bit prime number. The b4 will hold current timestamp, you can also optionally specify datetime to convert. Finally we generate something called DeBruijn pattern. This is a stream of bytes in where any sequence of x bytes (4 in this case) will appear in the pattern once or not at all. That means, given a 4B substring, you can easily find its offset. This is useful when looking for stack overflows (you use the pattern as payload and when program crashes and spits out the bad instruction pointer value you can easily get the correct offset). But this is a different topic. In the end we can expect results like this:
*** vars~b b1 1831257872 b2 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 b3 894066956381389645393937 b4 1577966984 b5 AAABAACAAD
Useful functions
There are few generally useful functions worth mentioning. You can assign them into new variable, like c1 = len a1. The functions are:
len a1orlength a1returns 5 – the number of bytes a variable is holding,rev a1reverses data (olleH), you can also userev a1 16to reverse by 2B (16b) chunks (ollHe),concat a1 b1concatenates data, this will result in Hello1831257872 here,substring a1 1 2returns 2 bytes at offset 1 of variable a1, ‘el‘ in this case,gray a1converts data into 8b Gray code (lW\xdaZX),ungray c1would convert it back,sleep 2will just sleep for 2 secondsentropy a1will get a1’s entropy (as <0; 1>), 0.24024 in this case,histogram a1shows simple byte histogram, like the one below.

CLI mode
If you run Langdon with --help argument, you will get list of available console commands. There are basic functions mentioned above, plus a few functions for transition between different forms, such as --hex and --unhex (they are also available in interactive Langdon, but they are not so useful there). For CLI approach you can use files or stdin as input.
But wait! There’s more! But we will deal with the other Langdon perks later in appropriate chapters. In the next chapter I will show how to solve first few cryptopals challenges with the Langdon’s aid. In the meantime you can watch today’s topic as asciinema cast.