diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..dbd29cc --- /dev/null +++ b/cmd/main.go @@ -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) +} diff --git a/cryptmt.go b/cryptmt.go index 6888667..3a627ed 100644 --- a/cryptmt.go +++ b/cryptmt.go @@ -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. //