func CreateRC5RSWPuzzleWithPrimes(a uint64, t uint64, message []byte, p *big.Int, q *big.Int) (ciphertext []byte, puzzle rsw.PuzzleRSW, err error) {
	var key []byte
	if key, err = Generate16ByteKey(rand.Reader); err != nil {
		err = fmt.Errorf("Could not generate rc5 key for puzzle: %s", err)
		return
	}
	var pzInterface crypto.Puzzle
	if pzInterface, key, err = createRSWPuzzleWithPrimes(a, t, key, p, q); err != nil {
		err = fmt.Errorf("Error creating rsw puzzle with primes before encrypting: %s", err)
		return
	}
	var pzSerialized []byte
	if pzSerialized, err = pzInterface.Serialize(); err != nil {
		err = fmt.Errorf("Error serializing puzzle before encryption: %s", err)
		return
	}
	if err = puzzle.Deserialize(pzSerialized); err != nil {
		err = fmt.Errorf("Error deserializing puzzle before encryption: %s", err)
		return
	}
	if len(key) != 16 {
		err = fmt.Errorf("Error with key size")
		return
	}
	var RC5Cipher cipher.Block
	if RC5Cipher, err = rc5.New(key); err != nil {
		err = fmt.Errorf("Error creating cipher for encryption in rc5 puzzle: %s", err)
		return
	}
	if len(message) < RC5Cipher.BlockSize() {
		err = fmt.Errorf("ciphertext less than blocksize, make a bigger ciphertext")
		return
	}
	var iv []byte
	ciphertext = make([]byte, RC5Cipher.BlockSize()+len(message))
	iv = ciphertext[:RC5Cipher.BlockSize()]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		err = fmt.Errorf("Error reading random reader for iv: %s", err)
	}
	var cfbEncrypter cipher.Stream
	cfbEncrypter = cipher.NewCFBEncrypter(RC5Cipher, iv)
	cfbEncrypter.XORKeyStream(ciphertext[RC5Cipher.BlockSize():], message)
	return
}
CreateRC5RSWPuzzleWithPrimes creates a RSW timelock puzzle with
time t and encrypts the message using RC5, given some user-defined
primes. This returns a struct unlike the other methods here.
package timelockencoders
import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"crypto/sha256"
	"fmt"
	"io"
	"math/big"
	"github.com/dgryski/go-rc5"
	"github.com/dgryski/go-rc6"
	"github.com/mit-dci/opencx/crypto"
	"github.com/mit-dci/opencx/crypto/hashtimelock"
	"github.com/mit-dci/opencx/crypto/rsw"
)
func createSHAPuzzle(t uint64, key []byte) (puzzle crypto.Puzzle, anskey []byte, err error) {
	var timelock crypto.Timelock
	if timelock, err = hashtimelock.New(key, sha256.New()); err != nil {
		err = fmt.Errorf("Error creating new hash timelock for SHA256 puzzle: %s", err)
		return
	}
	if puzzle, anskey, err = timelock.SetupTimelockPuzzle(t); err != nil {
		err = fmt.Errorf("Error setting up timelock while creating rsw puzzle: %s", err)
		return
	}
	return
}
func createRSWPuzzle(t uint64, key []byte) (puzzle crypto.Puzzle, anskey []byte, err error) {
	var timelock crypto.Timelock
	if timelock, err = rsw.New2048A2(key); err != nil {
		err = fmt.Errorf("Error creating new rsw timelock for rsw puzzle: %s", err)
		return
	}
	if puzzle, anskey, err = timelock.SetupTimelockPuzzle(t); err != nil {
		err = fmt.Errorf("Error setting up timelock while creating rsw puzzle: %s", err)
		return
	}
	return
}
func createRSWPuzzleWithPrimes(a uint64, t uint64, key []byte, p *big.Int, q *big.Int) (puzzle crypto.Puzzle, anskey []byte, err error) {
	var timelock crypto.Timelock
	if timelock, err = rsw.NewTimelockWithPrimes(key, a, p, q); err != nil {
		err = fmt.Errorf("Error creating new rsw timelock for rsw puzzle: %s", err)
		return
	}
	if puzzle, anskey, err = timelock.SetupTimelockPuzzle(t); err != nil {
		err = fmt.Errorf("Error setting up timelock while creating rsw puzzle: %s", err)
		return
	}
	return
}