@@ -19,7 +19,9 @@ package password
1919
2020import (
2121 "fmt"
22+ "math/rand"
2223 "testing"
24+ "time"
2325)
2426
2527func TestBench (t * testing.T ) {
@@ -45,23 +47,68 @@ func TestBench(t *testing.T) {
4547 t .FailNow ()
4648 }
4749}
48- func TestHash (t * testing.T ) {
49- output , err := Hash ("password1234" , "masterpassphrase" , 0 , ScryptParams {N : 32768 , R : 16 , P : 1 }, DefaultParams )
50- if err != nil {
51- t .Log (err )
52- t .FailNow ()
50+
51+ var src = rand .NewSource (time .Now ().UnixNano ())
52+
53+ const (
54+ chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+<>?/,.:;[]-~`"
55+ letterIdxBits = 6 // 6 bits to represent a letter index
56+ letterIdxMask = 1 << letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
57+ letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
58+ )
59+
60+ func RandStringBytesMaskImprSrc (n int ) string {
61+ b := make ([]byte , n )
62+ // A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
63+ for i , cache , remain := n - 1 , src .Int63 (), letterIdxMax ; i >= 0 ; {
64+ if remain == 0 {
65+ cache , remain = src .Int63 (), letterIdxMax
66+ }
67+ if idx := int (cache & letterIdxMask ); idx < len (chars ) {
68+ b [i ] = chars [idx ]
69+ i --
70+ }
71+ cache >>= letterIdxBits
72+ remain --
5373 }
54- fmt .Println ("Output: " + output )
55- fmt .Printf ("Length: %v\n " , len (output ))
5674
57- err = Verify ("password1234" , "masterpassphrase" , output )
58- if err != nil {
59- t .Log (err )
60- t .FailNow ()
75+ return string (b )
76+ }
77+
78+ func TestHash (t * testing.T ) {
79+
80+ var total int
81+ runs := 52
82+ // Test expect success
83+ for i := 2 ; i < runs ; i ++ {
84+ // Generate Test Password
85+ testUserPass := RandStringBytesMaskImprSrc (i * 4 )
86+ testMasterPass := RandStringBytesMaskImprSrc (i * 4 )
87+ // Hash Password
88+ output , err := Hash (testUserPass , testMasterPass , 0 , ScryptParams {N : 32768 , R : 16 , P : 1 }, DefaultParams )
89+ if err != nil {
90+ t .Log (err )
91+ t .FailNow ()
92+ }
93+ t .Logf ("Output: " + output )
94+
95+ // Check Output Length
96+ lgth := len (output )
97+ if lgth > 225 {
98+ t .Logf ("Output Length over 225 chars at %v for input userpass length %v" , lgth , len (testUserPass ))
99+ }
100+ total = total + lgth
101+
102+ // Verify Password
103+ if err := Verify (testUserPass , testMasterPass , output ); err != nil {
104+ t .Log (err )
105+ t .FailNow ()
106+ }
61107 }
108+ fmt .Printf ("Average length of %v runs: %v\n " , runs , total / runs )
62109
63110 // Test with Bad Params
64- _ , err = Hash ("password1234" , "masterpassphrase" , 0 , ScryptParams {N : 2048 , R : 16 , P : 1 }, DefaultParams )
111+ _ , err : = Hash ("password1234" , "masterpassphrase" , 0 , ScryptParams {N : 2048 , R : 16 , P : 1 }, DefaultParams )
65112 if err != ErrScryptParamN {
66113 t .Log ("Expected Scrypt N failure for user params" )
67114 t .FailNow ()
0 commit comments