Performance optimizations and memory management

Added some benchmarks to secure channel and played around with improving its performance, also started using a sync.Pool for message buffers.
Actually, @whyrusleeping, I'd prefer: 

```Go
// in blocks/blocks.go
// NewBlock creates a Block object from opaque data. It will hash the data.
func NewBlockWithHash(data []byte, hash mh.Multihash) *Block {
	return &Block{Data: data, Multihash: hash}
}

// here
return blocks.NewBlockWithHash(bdata, mh.Multihash(k)), nil
```

to ensure we dont accidentally break everything if we think `NewBlock` is the only way to initialize things.