Skip to content

Instantly share code, notes, and snippets.

@cmars
Last active August 29, 2015 14:02
Show Gist options
  • Save cmars/c6129fc699f781094904 to your computer and use it in GitHub Desktop.
Save cmars/c6129fc699f781094904 to your computer and use it in GitHub Desktop.
package main
import (
"crypto/rand"
"fmt"
"code.google.com/p/go.crypto/nacl/box"
)
type PublicKey struct {
pk [32]byte
}
type PrivateKey struct {
sk [32]byte
}
type Keyring struct {
PublicKey PublicKey
PrivateKey PrivateKey
}
func GenerateKeyring() (*Keyring, error) {
pk, sk, err := box.GenerateKey(rand.Reader)
if err != nil {
return nil, err
}
return &Keyring{PublicKey: PublicKey{*pk}, PrivateKey: PrivateKey{*sk}}, nil
}
type Nonce struct {
n [24]byte
}
func newNonce() (Nonce, error) {
var n Nonce
_, err := rand.Reader.Read(n.n[:])
return n, err
}
func encrypt(from PrivateKey, to PublicKey, plaintext string) ([]byte, Nonce) {
msgb := []byte(plaintext)
out := make([]byte, box.Overhead+len(msgb))
nonce, _ := newNonce()
out = box.Seal(nil, msgb, &nonce.n, &to.pk, &from.sk)
return out, nonce
}
func decrypt(from PublicKey, to PrivateKey, ciphertext []byte, nonce Nonce) (string, error) {
if len(ciphertext) < box.Overhead {
return "", fmt.Errorf("ciphertext too short")
}
out, ok := box.Open(nil, ciphertext, &nonce.n, &from.pk, &to.sk)
if !ok {
return "", fmt.Errorf("decryption failed")
}
return string(out), nil
}
func (kr *Keyring) EncryptTo(pk PublicKey, plaintext string) ([]byte, Nonce) {
return encrypt(kr.PrivateKey, pk, plaintext)
}
func (kr *Keyring) DecryptFrom(pk PublicKey, nonce Nonce, ciphertext []byte) (string, error) {
return decrypt(pk, kr.PrivateKey, ciphertext, nonce)
}
func die(err error) {
panic(err)
}
func main() {
reg, err := GenerateKeyring()
if err != nil {
die(err)
}
bob, err := GenerateKeyring()
if err != nil {
die(err)
}
plaintext := "welcome to the salty spitton. how tough are ya?"
ciphertext, nonce := reg.EncryptTo(bob.PublicKey, plaintext)
fmt.Println(ciphertext, nonce)
plaintext2, err := bob.DecryptFrom(reg.PublicKey, nonce, ciphertext)
if err != nil {
die(err)
}
fmt.Println(plaintext)
fmt.Println(plaintext2)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment