From e5c73c2969cce7fa56a30ff1a527ffa1ea2745b2 Mon Sep 17 00:00:00 2001 From: Brian Dillmann Date: Thu, 3 Aug 2017 11:50:40 -0400 Subject: [PATCH] make cryptographically secure randoms the default --- README.md | 4 ++-- sputter.go | 24 ++++++++++++++++++++++-- sputter_test.go | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index df1b4b4..9766344 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # sputter -_WARNING: I AM NOT CRYPTO FRIENDLY_ - POSIX basic regular expressions to psuedo random string generator, just for fun :) ### Usage @@ -31,6 +29,8 @@ WordWord Њѯѹկ¢↔≡♲ ``` +_For cryptographically insecure usage, use the `GenInsecure` function in place of `Gen`_ + ### Supported Operations diff --git a/sputter.go b/sputter.go index 6f11030..0c9bc4b 100644 --- a/sputter.go +++ b/sputter.go @@ -2,7 +2,9 @@ package sputter import ( "bytes" + crypto "crypto/rand" "fmt" + "math/big" "math/rand" "regexp/syntax" "time" @@ -11,15 +13,33 @@ import ( const ( repetitionMax = 100 + maxUint64 = ^uint64(0) + maxInt64 = int64(maxUint64 >> 1) ) +func init() { + rand.Seed(time.Now().UTC().UnixNano()) +} + // Gen takes a regular expression and attempts // to generate a pseudo-randomized string that // matches the input expression. func Gen(exp string) (string, error) { - // setup random package - rand.Seed(time.Now().UTC().UnixNano()) + // cryptographically seed random package + bigSeed, err := crypto.Int(crypto.Reader, big.NewInt(maxInt64)) + if err != nil { + return "", err + } + rand.Seed(bigSeed.Int64()) + + r, err := syntax.Parse(exp, 0) + if err != nil { + return "", err + } + return sput(r) +} +func GenInsecure(exp string) (string, error) { r, err := syntax.Parse(exp, 0) if err != nil { return "", err diff --git a/sputter_test.go b/sputter_test.go index 4353cfe..f700e8b 100644 --- a/sputter_test.go +++ b/sputter_test.go @@ -58,6 +58,7 @@ func TestEndLine(t *testing.T) { } func testSputHundredEmoji(t *testing.T, exp string) { + // test cryptographically secure function 100 times for i := 0; i < 100; i++ { s, err := Gen(exp) if err != nil { @@ -73,4 +74,21 @@ func testSputHundredEmoji(t *testing.T, exp string) { t.Error(err) } } + + // do same for cryptographically insecure function + for i := 0; i < 100; i++ { + s, err := GenInsecure(exp) + if err != nil { + t.Error(`error from Gen:`, err) + } + + match, err := regexp.Match(exp, []byte(s)) + if !match { + t.Errorf(`output string "%s" does not match expression "%s"`, s, exp) + } + + if err != nil { + t.Error(err) + } + } }