Euler’s Line in MetaPost

Euler’s line, showing that the orthocenter, centroid, and circumcenter are collinear. Created with MetaPost.

This was all defined in MetaPost parametrically, so it’s trivial to create the line through any (non-equilateral) triangle. Showing the center of the 9-point circle is collinear as well is easy too.

Source here.

ICFP ‘08 Contest

I gave the ICFP contest a try again this year, and had a really good time. The task was to write a controller for a martian rover, capable of avoiding basic obstacles like boulders, as well as enemy martians of unknown intelligence. Telemetry input streamed from a network socket to the controller, and basic control commands such as accelerate or turn left, had to be sent back.

Unlike previous years, where it took some time (several hours of implementing an interpreter spec) to really understand the scope of the problem, you knew what you were getting into after reading the very concise task description. I immensely enjoyed the previous formats, but change is good.

Haskell seemed as sensible a choice as anything else, so I went with it. Sending and receiving formatted data (a sample server was provided) over a network socket was the first task, and that was thankfully straightforward. 4 lines (connect, unbuffer, receive, send), and no more I/O to bother with.

Parsing messages from the server was a bit clumsy, I have promised myself I will learn Parsec soon.
Sending commands was nicer though, since I just had to define the datatype, and make a simple instance of Show.

I was somewhat familiar with Yampa before the contest, but I could probably spend a whole weekend just fully understanding how it works, so I decided to stick to a simple turn-based strategy. For every telemetry message sent by the server, I would compute the command sequence to send to the rover, and then wait for new telemetry. The server latency was small enough (~100ms) to make this acceptable.

The biggest challenge was deciding how to structure the event loop, and create composeable strategies for the rover. Given the initial message, and a telemetry message, the controller could probably do a satisfactory job of deciding what commands to send. I had some grand plans of updating a global view of the map, as well as tracking acceleration/braking constants, so I wanted to keep track of some changing state for each turn. My simple solution, which I think was the right choice given the time constraints, was to create a datatype for the rover/world state, and write strategies as transformers of that state. The natural choice to handle this was the State monad. The world (init message), the rover (acceleration/turning state), and the current and past telemetry were encapsulated inside the monad, and the return value was a list of command messages. Each strategy would be able to inspect the telemetry and current rover state, and make changes, or do nothing. By ordering these strategies, I was able to make a rover that charged ahead towards the goal, until it detected something in its path (causing it to turn), or detected it was going to overshoot its goal (causing it to slow down). Strategies could be combined in order, with the last one able to override any previous decisions.

Strategies manipulated the desired state of the rover, which was represented as a state machine. Commands had to be sent that took the rover from its previous state (described in telemetry messages) to the desired state. Making each of the state components an instance of Enum made this transition simple. I just had to count how many applications of the succ or pred functions were necessary to move the state to the goal.

Finally, in the main program, the state transforming function was mapped over the parsed network input, and the result was evaluated, and sent back over the wire.

You can view my solution here: Darcs repo of icfp08

Cheers to the organizers, who did a really fantastic job creating the task (crazy difficult, but very approachable), manning IRC, and keeping track of issues/FAQ.

Byteflow

Wordpress is out, Byteflow is in. I was primarily looking for a small, fun codebase to hack on, and WP/PHP was anything but that.

I spent the past few days getting up to speed with Django, and in fact I’ve already submitted (1,2,3,4) patches against byteflow, so it is definitely quick to get going with.

I’ve also spent quite a while learning how to get around within Mercurial. Maybe i’ll change my mind after doing some more work with it, but I find the usability very poor compared to Darcs.
Mercurial Queues are probably the neatest feature, but that too seems to regularly lead to disaster.

I’ve written a WordPress importer as well, which I used to import all the content from my old blog: WXRImporter.py

Inside Leopard FSEvents

I pieced together some of Apple’s sample code for working with Filesystem Events, the API that powers TimeMachine. Might be useful to see what exactly gets modified between backups, or what directories are being modified on a running system. You can drop this source file into an XCode project with CoreFoundation and CoreServices frameworks, or download a universal binary. Should go without saying, but this requires OS X 10.5.
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>

/*
 *  Watch for filesystem changes using FSEvents API.
 *  11/14/2007, Greg Heartsfield
 *
 *  No copyright claimed by me, this is mostly Apple
 *  example code, with a run loop added.
 */

