//go:build !solution package otp import ( "io" ) type cipherReader struct { r io.Reader prng io.Reader } type cipherWriter struct { w io.Writer prng io.Reader } func (c *cipherReader) Read(p []byte) (n int, err error) { n, err = c.r.Read(p) if err != nil { if err == io.EOF { p = p[:n] } else { return } } rand := make([]byte, n) _, rngErr := c.prng.Read(rand) if rngErr != nil { return } for i := 0; i < n; i++ { p[i] ^= rand[i] } return } func (c *cipherWriter) Write(p []byte) (n int, err error) { data := make([]byte, len(p)) _, err = c.prng.Read(data) if err != nil { return } for i := 0; i < len(p); i++ { data[i] ^= p[i] } n, err = c.w.Write(data) return } func NewReader(r io.Reader, prng io.Reader) io.Reader { return &cipherReader{r, prng} } func NewWriter(w io.Writer, prng io.Reader) io.Writer { return &cipherWriter{w, prng} }