using nacl.Sign and understanding its I/O arguments

219 views Asked by At

In the package golang.org/x/crypto/nacl/sign the Sign function has both an out []byte argument and it returns a byte slice.

Reading the source code, i am struggling figuring out how to correctly use them, they are head and tail, though in following example, the resulting out byte slice is zero len.

Please see following example,


package main

import (
    "crypto/rand"
    "encoding/base64"
    "fmt"

    "golang.org/x/crypto/nacl/sign"
)

func main() {
    _, priv, err := sign.GenerateKey(rand.Reader)
    if err != nil {
        panic(err)
    }
    msg := []byte("hello world!")
    out := make([]byte, 0, len(msg)+sign.Overhead)
    ret := sign.Sign(out, msg, priv)

    fmt.Printf("len(msg): %v %s\n", len(msg), msg)
    fmt.Printf("len(out): %v %v\n", len(out), base64.StdEncoding.EncodeToString(out))
    fmt.Printf("len(ret): %v %v\n", len(ret), base64.StdEncoding.EncodeToString(ret))
}
// Output:
// len(msg): 12 hello world!
// len(out): 0 
// len(ret): 76 h+ZkFoWxuxOj7zV3tekiQz/z/yfuvXNUHxBjklo4iGBy7PfCEwvAiy3gi7GnuYGWB3SMxuxHtV5tNuUL1b3kAGhlbGxvIHdvcmxkIQ==

I dont understand why Sign returns both out and ret. I am unsure how long should be the out buffer to sign.Sign.

Conversely this examples works, though, is it correct ?

package main

import (
    "crypto/rand"
    "encoding/base64"
    "fmt"

    "golang.org/x/crypto/nacl/sign"
)

func main() {
    pub, priv, err := sign.GenerateKey(rand.Reader)
    if err != nil {
        panic(err)
    }
    msg := []byte("hello world!")
    out := make([]byte, 0, len(msg)+sign.Overhead)
    ret := sign.Sign(out, msg, priv)

    fmt.Printf("len(msg): %v %s\n", len(msg), msg)
    fmt.Printf("len(out): %v %v\n", len(out), base64.StdEncoding.EncodeToString(out))
    fmt.Printf("len(ret): %v %v\n", len(ret), base64.StdEncoding.EncodeToString(ret))

    openOut := make([]byte, 0, len(ret)-sign.Overhead)
    res, ok := sign.Open(openOut, ret, pub)
    if !ok {
        panic("failed to open signed message")
    }
    fmt.Printf("len(res): %v %s\n", len(res), res)
}
// Output:
// len(msg): 12 hello world!
// len(out): 0 
// len(ret): 76 h+ZkFoWxuxOj7zV3tekiQz/z/yfuvXNUHxBjklo4iGBy7PfCEwvAiy3gi7GnuYGWB3SMxuxHtV5tNuUL1b3kAGhlbGxvIHdvcmxkIQ==
// len(res): 12 hello world!

Looking forward for some explanations and correctness help.

0

There are 0 answers