# Go Lang NACL Cryptography

by Anish

Posted on Monday December 17 , 2018

This sample chapter extracted from the book, Go Lang Cryptography for Developers . The Book theme isCryptography is for EveryOne. Learn from Crypto Principle to Applied Cryptography With Practical Example Grab a Copy

NaCl (pronounced "salt") is a new easy-to-use high-speed software library for network communication, encryption, decryption, signatures, etc. NaCl's goal is to provide all of the core operations needed to build higher-level cryptographic tools.

### Nacl Box

The Nacl Box uses the given public and private (secret) keys to derive a shared key, which is used with the nonce given to encrypt the given messages and to decrypt the given ciphertexts.

The same shared key will be generated from both pairing of keys, so given two keypairs belonging to Alice (pkalice, skalice) and Bob (pkbob, skbob), the key derived from (pkalice, skbob) will equal that from (pkbob, skalice).

golang.org/x/crypto/nacl/box authenticates and encrypts small messages using public-key cryptography.

Box uses Curve25519, XSalsa20 and Poly1305 to encrypt and authenticate messages. The length of messages is not hidden.

func `Seal` appends an encrypted and authenticated copy of message to out, which will be Overhead bytes longer than the original and must not overlap it. The nonce must be unique for each distinct message for a given pair of keys.

``````func Seal(out, message []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) []byte
``````

func `Open` Open authenticates and decrypts a box produced by Seal and appends the message to out, which must not overlap box. The output will be Overhead bytes smaller than box

``````func Open(out, box []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) ([]byte, bool)
``````

func `GenerateKey` GenerateKey generates a new public/private key pair suitable for use with Seal and Open

``func GenerateKey(rand io.Reader) (publicKey, privateKey *[32]byte, err error)``

The following example will show how to use NACL box, to secretly send encrypted and authenticated copy of message from Alice to Bob

• Public Cryptography requires Key Pair, So first generate. In real world the receiver private key is not known to the sender, only the public key is known.
• Nonce is appended to encrypted message and then send to the receiver.
• Use the same nonce you used to encrypt the message, this is usually done by storing nonce alongside the encrypted message
``````package main

import (
crypto_rand "crypto/rand"
"fmt"
"golang.org/x/crypto/nacl/box"
"io"
)
func main() {
plaintext := "Hello 8gwifi.org using go lang Box Example"
if err != nil {
panic(err)
}

if err != nil {
panic(err)
}
fmt.Printf("Original Text:  %s\n", plaintext)
fmt.Println("====NACL Box Seal/ Open====")

// You must use a different nonce for each message you encrypt with the
// same key. Since the nonce here is 192 bits long, a random value
// provides a sufficiently small probability of repeats.  var nonce [24]byte
panic(err)
}

// This encrypts msg and appends the result to the nonce.
encrypted := box.Seal(nonce[:], []byte(plaintext), &nonce, pkbob, skalice)
fmt.Printf("Alice Send Encrypted Message to Bob  %x\n", encrypted)

// The recipient can decrypt the message using their private key and the
// sender's public key. When you decrypt, you must use the same nonce you
// used to encrypt   the message. One way to achieve this is to store the
// nonce alongside the encrypted message. Above, we stored the nonce in the
// first 24 bytes of the encrypted text.
var decryptNonce [24]byte
copy(decryptNonce[:], encrypted[:24])
decrypted, ok := box.Open(nil, encrypted[24:], &decryptNonce, pkalice, skbob)
if !ok {
panic("decryption error")
}

}
``````

The output

``````\$ go run naclbox.go
Original Text:  Hello 8gwifi.org using go lang Box Example
====NACL Box Seal/ Open====
Alice Send Encrypted Message to Bob  420d83bc6d773bd0597002edc430ae44452d60ba7fa3402b3cdd827343b10a9c0c0a783a1aeb81829a52c3ed15b58568620fc4c807abbfbb48cafe9370567b6201bc33f5289a8d2cf227cd57d512177e22fa
Bob Read Message[ Hello 8gwifi.org using go lang Box Example ]
``````

Nacl Box Faster Computing with Shared Key

The shared key can be used to speed up processing when using the same, pair of keys repeatedly. To achieve this use the go lang functions

func `SealAfterPrecomputation` performs the same actions as Seal, but takes a shared key as generated by Precompute.

``````func SealAfterPrecomputation(out, message []byte, nonce *[24]byte, sharedKey *[32]byte) []byte
``````

func `OpenAfterPrecomputation` n performs the same actions as Open, but takes a shared key as generated by Precompute.

``````func OpenAfterPrecomputation(out, box []byte, nonce *[24]byte, sharedKey *[32]byte) ([]byte, bool)
``````

NACL Box Precompute Example

``````package main

