From 461aafcfc962dc0a0253a506dd4dca79a45a493d Mon Sep 17 00:00:00 2001 From: arnaucube Date: Sat, 6 Apr 2019 19:59:14 +0200 Subject: [PATCH] first commit --- README.md | 5 +++++ core/common.go | 51 ++++++++++++++++++++++++++++++++++++++++++ core/common_test.go | 54 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 README.md create mode 100644 core/common.go create mode 100644 core/common_test.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..26836c9 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# slowlorisdb + +Slow and decentralized cryptographically consistent database + +![slowloris](https://04019a5a-a-62cb3a1a-s-sites.googlegroups.com/site/jchristensensdigitalportfolio/slow-loris/IO-moth-eating-frozen-apple-sauce.jpg "slowloris") diff --git a/core/common.go b/core/common.go new file mode 100644 index 0000000..183b5f6 --- /dev/null +++ b/core/common.go @@ -0,0 +1,51 @@ +package core + +import ( + "bytes" + "crypto/sha256" +) + +// Hash is the type for a hash data packet +type Hash [32]byte + +// IsZero returns true if the Hash is empty (all zeroes) +func (h *Hash) IsZero() bool { + z := Hash{} + if bytes.Equal(z[:], h[:]) { + return true + } + return false +} + +// HashBytes performs a hash over a given byte array +func HashBytes(b []byte) Hash { + h := sha256.Sum256(b) + return h +} + +// PoWData is the interface for the data that have the Nonce parameter to calculate the Proof-of-Work +type PoWData interface { + Bytes() []byte + GetNonce() uint64 + IncrementNonce() +} + +// CheckPoW verifies the PoW difficulty of a Hash +func CheckPoW(hash Hash, difficulty int) bool { + var empty [32]byte + if !bytes.Equal(hash[:][0:difficulty], empty[0:difficulty]) { + return false + } + return true +} + +// CalculatePoW calculates the nonce for the given data in order to fit in the current Proof of Work difficulty +func CalculatePoW(data PoWData, difficulty int) (uint64, error) { + hash := HashBytes(data.Bytes()) + for !CheckPoW(hash, difficulty) { + data.IncrementNonce() + + hash = HashBytes(data.Bytes()) + } + return data.GetNonce(), nil +} diff --git a/core/common_test.go b/core/common_test.go new file mode 100644 index 0000000..f47f808 --- /dev/null +++ b/core/common_test.go @@ -0,0 +1,54 @@ +package core + +import ( + "encoding/hex" + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestHashBytes(t *testing.T) { + m := []byte("test") + h := HashBytes(m) + assert.Equal(t, hex.EncodeToString(h[:]), "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08") + assert.True(t, !h.IsZero()) + + z := Hash{} + assert.True(t, z.IsZero()) +} + +type testData struct { + Data []byte + Nonce uint64 +} + +func (d *testData) Bytes() []byte { + b, _ := json.Marshal(d) + return b +} + +func (d *testData) GetNonce() uint64 { + return d.Nonce +} +func (d *testData) IncrementNonce() { + d.Nonce++ +} + +func TestPoW(t *testing.T) { + difficulty := 2 + data := &testData{ + Data: []byte("test"), + Nonce: 0, + } + nonce, err := CalculatePoW(data, difficulty) + assert.Nil(t, err) + data.Nonce = nonce + + h := HashBytes(data.Bytes()) + + assert.Equal(t, hex.EncodeToString(h[:]), "0000020881c02f5171b978e74bb710242e95cc67b36416e382118a7ab2a69321") + + // CheckPoW + assert.True(t, CheckPoW(h, difficulty)) +}