Summary

While examining Racket's built-in, continuation-based web application library, I noticed that by default, serialized continuations are sent to the HTTP client both unencrypted and unsigned. After a bit of browsing the manual, I discovered that there is some built-in support for signing serialized data using HMAC-SHA1. However, HMAC-SHA1, while not as insecure as a naive approach using plain SHA1, isn't the cryptographically strongest algorithm around. This encouraged me to write my own little library of cryptographic algorithms.

In addition to HMAC and Whirlpool, which were originally intended to be used as a drop-in replacement for Racket's HMAC-SHA1 function, this library provides implementations of Dan Bernstein's CubeHash hashing function and Salsa20 stream cipher.

Installation

You can require the PLaneT version directly from Racket:

(require (planet mbenkard/mulkrypt))

Development Access

If you want to hack Mulkrypt (there's an apparently incorrect implementation of Threefish in there; if you can fix it, that would be great!), you can fetch the Mercurial repository using the following command:

hg clone http://matthias.benkard.de/code/mulkrypt-for-racket/

(Mind the trailing slash. My web server is overly picky there.)

Implemented Algorithms

  • Cryptographic hashing: Whirlpool, CubeHash
  • Message authentication: HMAC
  • Stream ciphers: Salsa20

Implementation Features

  • No dependencies other than Racket's built-in libraries
  • Pure Racket (no use of C code or foreign libraries)
  • AGPLv3 license
  • Stream ciphers operate on (possibly infinite) sequences, including ports, and output (again, possibly infinite) sequences.

Examples

> (define fox-and-dog #"The quick brown fox jumps over the lazy dog")
> (printf "~x" (cubehash-512x fox-and-dog))
a0e462f1cc35c81f73b6e0aad5f92a20ff5cc25d2bf607ff6db9fa47711db65d
65fd2e1df20857609480968e9189825ddb1f7dd57ac1e0d985e9a27fe5f0a5ec
> (printf "~x" (whirlpool fox-and-dog))
b97de512e91e3828b40d2b0fdce9ceb3c4a71f9bea8d88e75c4fa854df36725f
d2b52eb6544edcacd6f8beddfea403cb55ae31f03ad62a5ef54e42ee82c3fb35
> (printf "~x" (hmac cubehash-256 32 16 #"key" fox-and-dog))
a40cf15be135c55c9977650bf50cc4cf0c85539efc47aeaf29f0ce8696097d55
> (sequence->list (salsa20 #"<<<<<key of 16 or 32 bytes.>>>>>"
                           #"<nonce.>"
                           fox-and-dog))
(122 146 89 152 145 152 42 248 229 225 154 77 160 250 22 247 6 191 4 202 154 
 186 141 181 124 241 166 3 1 133 42 128 25 136 203 216 165 24 195 21 159 96 105)