Last active
August 29, 2015 14:02
-
-
Save cmars/c6129fc699f781094904 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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