1package box_test 2 3import ( 4 crypto_rand "crypto/rand" // Custom so it's clear which rand we're using. 5 "fmt" 6 "io" 7 8 "golang.org/x/crypto/nacl/box" 9) 10 11func Example() { 12 senderPublicKey, senderPrivateKey, err := box.GenerateKey(crypto_rand.Reader) 13 if err != nil { 14 panic(err) 15 } 16 17 recipientPublicKey, recipientPrivateKey, err := box.GenerateKey(crypto_rand.Reader) 18 if err != nil { 19 panic(err) 20 } 21 22 // You must use a different nonce for each message you encrypt with the 23 // same key. Since the nonce here is 192 bits long, a random value 24 // provides a sufficiently small probability of repeats. 25 var nonce [24]byte 26 if _, err := io.ReadFull(crypto_rand.Reader, nonce[:]); err != nil { 27 panic(err) 28 } 29 30 msg := []byte("Alas, poor Yorick! I knew him, Horatio") 31 // This encrypts msg and appends the result to the nonce. 32 encrypted := box.Seal(nonce[:], msg, &nonce, recipientPublicKey, senderPrivateKey) 33 34 // The recipient can decrypt the message using their private key and the 35 // sender's public key. When you decrypt, you must use the same nonce you 36 // used to encrypt the message. One way to achieve this is to store the 37 // nonce alongside the encrypted message. Above, we stored the nonce in the 38 // first 24 bytes of the encrypted text. 39 var decryptNonce [24]byte 40 copy(decryptNonce[:], encrypted[:24]) 41 decrypted, ok := box.Open(nil, encrypted[24:], &decryptNonce, senderPublicKey, recipientPrivateKey) 42 if !ok { 43 panic("decryption error") 44 } 45 fmt.Println(string(decrypted)) 46 // Output: Alas, poor Yorick! I knew him, Horatio 47} 48 49func Example_precompute() { 50 senderPublicKey, senderPrivateKey, err := box.GenerateKey(crypto_rand.Reader) 51 if err != nil { 52 panic(err) 53 } 54 55 recipientPublicKey, recipientPrivateKey, err := box.GenerateKey(crypto_rand.Reader) 56 if err != nil { 57 panic(err) 58 } 59 60 // The shared key can be used to speed up processing when using the same 61 // pair of keys repeatedly. 62 sharedEncryptKey := new([32]byte) 63 box.Precompute(sharedEncryptKey, recipientPublicKey, senderPrivateKey) 64 65 // You must use a different nonce for each message you encrypt with the 66 // same key. Since the nonce here is 192 bits long, a random value 67 // provides a sufficiently small probability of repeats. 68 var nonce [24]byte 69 if _, err := io.ReadFull(crypto_rand.Reader, nonce[:]); err != nil { 70 panic(err) 71 } 72 73 msg := []byte("A fellow of infinite jest, of most excellent fancy") 74 // This encrypts msg and appends the result to the nonce. 75 encrypted := box.SealAfterPrecomputation(nonce[:], msg, &nonce, sharedEncryptKey) 76 77 // The shared key can be used to speed up processing when using the same 78 // pair of keys repeatedly. 79 var sharedDecryptKey [32]byte 80 box.Precompute(&sharedDecryptKey, senderPublicKey, recipientPrivateKey) 81 82 // The recipient can decrypt the message using the shared key. When you 83 // decrypt, you must use the same nonce you used to encrypt the message. 84 // One way to achieve this is to store the nonce alongside the encrypted 85 // message. Above, we stored the nonce in the first 24 bytes of the 86 // encrypted text. 87 var decryptNonce [24]byte 88 copy(decryptNonce[:], encrypted[:24]) 89 decrypted, ok := box.OpenAfterPrecomputation(nil, encrypted[24:], &decryptNonce, &sharedDecryptKey) 90 if !ok { 91 panic("decryption error") 92 } 93 fmt.Println(string(decrypted)) 94 // Output: A fellow of infinite jest, of most excellent fancy 95} 96