import (
crypto_rand "crypto/rand" // Custom so it's clear which rand we're using.
"fmt"
"golang.org/x/crypto/nacl/box"
"io"
)

func main() {
plaintext := "Hello 8gwifi.org using go lang Box Example"
if err != nil {
panic(err)
}
if err != nil {
panic(err)
}
fmt.Printf("Original Text:  %s\n", plaintext)
fmt.Println("====NACL Box SealAfterPrecomputation/ OpenAfterPrecomputation====")

// You must use a different nonce for each message you encrypt with the
// same key. Since the nonce here is 192 bits long, a random value
// provides a sufficiently small probability of repeats.
var nonce [24]byte
panic(err)
}
// The shared key can be used to speed up processing when using the same
// pair of keys repeatedly.  sharedEncryptKey := new([32]byte)
box.Precompute(sharedEncryptKey, pkbob, skalice)
fmt.Printf("Shared Key [%x\n", *sharedEncryptKey, "]")

// This encrypts msg and appends the result to the nonce.
encrypted := box.SealAfterPrecomputation(nonce[:], []byte(plaintext), &nonce, sharedEncryptKey)

fmt.Printf("Alice Send Encrypted Message to Bob  %x\n", &encrypted)
// The shared key can be used to speed up processing when using the same
// pair of keys repeatedly.  var sharedDecryptKey [32]byte
box.Precompute(&sharedDecryptKey, pkalice, skbob)
// The recipient can decrypt the message using their private key and the
// sender's public key. When you decrypt, you must use the same nonce you
// used to encrypt the message. One way to achieve this is to store the
// nonce alongside the encrypted message. Above, we stored the nonce in the
// first 24 bytes of the encrypted text.  var decryptNonce [24]byte
copy(decryptNonce[:], encrypted[:24])
decrypted, ok := box.OpenAfterPrecomputation(nil, encrypted[24:], &decryptNonce, &sharedDecryptKey)
if !ok {
panic("decryption error")
}
}
``````

The output

``````\$ go run naclbox1.go
Original Text:  Hello 8gwifi.org using go lang Box Example
====NACL Box SealAfterPrecomputation/ OpenAfterPrecomputation====
Shared Key [20e4228e59d552f15ab04a67269b792957d7a71400b353940bcd13b225795ec3
Alice Send Encrypted Message to Bob  &3e6b0011dfcfcd9163f7d3cb68eeadf683f941f7dfca1b3c7637bf9e0fe75563b3db93ef7f357f475b7c4d1c9789c8e396951488b0cc1892668dcf9b3ed10d37feebd059622175071de065394c31478bdb0d
Bob Read Message[ Hello 8gwifi.org using go lang Box Example ]
``````

### Nacl SecretBox

Secret key encryption (also called symmetric key encryption) is analogous to a safe. You can store something secret through it and anyone who has the key can open it and view the contents. SecretBox functions as just such a safe, and like any good safe any attempts to tamper with the contents are easily detected.

Go lang Package secretbox uses XSalsa20 and Poly1305 to encrypt and authenticate messages with secret-key cryptography. The length of messages is not hidden.

func `Seal` appends an encrypted and authenticated copy of message to out, which must not overlap message. The key and nonce pair must be unique for each distinct message and the output will be Overhead bytes longer than message

``````func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte
``````

func `open` authenticates and decrypts a box produced by Seal and appends the message to out, which must not overlap box. The output will be Overhead bytes smaller than box.

``````func Open(out, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool)
``````

Note: secretbox encrypts and authenticates small messages.

The following example will show how to use NACL secretbox, to perform Secret key encryption.

• nonce must be 24 bytes
• secret key must be of 32 bytes
``````import (
"crypto/rand"
"fmt"
"golang.org/x/crypto/nacl/secretbox"
"io"
)
func main() {
plaintext := "Hello 8gwifi.org using go lang secretbox esample"
// Do not Use this Key, This is for Demo Purpose only
var secretKey [32]byte
copy(secretKey[:], key)

fmt.Printf("Original Text:  %s\n", plaintext)
fmt.Println("====NACL secretbox Seal/ Open====")

// You must use a different nonce for each message you encrypt with the
// same key. Since the nonce here is 192 bits long, a random value
// provides a sufficiently small probability of repeats.
var nonce [24]byte
panic(err)
}
encrypted := secretbox.Seal(nonce[:], []byte(plaintext), &nonce, &secretKey)
fmt.Printf("Encrypted Message:  %x\n", encrypted)

// When you decrypt, you must use the same nonce and key you used to
// encrypt the message. One way to achieve this is to store the nonce
// alongside the encrypted message. Above, we stored the nonce in the first
// 24 bytes of the encrypted text.  var decryptNonce [24]byte
copy(decryptNonce[:], encrypted[:24])
decrypted, ok := secretbox.Open(nil, encrypted[24:], &decryptNonce, &secretKey)
if !ok {
panic("decryption error")
}
fmt.Println(string(decrypted))
}
``````

