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 }