Added io.Reader/Writers to satisfy io.Copy() interface

Added cmd/main for CLI usage

Signed-off-by: Russ Magee <rmagee@gmail.com>
This commit is contained in:
Russ Magee 2020-02-06 18:52:52 -08:00
parent ce6570ddcc
commit 41d01db0ab
2 changed files with 55 additions and 4 deletions

33
cmd/main.go Normal file
View file

@ -0,0 +1,33 @@
// WANDERER - a crypto doodle that appears to give adequate
// protection to data in a stream cipher context (?)
//
// Properties visualized using https://github.com/circulosmeos/circle
//
// test command-line 'main' program
package main
// TODOs:
// -use a crypto rand (eg mtwist64) instead of go pkg rand?
// -define s-box rotation/shuffle schema
// -devise p-box schema
// ...
import (
"flag"
"io"
"os"
"blitter.com/go/cryptmt"
)
var (
k string
)
func main() {
flag.StringVar(&k, "k", "WARNING_DEFAULT_KEY", "Key (NOTE insecure specified on command line)")
flag.Parse()
c := cryptmt.New(os.Stdin, os.Stdout, []byte(k))
_, _ = io.Copy(c, c)
}

View file

@ -1,6 +1,6 @@
// Package CryptMT - implementation of cryptMTv1 stream cipher
// (but with mtwist64 as base accum)
// https://eprint.iacr.org/2005/165.pdf
// (but with mtwist64 as base accum)
// https://eprint.iacr.org/2005/165.pdf
package cryptmt
// TODO rlm: according to go docs, stream ciphers do not implement the
@ -11,11 +11,14 @@ package cryptmt
import (
"errors"
"io"
mtwist "blitter.com/go/mtwist"
)
type Cipher struct {
r io.Reader
w io.Writer
accum uint64
m *mtwist.MT19937_64
}
@ -28,8 +31,8 @@ func (c *Cipher) yield() (r byte) {
// New creates and returns a Cipher. The key argument should be the
// CryptMT key, 64 bytes.
func New(key []byte) (c *Cipher) {
c = &Cipher{m: mtwist.New()}
func New(r io.Reader, w io.Writer, key []byte) (c *Cipher) {
c = &Cipher{m: mtwist.New(), r: r, w: w}
c.m.SeedFullState(key)
c.accum = 1
// from paper, discard first 64 bytes of output
@ -39,6 +42,21 @@ func New(key []byte) (c *Cipher) {
return c
}
func (c *Cipher) Read(p []byte) (n int, err error) {
n, err = c.r.Read(p)
if err == nil {
for idx := 0; idx < n; idx++ {
p[idx] = p[idx] ^ c.yield()
}
}
return n, err
}
func (c *Cipher) Write(p []byte) (n int, err error) {
n, err = c.w.Write(p)
return n, err
}
// XORKeyStream XORs each byte in the given slice with a byte from the
// cipher's key stream. Dst and src must overlap entirely or not at all.
//