void printDirectories
(
 ConstFSEventStreamRef streamRef,
 void *clientCallBackInfo,
 size_t numEvents,
 void *eventPaths,
 const FSEventStreamEventFlags eventFlags[],
 const FSEventStreamEventId eventIds[])
{
  int i;
  char **paths = eventPaths;
  for (i=0; i<numEvents; i++) {
    printf("%s\n", paths[i],
           eventFlags[i]);
  }
}

int main (int argc, const char * argv[]) {
  fprintf(stderr, "Watching for filesystem changes to /\n");
  CFStringRef mypath = CFSTR("/");
  CFArrayRef pathsToWatch =
    CFArrayCreate(NULL,
                  (const void **)&mypath,
                  1, NULL);
  void *callbackInfo = NULL;
  FSEventStreamRef stream;
  CFAbsoluteTime latency = 2.0;
  stream =
    FSEventStreamCreate(NULL,
                        printDirectories,
                        callbackInfo,
                        pathsToWatch,
                        kFSEventStreamEventIdSinceNow,
                        latency,
                        kFSEventStreamCreateFlagNone
                        );
  CFRunLoopRef mainLoop = CFRunLoopGetCurrent();
  FSEventStreamScheduleWithRunLoop(stream,
                                   mainLoop,
                                   kCFRunLoopDefaultMode);
  FSEventStreamStart(stream);
  CFRunLoopRun();
  return 0; }

GHC 6.8.1 OS X Builds

Builds of the newly released GHC 6.8.1 for OS X PPC and Intel.

ghc-6.8.1-powerpc-apple-darwin.tar.bz2 (70 MB) ghc-6.8.1-i386-apple-darwin.tar.bz2 (61 MB) Requires readline/GMP, as usual.

To install:

   ./configure
   sudo make install
   
Note: The PowerPC build does not work on 10.5 Leopard. See this GHC Trac bug.

Leopard Breaks /usr/local/lib

After updating to Leopard last night, I noticed that certain command line apps had broken, with various different errors:
$ ghci-6.6.1 
/usr/local/bin/ghci-6.6.1: line 12: /usr/local/lib/ghc-6.6.1/ghc-6.6.1:
    Too many levels of symbolic links
/usr/local/bin/ghci-6.6.1: line 12: exec: /usr/local/lib/ghc-6.6.1/ghc-6.6.1:
    cannot execute: Too many levels of symbolic links
$ mutt
dyld: Library not loaded: /usr/local/lib/libintl.3.dylib
  Referenced from: /usr/local/bin/mutt
  Reason: no suitable image found.  Did find:
	/usr/local/lib/libintl.3.dylib: stat() failed with errno=62
	/usr/local/lib/libintl.3.dylib: stat() failed with errno=62
