diff options
Diffstat (limited to 'src/gobang.go')
-rw-r--r-- | src/gobang.go | 207 |
1 files changed, 128 insertions, 79 deletions
diff --git a/src/gobang.go b/src/gobang.go index 4ce13ff..4775dfc 100644 --- a/src/gobang.go +++ b/src/gobang.go @@ -19,19 +19,18 @@ import ( "strings" "sync" "syscall" - "testing" "time" ) -type LogLevel int8 +type logLevel int8 const ( - LevelNone LogLevel = 0 - LevelError LogLevel = 1 - LevelWarning LogLevel = 2 - LevelInfo LogLevel = 3 - LevelDebug LogLevel = 4 + LevelNone logLevel = 0 + LevelError logLevel = 1 + LevelWarning logLevel = 2 + LevelInfo logLevel = 3 + LevelDebug logLevel = 4 ) const lengthUUID = 16 @@ -52,7 +51,15 @@ type CopyResult struct { -const MaxInt = int((^uint(0)) >> 1) +const maxInt = int((^uint(0)) >> 1) + +const ( + scrypt_N = 32768 + scrypt_r = 8 + scrypt_p = 1 + scryptSaltMinLength = 32 + scryptDesiredLength = 32 +) @@ -62,14 +69,17 @@ const MaxInt = int((^uint(0)) >> 1) // // 52 bits of time in milliseconds since epoch // 12 bits of (fractional nanoseconds) >> 8 + var lastV7Time int64 -var timeMu sync.Mutex +var timeMutex sync.Mutex + + +// Local variables -// Global variables var ( - Level LogLevel = LevelInfo - EmitMetric bool = true - Hostname string + level logLevel = LevelInfo + emitMetric bool = true + hostname string ) @@ -104,7 +114,7 @@ var ( // // Using a higher iteration count will increase the cost of an exhaustive // search but will also make derivation proportionally slower. -func PBKDF2Key( +func _PBKDF2Key( password []byte, salt []byte, iter int, @@ -127,7 +137,7 @@ func PBKDF2Key( buf[0] = byte(block >> 24) buf[1] = byte(block >> 16) buf[2] = byte(block >> 8) - buf[3] = byte(block) + buf[3] = byte(block >> 0) prf.Write(buf[:4]) dk = prf.Sum(dk) T := dk[len(dk) - hashLen:] @@ -341,7 +351,7 @@ func smix(b []byte, r int, N int, v []uint32, xy []uint32) { // and p=1. The parameters N, r, and p should be increased as memory latency and // CPU parallelism increases; consider setting N to the highest power of 2 you // can derive within 100 milliseconds. Remember to get a good random salt. -func Scrypt( +func scrypt( password []byte, salt []byte, N int, @@ -353,35 +363,35 @@ func Scrypt( return nil, errors.New("scrypt: N must be > 1 and a power of 2") } if ((uint64(r) * uint64(p)) >= (1 << 30)) || - r > MaxInt / 128 / p || - r > MaxInt / 256 || - N > MaxInt / 128 / r { + r > maxInt / 128 / p || + r > maxInt / 256 || + N > maxInt / 128 / r { return nil, errors.New("scrypt: parameters are too large") } xy := make([]uint32, 64 * r) v := make([]uint32, 32 * N * r) - b := PBKDF2Key(password, salt, 1, p * 128 * r, sha256.New) + b := _PBKDF2Key(password, salt, 1, p * 128 * r, sha256.New) for i := 0; i < p; i++ { smix(b[i * 128 * r:], r, N, v, xy) } - return PBKDF2Key(password, b, 1, keyLen, sha256.New), nil + return _PBKDF2Key(password, b, 1, keyLen, sha256.New), nil } -func CopyData( - c chan CopyResult, - label string, - from io.Reader, - to io.WriteCloser, -) { - written, err := io.Copy(to, from) - c <- CopyResult { - Written: written, - Err: err, - Label: label, - } +func Salt() []byte { + var buf [scryptSaltMinLength]byte + _, err := io.ReadFull(rand.Reader, buf[:]) + FatalIf(err) + return buf[:] +} + +func Hash(password []byte, salt []byte) []byte{ + Assert(len(salt) >= scryptSaltMinLength, "salt is too small") + hash, err := scrypt(password, salt, scrypt_N, scrypt_r, scrypt_p, scryptDesiredLength) + FatalIf(err) + return hash } // FIXME: finish rewriting @@ -397,8 +407,8 @@ func getV7Time(nano int64) (int64, int64) { seq := (nano - (milli * nanoPerMilli)) >> 8 now := milli << (12 + seq) - timeMu.Lock() - defer timeMu.Unlock() + timeMutex.Lock() + defer timeMutex.Unlock() if now <= lastV7Time { now = lastV7Time + 1 milli = now >> 12 @@ -460,7 +470,7 @@ func (uuid UUID) ToString() string { } func Debug(message string, type_ string, args ...any) { - if Level < LevelDebug { + if level < LevelDebug { return } @@ -478,7 +488,7 @@ func Debug(message string, type_ string, args ...any) { } func Info(message string, type_ string, args ...any) { - if Level < LevelInfo { + if level < LevelInfo { return } @@ -496,7 +506,7 @@ func Info(message string, type_ string, args ...any) { } func Warning(message string, type_ string, args ...any) { - if Level < LevelWarning { + if level < LevelWarning { return } @@ -514,7 +524,7 @@ func Warning(message string, type_ string, args ...any) { } func Error(message string, type_ string, args ...any) { - if Level < LevelError { + if level < LevelError { return } @@ -532,7 +542,7 @@ func Error(message string, type_ string, args ...any) { } func Metric(type_ string, label string, args ...any) { - if !EmitMetric { + if !emitMetric { return } @@ -602,35 +612,69 @@ func MakeCounter(label string) func(...any) { } } -func ErrorIf(t *testing.T, err error) { +func ErrorIf(err error) { if err != nil { - t.Errorf("Unexpected error: %#v\n", err) + fmt.Fprintf(os.Stderr, "Unexpected error: %#v\n", err) + os.Exit(1) } } -func ErrorNil(t *testing.T, err error) { +func ErrorNil(err error) { if err == nil { - t.Errorf("Expected error, got nil\n") + fmt.Fprintf(os.Stderr, "Expected error, got nil\n") + os.Exit(1) + } +} + +func showColour() bool { + return os.Getenv("NO_COLOUR") == "" +} + +func TestStart(name string) { + fmt.Fprintf(os.Stderr, "%s:\n", name) +} + +func Testing(message string, body func()) { + if showColour() { + fmt.Fprintf(os.Stderr, "\033[0;33mtesting\033[0m: %s... ", message) + body() + fmt.Fprint(os.Stderr, "\033[0;32mOK\033[0m.\n") + } else { + fmt.Fprintf(os.Stderr, "testing: %s...", message) + body() + fmt.Fprint(os.Stderr, " OK.\n") } } -func AssertEqual(t *testing.T, given any, expected any) { +func AssertEqual(given any, expected any) { if !reflect.DeepEqual(given, expected) { - t.Errorf("given != expected\n") - t.Errorf("given: %#v\n", given) - t.Errorf("expected: %#v\n", expected) + if showColour() { + fmt.Fprintf(os.Stderr, "\033[0;31mERR\033[0m.\n") + } else { + fmt.Fprintf(os.Stderr, "ERR.\n") + } + fmt.Fprintf(os.Stderr, "given != expected\n") + fmt.Fprintf(os.Stderr, "given: %#v\n", given) + fmt.Fprintf(os.Stderr, "expected: %#v\n", expected) + os.Exit(1) } } -func AssertEqualI(t *testing.T, i int, given any, expected any) { +func AssertEqualI(i int, given any, expected any) { if !reflect.DeepEqual(given, expected) { - t.Errorf("given != expected (i = %d)\n", i) - t.Errorf("given: %#v\n", given) - t.Errorf("expected: %#v\n", expected) + if showColour() { + fmt.Fprintf(os.Stderr, "\033[0;31mERR\033[0m.\n") + } else { + fmt.Fprintf(os.Stderr, "ERR.\n") + } + fmt.Fprintf(os.Stderr, "given != expected (i = %d)\n", i) + fmt.Fprintf(os.Stderr, "given: %#v\n", given) + fmt.Fprintf(os.Stderr, "expected: %#v\n", expected) + os.Exit(1) } } -func SetLoggerOutput(w io.Writer) { +func setLoggerOutput(w io.Writer) { slog.SetDefault(slog.New(slog.NewJSONHandler(w, &slog.HandlerOptions { AddSource: true, })).With( @@ -643,47 +687,47 @@ func SetLoggerOutput(w io.Writer) { )) } -func LevelFromString(name string) (bool, LogLevel) { - level := strings.ToUpper(name) +func levelFromString(name string) (bool, logLevel) { + label := strings.ToUpper(name) - if level == "NONE" { + if label == "NONE" { return true, LevelNone } - if level == "ERROR" { + if label == "ERROR" { return true, LevelError } - if level == "WARNING" { + if label == "WARNING" { return true, LevelWarning } - if level == "INFO" { + if label == "INFO" { return true, LevelInfo } - if level == "DEBUG" { + if label == "DEBUG" { return true, LevelDebug } - return false, Level + return false, level } -func SetLogLevel() { - ok, level := LevelFromString(os.Getenv("LOG_LEVEL")) +func setLogLevel() { + ok, envLevel := levelFromString(os.Getenv("LOG_LEVEL")) if ok { - Level = level + level = envLevel } } -func SetMetric() { +func setMetric() { if os.Getenv("NO_METRIC") != "" { - EmitMetric = false + emitMetric = false } } -func SetTraceback() { +func setTraceback() { if os.Getenv("GOTRACEBACK") == "" { debug.SetTraceback("crash") } @@ -705,21 +749,26 @@ func FatalIf(err error) { } } -func SetHostname() { - var err error - Hostname, err = os.Hostname() - FatalIf(err) +func Assert(condition bool, message string) { + if !condition { + Fatal(errors.New(message)) + } } -func Init() { - SetLoggerOutput(os.Stdout) - SetLogLevel() - SetMetric() - SetTraceback() - SetHostname() +func Unreachable() { + Assert(false, "Unreachable code was reached") } +func setHostname() { + var err error + hostname, err = os.Hostname() + FatalIf(err) +} -func Main() { - fmt.Println(NewUUID().ToString()) +func Init() { + setLoggerOutput(os.Stdout) + setLogLevel() + setMetric() + setTraceback() + setHostname() } |