Rationale for using arrays rather than slices in the NaCL API?

234 views
Skip to first unread message

David Anderson

unread,
Nov 24, 2012, 6:51:59 PM11/24/12
to golang-nuts, a...@golang.org
I'm working on an implementation of CurveCP (http://curvecp.org) in Go, using the box/secretbox operations that agl graciously wrote.

However, I'm puzzled as to why the APIs (http://go.pkgdoc.org/code.google.com/p/go.crypto/nacl/box and http://go.pkgdoc.org/code.google.com/p/go.crypto/nacl/secretbox) use pointers to raw arrays, rather than slices, for keys and nonces. It makes using the API a little clunky, as I have to allocate a bunch of raw arrays and copy keys around, when I could just point at the key in the received packets directly if I could pass in a slice.

And, in general, it's so rare to see raw arrays that the API feels surprising. Is there a reason for not using slices, besides being able to avoid an if len(k) != 32 { panic(...) } ?

- Dave

Adam Langley

unread,
Nov 24, 2012, 7:37:43 PM11/24/12
to David Anderson, golang-nuts
Avoiding lots of "if len(k) != x { panic" is a fair bit of it, as well
as documenting the sizes of things in the type, rather than having to
read the comments and also preventing typos where, say, the nonce and
key are interchanged. (For example, the fact that the nonce is 24
bytes for (secret)box is significant because the Salsa20 nonce is
usually 8 bytes and hints that something more complex is happening
under the covers.)

Often a new type would be used for these things but crypto is
something that generally happens at the edge of a process, where type
information is lost in serialisation. So that doesn't work as well as
it might otherwise.

(And one of my Go nits is that casting from a slice to an array
pointer doesn't work.)

It's quite possible that I was an idiot and should just have used slices.


Cheers

AGL

David Anderson

unread,
Nov 24, 2012, 7:49:15 PM11/24/12
to Adam Langley, golang-nuts
Makes sense, I guess. As you say, with the inability to go back from slice to array, it uglifies things a little bit. That said, after remembering that you can stack-declare arrays, the code ends up being nice enough. I end up copying the nonces and keys a few more times than strictly necessary, but whatever.

Thanks!
- Dave
 


Cheers

AGL

Dmitry Chestnykh

unread,
Nov 24, 2012, 7:54:56 PM11/24/12
to golan...@googlegroups.com, David Anderson
I'd add that the speed difference between arrays and slices is currently significant.
My first versions of Salsa20 and Poly1305 used slices for everything, and when I switched
them to arrays, this eliminated a huge amount of bounds checking, increasing performance.
(So even your copying of key won't have significant impact).

Here's a piece of relevant git log:

Date:   Sat Jun 2 23:36:30 2012 +0200

    salsa20: use pointers to arrays instead of byte slices.
            
    Before:
    
    BenchmarkXOR1K  200000     11092 ns/op  92.31 MB/s
    BenchmarkXOR8K   200000     88136 ns/op  92.95 MB/s
    
    After.
    
    BenchmarkXOR1K  200000      9216 ns/op 111.11 MB/s
    BenchmarkXOR8K   50000     73743 ns/op 111.09 MB/s

It's also easier to control allocations with arrays.

But compile-time checking, as Adam mentioned, is still the most important factor for me.

-Dmitry
Reply all
Reply to author
Forward
0 new messages