Trace/BPT trap
Traced it back relatively quickly to this travesty:
$ ls -altr /usr/local/lib
lrwxr-xr-x  1 root  wheel  14 Oct 26 20:40 /usr/local/lib -> /usr/local/lib
Yep, /usr/local/lib is a symlink to /usr/local/lib. Something in the install process moved my original /usr/local/lib to “/usr/local/lib 1”, so the fix is simple:
$ sudo mv /usr/local/lib /usr/local/lib_broken
$ sudo mv /usr/local/lib\ 1/ /usr/local/lib
Besides that, Leopard is brilliant :) Update: Coqide (theorem prover GUI) crashes on startup :(

QuickCheck Love

If you actually want to get started with QuickCheck, check out the HaskellWiki. The following is just meant to give a simple motivating example for using QuickCheck.

We’ve implemented some simple symmetric block ciphers in Haskell, all of which have encryption/decryption functions with types like the following:

   tea_enc :: Int                              -- Cycle count
           -> (Word32, Word32, Word32, Word32) -- 128-bit key
           -> (Word32, Word32)                 -- Input block
           -> (Word32, Word32)                 -- Output block
   

For these ciphers, we want to verify the very simple property that when using the same key, encrypting and then decrypting a block will yield that same block. That property is represented with the code below (which takes the encryption/decryption ciphers, a key, and an input block as arguments):

   test_identity enc dec key input =
       input == dec key (enc key input)
   

Now, we want to use QuickCheck to randomly generate keys and input blocks, and check the identity property. To do that, we’ll change the function to just take the cipher algorithms as arguments, and use QuickCheck to generate the rest.

   test_identity enc dec =
       quickCheck (key input ->
                   input == dec key (enc key input))
   

Notice how it’s almost identical to our original function that tests a single instance of the property. The only change was moving the arguments that we want to vary into a lambda function, and handing it off to the quickCheck function. QuickCheck figures out how to generate the required arguments, pumps out arbitrary values, and tests them against the given property.

Finally, we can run some tests on our cipher (using 32 cycles):

   TEA> test_identity (xtea_encode 32) (xtea_decode 32)
   OK, passed 100 tests.
   

Let’s deliberately cause the property to be invalidated by changing just the encoding function and re-running the test:

   TEA> test_identity (xtea_encode 32) (xtea_decode 32)
   Falsifiable, after 1 tests:
   (3,4294967295) (2,1,0,4294967295)
   

Which tells us after the very first test, it was able to find an input block and key that make the property false. Notice the numbers QuickCheck selected for its first test, they do not appear random, and in fact, QuickCheck doesn’t necessarily generate random values for types. In this case, it is starting with what look like typical corner cases (very large numbers, zero, small numbers).

Note: QuickCheck isn’t natively able to generate arbitrary values for the type Word32, so we had to tell it how to do so, with the following code, which maps arbitrary integers onto Word32 values (courtesy of a haskell-cafe post by Sebastian Sylvan):

   instance Arbitrary Word32 where
       arbitrary = do c <- arbitrary :: Gen Integer
              return (fromIntegral c)
   

By making any user-defined type an instance of Arbitrary, you can have QuickCheck automatically generate tests for properties that take that type as an argument.

xUnit tests definitely have their place. Some ciphers have sets of test vectors for instance, which exploit very specific corner cases in the algorithm. But for testing general properties of code, the quickcheck style can be very intuitive and… quick.

Pre-signing URIs for expiration with S3

This is a neat feature of S3 that I wasn’t aware of until after digging through the API docs. You can generate URIs to S3 resources, which expire after a given time. It’s in the latest release of hS3, which includes an example for generating a URI valid for a certain number of seconds in the future.

Instead of making an object public via an ACL, you create a signature of the resource and an expiration date. This signature is added as a query element to the URI, and then given out to users. The end result looks like the following:

   http://s3.amazonaws.com:80/hS3/LICENSE
   ?AWSAccessKeyId=09MD8BAR1GEXCERHT1R2
   &Expires=1191208823 &Signature=bY6Luynk8mxbzaO8yv2Pcd3kd1U%3d
   

Which is generated by code like:

   do uri <- publicUriForSeconds connection object exp_seconds
      putStrLn uri
   

Haskell S3 Library

Amazon says: Amazon S3 provides a simple web services interface that can be used to store and retrieve any amount of data, at any time, from anywhere on the web. It gives any developer access to the same highly scalable, reliable, fast, inexpensive data storage infrastructure that Amazon uses to run its own global network of web sites. The service aims to maximize benefits of scale and to pass those benefits on to developers.

After hacking away for most of my evenings this week, and the weekend, I’ve got something that I don’t feel terribly bad about releasing. Still needs a good deal of work, but the fundamental operations work. I’m sure there will be some API changes in the future to accomodate some of the missing features.

What works:

Issues:

  • It’s slooow. The HTTP library doesn’t use ByteStrings, so sending multi-megabyte files is painful.
  • Requires the absolute latest Crypto and HTTP libraries, since I submitted patches for HMAC-SHA1, and HTTP DELETE during the course of writing the library.
  • To use the more advanced features, such as ACLs, metadata, hierarchical listings, you’ll probably have to spend some time with the Amazon docs.

Coming Soon:

  • Better documentation, examples, and test cases.
  • Other Amazon Web Services, in the order that they interest me (SQS, EC2, FPS…)

Here’s how you get started. The latest version is available via darcs:

darcs get http://gregheartsfield.com/hS3
Or, get the official release from Hackage

Documentation here, the AWSConnection, S3Bucket, and S3Object modules are where you’ll want to begin.

Haskell HMAC

A necessary part of the Amazon S3 library I’m planning on putting some effort into is HMAC-SHA1, for authentication. It is missing from any public Haskell libraries I could find, so I put one together during my weekend in Austin. Hopefully it will make a nice addition (after some cleanup) to the excellent Crypto library, on which it depends for message digest functions.
-----------------------------------------------------------------------------
-- |
-- Module      :  Data.HMAC
-- Copyright   :  (c) Greg Heartsfield 2007
-- License     :  BSD-style (see the file ReadMe.tex)
--
-- Implements HMAC (hashed message authentication code) as defined in FIPS 198
-- .
--
-----------------------------------------------------------------------------

module Data.HMAC(
   -- * Function Types
   hmac, hmac_sha1, hmac_md5,    sha1_hm,key_from_user,
   -- * Data Types
   HashMethod(HashMethod, digest, input_blocksize),
   ) where

import Data.Digest.SHA1 as SHA1
import Data.Digest.MD5 as MD5
import Data.Word(Word32)
import Data.Bits (shiftR, xor, bitSize, Bits)
import Codec.Utils (Octet)
import Debug.Trace

-- | HMAC works over any hash function, which is represented by
--   HashMethod.  A hash function, and input block size must
--   be specified.

data HashMethod =
    HashMethod { -- | An arbitrary hash function
                 digest :: [Octet] -> [Octet],
                -- | Bit size of an input block to the hash function
                 input_blocksize :: Int}

--Some useful digest functions for use with HMAC.

sha1_hm = HashMethod (w160_to_w8s . SHA1.hash) 512
md5_hm = HashMethod MD5.hash 512

-- | Compute an HMAC using SHA-1 as the underlying hash function.

hmac_sha1 :: [Octet] -- ^ Secret key
          -> [Octet] -- ^ Message text
          -> [Octet] -- ^ Resulting HMAC-SHA1 value
hmac_sha1 = hmac sha1_hm

-- | Compute an HMAC using MD5 as the underlying hash function.

hmac_md5 :: [Octet] -- ^ Secret key
         -> [Octet] -- ^ Message text
         -> [Octet] -- ^ Resulting HMAC-SHA1 value
hmac_md5 = hmac md5_hm

w160_to_w8s :: Word160 -> [Octet]
w160_to_w8s w = concat $ map w32_to_w8s (w160_to_w32s w)

w160_to_w32s :: Word160 -> [Word32]
w160_to_w32s (Word160 a b c d e) = a : b : c : d : e : []

w32_to_w8s :: Word32 -> [Octet]
w32_to_w8s a = (fromIntegral (shiftR a 24)) :
               (fromIntegral (shiftR a 16)) :
               (fromIntegral (shiftR a 8)) :
               (fromIntegral a) : []

-- | Generalized function for creating HMACs on a specified
--   hash function.

hmac :: HashMethod -- ^ Hash function and associated block size
        -> [Octet] -- ^ Secret key
        -> [Octet] -- ^ Message text
        -> [Octet] -- ^ Resulting HMAC value
hmac h uk m = hash (opad ++ (hash (ipad ++ m)))
    where hash = digest h
          (opad, ipad) = process_pads key
                           (make_start_pad bs opad_pattern)
                           (make_start_pad bs ipad_pattern)
          bs = input_blocksize h
          key = key_from_user h uk

-- Create a key of the proper size from the user-supplied key.
-- Keys greater than blocksize get hashed and returned.
-- Keys same as blocksize are used as is.
-- Keys shorter than blocksize are padding with zeros.

key_from_user :: HashMethod -> [Octet] -> [Octet]
key_from_user h uk =
    case (compare (bitcount uk) (input_blocksize h)) of
      GT -> fill_key ((digest h) uk)
      LT -> fill_key uk
      EQ -> uk
    where fill_key kd =
              kd ++ (take (((input_blocksize h) — (bitcount kd)) `div` 8)
                     (repeat 0x0))

-- Create the inner/outer pad values by XOR'ing with the key.

process_pads :: [Octet] -- Key
             -> [Octet] -- opad
             -> [Octet] -- ipad
             -> ([Octet], [Octet]) -- new opad, new ipad
process_pads ks os is =
    unzip $ zipWith3 (\k o i -> (k `xor` o, k `xor` i)) ks os is

-- Create padding values for a hash of a given bit size.

make_start_pad :: Int -> Octet -> [Octet]
make_start_pad size pad = take (size `div` (bitSize pad)) $ repeat pad

-- Padding constants, per the spec.

opad_pattern = 0x5c :: Octet
ipad_pattern = 0x36 :: Octet

-- Bit count of byte array.

bitcount :: [Octet] -> Int
bitcount k = (length k) * (bitSize (head k))

edited to fix bugs and incorporate suggestions from comments And… test cases This is now incorporated into the latest version of the Haskell crypto library (later than 4.0.3).