aboutsummaryrefslogtreecommitdiff
path: root/message
diff options
context:
space:
mode:
authorJoop Kiefte <ikojba@gmail.com>2021-12-10 13:01:14 +0000
committerGitHub <noreply@github.com>2021-12-10 13:01:14 +0000
commit7aa71680132984ba729c12af727fddd6d23670d2 (patch)
tree8cc5be934b5f6a0720245f0f2e1b8f365e26eec7 /message
parentf0b034381cb18671b9ffe718b01ed429c33fbd12 (diff)
Implement Proof of Work
Diffstat (limited to 'message')
-rw-r--r--message/message.go72
1 files changed, 72 insertions, 0 deletions
diff --git a/message/message.go b/message/message.go
new file mode 100644
index 0000000..14e9cac
--- /dev/null
+++ b/message/message.go
@@ -0,0 +1,72 @@
+package message
+
+import (
+ "crypto/sha256"
+ "fmt"
+ "math/bits"
+)
+
+// Messages on Infodump use a "stamp" using the hashcash algorithm to prevent spam and enable storing messages by importance
+// The Message type contains the message itself and a nonce that is used to verify the stamp
+type Message struct {
+ Message string
+ Nonce int
+}
+
+// Proof of Work: Find the nonce for a message by hashing the message and checking for at least n initial zeroes in the binary representation of the resulting hash
+func (msg *Message) ProofOfWork(n int) {
+ // Create a local copy of the message and start counting
+ m := *msg
+ m.Nonce = 0
+ // Loop until we find a nonce that satisfies the proof of work
+ for {
+ // Increment the nonce and hash the message
+ m.Nonce++
+ hash := m.Hash()
+ // If the hash has at least n initial zeroes, we have found a valid nonce
+ if CountLeadingZeroes(hash) >= n {
+ break
+ }
+ }
+ // Set the message to the local copy
+ *msg = m
+}
+
+// Get the SHA256 hash of a message plus the nonce as a byte slice
+func (m *Message) Hash() [32]byte {
+ hash := sha256.Sum256([]byte(fmt.Sprintf("%s%d", m.Message, m.Nonce)))
+ return hash
+}
+
+// Bitwise count leading zeroes in a byte slice
+func CountLeadingZeroes(b [32]byte) int {
+ count := 0
+ for _, v := range b {
+ // If the byte is zero, that means there are 8 leading zeroes and we need to continue counting
+ if v == 0 {
+ count += 8
+ } else { // Otherwise, we add the number of leading zeroes in the byte and stop counting
+ // Bitwise count leading zeroes in the byte
+ count += bits.LeadingZeros8(v)
+ // If the byte is not zero, we can stop counting
+ break
+ }
+ }
+ return count
+}
+
+// Get the stamp of the message
+func (m *Message) Stamp() string {
+ return fmt.Sprintf("%x", m.Hash())
+}
+
+// Lead is a method that returns the number of leading zeroes in the hash of a message plus its nonce
+func (m *Message) Lead() int {
+ return CountLeadingZeroes(m.Hash())
+}
+
+func New(msg string, n int) *Message {
+ m := Message{Message: msg}
+ m.ProofOfWork(n)
+ return &m
+}