Code Poetry
and Text Adventures

by catid posted (>30 days ago) 12:41pm Mon. Nov 26th 2012 PST
This has been rattling around in my head for a while, just thought I'd share it in case anyone finds it interesting.

For a standard 20 character product key, redeem code (Google play cards), etc, you get about 103 bits to play with.  Throw a few away for a quick parity validation check that can be coded in JavaScript in the browser, and you have 101 bits for data.

The way I'd do it that seems optimal to me is to adapt the AES cipher to a shorter bit length and call it AES-101.  AES is a block cipher, which means that you cannot truncate the output.

So for a gift card application:

When a new card is generated, increment a counter and encrypt its value with AES-101, padded with zeroes.  Attach a simple parity check.  Convert the number to its 20-digit number+letter representation.  This is the gift card redemption code.

When a card is redeemed, perform a parity check in the browser to reduce server load.  Then submit the code to the server, which is able to decrypt the code, yielding either a small number padded with zeroes or a big random mess.  Since the server knows how many codes have been generated, it can determine if the received code is valid or not (<NextToGenerate).  Furthermore it can mark the code as having been used in a database.  The database can also be used to specify how large the value of the card is, etc.  Because the card numbers are dense, it packs maps directly into a database index and even admits custom databases that can scale as large as you need.

The decrypted counter value can be used to encode the type of card for some applications ($5, $10, $15, $25) to simplify the database so you'd only need a few bits per card to track whether or not it has been activated and whether or not it has been redeemed.

All the operations are really inexpensive and efficient.  The trickiest piece of engineering is changing AES to use a smaller block size.
last edit by catid edited (>30 days ago) 12:43pm Mon. Nov 26th 2012 PST