github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/teams/nonce.go (about)

     1  package teams
     2  
     3  import (
     4  	"encoding/base64"
     5  	"encoding/binary"
     6  
     7  	"github.com/keybase/client/go/libkb"
     8  )
     9  
    10  // nonce24 manages a 24-byte nonce with a 20-byte prefix
    11  // and a 4-byte counter.  The counter is incremented every
    12  // time the full nonce is retrieved so that no nonces are
    13  // reused.
    14  type nonce24 struct {
    15  	prefix  []byte
    16  	counter uint32
    17  }
    18  
    19  // newNonce24 creates a nonce with a random 20 byte prefix and
    20  // a counter starting at 0.
    21  func newNonce24() (*nonce24, error) {
    22  	prefix, err := libkb.RandBytes(20)
    23  	if err != nil {
    24  		return nil, err
    25  	}
    26  	return &nonce24{prefix: prefix}, nil
    27  }
    28  
    29  // newNonce24 creates a nonce with a random 20 byte prefix and
    30  // a counter starting at 1.
    31  func newNonce24SkipZero() (*nonce24, error) {
    32  	n, err := newNonce24()
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  	n.counter = 1
    37  	return n, nil
    38  }
    39  
    40  // Nonce gets the 24 byte nonce prefix + counter and increments
    41  // the counter so that the nonce isn't reused.
    42  func (n *nonce24) Nonce() ([24]byte, uint32) {
    43  	var nonce [24]byte
    44  	copy(nonce[:20], n.prefix)
    45  	copy(nonce[20:24], n.counterBytes())
    46  	counter := n.counter
    47  	n.counter++
    48  	return nonce, counter
    49  }
    50  
    51  // PrefixEncoded returns a base64 encoding of the 20 byte nonce prefix.
    52  func (n *nonce24) PrefixEncoded() string {
    53  	return base64.StdEncoding.EncodeToString(n.prefix)
    54  }
    55  
    56  func (n *nonce24) counterBytes() []byte {
    57  	b := [4]byte{}
    58  	binary.BigEndian.PutUint32(b[:], n.counter)
    59  	return b[:]
    60  }