package rand
import (
"errors"
"internal/byteorder"
"internal/chacha8rand"
)
type ChaCha8 struct {
state chacha8rand .State
readBuf [8 ]byte
readLen int
}
func NewChaCha8 (seed [32 ]byte ) *ChaCha8 {
c := new (ChaCha8 )
c .state .Init (seed )
return c
}
func (c *ChaCha8 ) Seed (seed [32 ]byte ) {
c .state .Init (seed )
c .readLen = 0
c .readBuf = [8 ]byte {}
}
func (c *ChaCha8 ) Uint64 () uint64 {
for {
x , ok := c .state .Next ()
if ok {
return x
}
c .state .Refill ()
}
}
func (c *ChaCha8 ) Read (p []byte ) (n int , err error ) {
if c .readLen > 0 {
n = copy (p , c .readBuf [len (c .readBuf )-c .readLen :])
c .readLen -= n
p = p [n :]
}
for len (p ) >= 8 {
byteorder .LePutUint64 (p , c .Uint64 ())
p = p [8 :]
n += 8
}
if len (p ) > 0 {
byteorder .LePutUint64 (c .readBuf [:], c .Uint64 ())
n += copy (p , c .readBuf [:])
c .readLen = 8 - len (p )
}
return
}
func (c *ChaCha8 ) UnmarshalBinary (data []byte ) error {
data , ok := cutPrefix (data , []byte ("readbuf:" ))
if ok {
var buf []byte
buf , data , ok = readUint8LengthPrefixed (data )
if !ok {
return errors .New ("invalid ChaCha8 Read buffer encoding" )
}
c .readLen = copy (c .readBuf [len (c .readBuf )-len (buf ):], buf )
}
return chacha8rand .Unmarshal (&c .state , data )
}
func cutPrefix(s , prefix []byte ) (after []byte , found bool ) {
if len (s ) < len (prefix ) || string (s [:len (prefix )]) != string (prefix ) {
return s , false
}
return s [len (prefix ):], true
}
func readUint8LengthPrefixed(b []byte ) (buf , rest []byte , ok bool ) {
if len (b ) == 0 || len (b ) < int (1 +b [0 ]) {
return nil , nil , false
}
return b [1 : 1 +b [0 ]], b [1 +b [0 ]:], true
}
func (c *ChaCha8 ) MarshalBinary () ([]byte , error ) {
if c .readLen > 0 {
out := []byte ("readbuf:" )
out = append (out , uint8 (c .readLen ))
out = append (out , c .readBuf [len (c .readBuf )-c .readLen :]...)
return append (out , chacha8rand .Marshal (&c .state )...), nil
}
return chacha8rand .Marshal (&c .state ), nil
}
The pages are generated with Golds v0.7.0-preview . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .