package internal import ( "encoding/binary" "time" "xdx.jelly/xgcl/internal" ) // var nonceCounter atomic.Int64 // atomic.Int64 only available in go 1.19, so we make a new one. type atomicUint64 struct { spin internal.SpinLock n uint64 } var nonceCounter atomicUint64 func (a *atomicUint64) LoadAndAdd(n uint64) uint64 { a.spin.Lock() defer a.spin.Unlock() v := a.n a.n += n return v } // nonce 由时间戳和单调递增的计数器组成 func Nonce() []byte { out := make([]byte, 16) binary.BigEndian.PutUint64(out, uint64(time.Now().UnixNano())) binary.BigEndian.PutUint64(out[8:], nonceCounter.LoadAndAdd(1)) return out } // AddModBytes a = a+b as integer, a,b are bigendian and len(a) >= len(b). func AddModBytes(a, b []byte) { var x uint x = 0 i := len(a) - 1 j := len(b) - 1 for j >= 0 { x += uint(a[i]) + uint(b[j]) a[i] = byte(x) x = x >> 8 j-- i-- } if x == 0 { return } for i >= 0 { a[i] += 1 if a[i] != 0 { break } } } func IncBytes(a []byte) { i := len(a) - 1 for i >= 0 { a[i]++ if a[i] != 0 { break } } }