nonce.go 860 Bytes
Newer Older
Jordan Sissel's avatar
Jordan Sissel committed
1
package sodium
Jordan Sissel's avatar
Jordan Sissel committed
2 3 4
import (
  "unsafe"
)
Jordan Sissel's avatar
Jordan Sissel committed
5

6 7 8
func RandomNonceStrategy() (func() []byte) {
  return func () ([]byte) {
    var nonce [crypto_box_NONCEBYTES]byte
Jordan Sissel's avatar
Jordan Sissel committed
9
    Randombytes(nonce[:])
10
    return nonce[:]
Jordan Sissel's avatar
Jordan Sissel committed
11 12 13
  }
}

14
func IncrementalNonceStrategy() (func() []byte) {
Jordan Sissel's avatar
Jordan Sissel committed
15 16 17 18 19 20
  var nonce [crypto_box_NONCEBYTES]byte
  Randombytes(nonce[:])

  // TODO(sissel): Make the high-8 bytes of the nonce based on current time to
  // help avoid collisions?

21
  return func() ([]byte) {
Jordan Sissel's avatar
Jordan Sissel committed
22
    increment(nonce[:], 1)
23
    return nonce[:]
Jordan Sissel's avatar
Jordan Sissel committed
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
  }
}

func increment(bytes []byte, value uint64) {
  for offset, carry := 0, false; carry == true || offset == 0; offset += 8 { 
    ptr := (*uint64)(unsafe.Pointer((&bytes[offset])))
    old := *ptr
    *ptr += value
    if old > *ptr {
      // overflow, carry and continue
      value = 1
      carry = true
    } else {
      carry = false
    }
  }
}