The output

``````\$ go run naclsecretbox.go
Original Text:  Hello 8gwifi.org using go lang secretbox esample
====NACL secretbox Seal/ Open====
Encrypted Message:  fc62734e5c73ceec5e3dfe75a439bc85d13138e97423e79a7fbb17ceef34cc0f47fe26d330cf83fe3210d2a93815e3706be29dce5a282c764001dd6d471781efdf5568a2cc3220cba7f29a7fa041565010c04a0ed1b76b78
Hello 8gwifi.org using go lang secretbox esample
``````

### NaCl Message Authentication

Nacl Message is done with go lang function auth

func `sum` generates an authenticator for m using a secret key and returns the 32-byte digest.

``````func Sum(m []byte, key *[KeySize]byte) *[Size]byte
``````

func `verify` checks that digest is a valid authenticator of message m under the given secret key. Verify does not leak timing information.

``````func Verify(digest []byte, m []byte, key *[KeySize]byte) bool
``````

The following example will show how to use NACL auth, to perform message authentication of a given message

• secret key must be of 32 bytes.
``````package main

import (
"fmt"
"golang.org/x/crypto/nacl/auth"
)
func main() {

plaintext := "Hello 8gwifi.org using go lang auth esample"
// Do not Use this Key, This is for Demo Purpose only
var secretKey [32]byte
copy(secretKey[:], key)

fmt.Printf("Original Text:  %s\n", plaintext)
fmt.Println("====NACL Message Authentication====")

mac := auth.Sum([]byte(plaintext), &secretKey)
fmt.Printf("MAC %x\n", *mac)
result := auth.Verify(mac[:], []byte(plaintext), &secretKey)
fmt.Println("Verified : ", result)

badResult := auth.Verify(mac[:], []byte("different message"), &secretKey)
}
``````

The output

``````\$ go run naclauth.go
Original Text:  Hello 8gwifi.org using go lang auth esample
====NACL Message Authentication====
Verified :  true
Verified :  false
``````

### Nacl Digital Signature

Digital signatures allow you to publish a public key, and then you can use your private signing key to sign messages. Others who have your public key can then use it to validate that your messages are actually authentic.

Nacl Digital Signature is done with go lang function sign

func `GenerateKey` generates a new public/private key pair suitable for use with Sign and Open.

``````func GenerateKey(rand io.Reader) (publicKey *[32]byte, privateKey *[64]byte, err error)
``````

func `Open` verifies a signed message produced by Sign and appends the message to out, which must not overlap the signed message.

``````func Open(out, signedMessage []byte, publicKey *[32]byte) ([]byte, bool)
``````

func `sign` appends a signed copy of message to out

``````func Sign(out, message []byte, privateKey *[64]byte) []byte
``````

The following example will show how to use NACL digital signature.

• Private key for producing digital signatures using the Ed25519 algorithm.
• Message is Signed with private key
• Signature is verified using public key.
``````package main
import (
"crypto/rand"
"fmt"
"golang.org/x/crypto/nacl/sign"
)
func main() {
plaintext := "Hello 8gwifi.org using go lang nacl signing esample"
fmt.Printf("Original Text:  %s\n", plaintext)
fmt.Println("====NACL Digital Signature====")

// Signing of Message is Perfomed with Private Key
signedMessage := sign.Sign(nil, []byte(plaintext), privateKey)
fmt.Printf("Message Signature %x\n ", signedMessage)
// Verification of the Message is performed with Public Key
_ , ok := sign.Open(nil, signedMessage, publicKey)

f !ok {
fmt.Printf("failed to verify signed message")
return
}
fmt.Printf("Verification  Passed ")

}
``````

The output

``````\$ go run naclsign.go
Original Text:  Hello 8gwifi.org using go lang nacl signing esample
====NACL Digital Signature====
Message Signature 1020e3901fc37f3c792a3d435ce7abca877c5171971227b6430f778ef8c245764149185abcef409de7e8e221afa723356363c017a1a46273c969b4809d52920e48656c6c6f203867776966692e6f7267207573696e6720676f206c616e67206e61636c207369676e696e67206573616d706c65
Verifification Passed
``````

{pagebreak}

Thanku for reading !!! Give a Share for Support

Instead of directly asking for donations, I'm thrilled to offer you all nine of my books for just \$9 on leanpub By grabbing this bundle you not only help cover my coffee, beer, and Amazon bills but also play a crucial role in advancing and refining this project. Your contribution is indispensable, and I'm genuinely grateful for your involvement in this journey!

Any private key value that you enter or we generate is not stored on this site, this tool is provided via an HTTPS URL to ensure that private keys cannot be stolen, for extra security run this software on your network, no cloud dependency