mirror of
https://github.com/vacp2p/mix.git
synced 2026-01-09 20:28:01 -05:00
Add PoW and PoW Tests
This commit is contained in:
39
src/pow.nim
Normal file
39
src/pow.nim
Normal file
@@ -0,0 +1,39 @@
|
||||
import crypto, std/times
|
||||
|
||||
const difficultyLevel = 18 # Difficulty level
|
||||
|
||||
# Helper function to convert integer to sequence of bytes
|
||||
proc intToBytes*(value: int64, byteSize: int): seq[byte] =
|
||||
result = newSeq[byte](byteSize)
|
||||
for i in 0..<byteSize:
|
||||
result[i] = byte((value shr (i * 8)) and 0xFF)
|
||||
|
||||
# Function to check if the computed hash meets the difficulty level
|
||||
proc isValidHash*(hash: array[32, byte]): bool =
|
||||
var zeroBits = 0
|
||||
for byte in hash:
|
||||
for i in countdown(7, 0):
|
||||
if ((byte shr i) and 1) == 0:
|
||||
zeroBits += 1
|
||||
if zeroBits >= difficultyLevel:
|
||||
return true
|
||||
else:
|
||||
return false
|
||||
return false
|
||||
|
||||
# Function to find a valid nonce that produces a hash with at least 'difficultyLevel' leading zeros. Attaches PoW to the input.
|
||||
proc attachPow*(message: seq[byte]): seq[byte] =
|
||||
var nonce = 0
|
||||
var hash: array[32, byte]
|
||||
let timestamp = intToBytes(getTime().toUnix, 8)
|
||||
|
||||
while true:
|
||||
let nonceBytes = intToBytes(nonce, 4)
|
||||
let inputData = message & timestamp & nonceBytes
|
||||
hash = sha256_hash(inputData)
|
||||
|
||||
# Check if hash meets the difficulty level
|
||||
if isValidHash(hash):
|
||||
return inputData
|
||||
|
||||
nonce.inc() # Increment nonce if hash does not meet criteria
|
||||
58
tests/test_pow.nim
Normal file
58
tests/test_pow.nim
Normal file
@@ -0,0 +1,58 @@
|
||||
import unittest, crypto, pow
|
||||
import std/random
|
||||
|
||||
# Helper function to create a dummy hash with leading zeros
|
||||
proc createDummyHash(leadingZeros: int): array[32, byte] =
|
||||
assert leadingZeros >= 0 and leadingZeros <= 256, "Number of leading zero bits must be between 0 and 256"
|
||||
|
||||
var arr: array[32, byte]
|
||||
for i in 0..<32:
|
||||
arr[i] = byte(rand(256))
|
||||
|
||||
let byteIndex = leadingZeros div 8
|
||||
let bitOffset = leadingZeros mod 8
|
||||
|
||||
if leadingZeros > 0:
|
||||
for i in 0..<byteIndex:
|
||||
arr[i] = 0x00
|
||||
|
||||
if byteIndex < 32:
|
||||
let mask = byte(0xFF shl (8 - bitOffset))
|
||||
arr[byteIndex] = arr[byteIndex] and mask
|
||||
|
||||
echo "Generated Hash: ", arr
|
||||
result = arr
|
||||
|
||||
suite "PoW Tests":
|
||||
|
||||
test "intToBytes basic conversions":
|
||||
assert intToBytes(255, 1) == @[255.byte], "Failed to convert int64 to 1 byte"
|
||||
assert intToBytes(65535, 2) == @[255.byte, 255.byte], "Failed to convert int64 to 2 bytes"
|
||||
assert intToBytes(65536, 4) == @[0.byte, 0.byte, 1.byte, 0.byte], "Failed to convert int64 to 4 bytes"
|
||||
|
||||
# Test edge case with maximum int64 value
|
||||
let maxInt64 = (int64(1) shl 63) - 1 # Maximum value for int64
|
||||
assert intToBytes(maxInt64, 8) == @[0xFF.byte, 0xFF.byte, 0xFF.byte, 0xFF.byte, 0xFF.byte, 0xFF.byte, 0xFF.byte, 0x7F.byte], "Failed to convert max int64 value to 8 bytes"
|
||||
|
||||
test "valid hash detection":
|
||||
let hashWith18Zeros = createDummyHash(18)
|
||||
assert isValidHash(hashWith18Zeros), "Hash with 18 leading zeros must be valid"
|
||||
|
||||
let hashWith17Zeros = createDummyHash(17)
|
||||
assert not isValidHash(hashWith17Zeros), "Hash with 17 leading zeros should not be valid"
|
||||
|
||||
test "PoW computation":
|
||||
let message: seq[byte] = cast[seq[byte]]("test message")
|
||||
let result = attachPow(message)
|
||||
|
||||
# Ensure result length is correct
|
||||
assert result.len == message.len + 8 + 4, "Result length should be message length + timestamp (8 bytes) + nonce (4 bytes)"
|
||||
|
||||
# Extract timestamp and nonce from result
|
||||
let timestamp = result[message.len..message.len+7]
|
||||
let nonce = result[message.len+8..message.len+11]
|
||||
|
||||
# Ensure nonce and timestamp are correct
|
||||
let inputData = message & timestamp & nonce
|
||||
let hash = sha256_hash(inputData)
|
||||
assert isValidHash(hash), "Hash of the result does not meet the difficulty level"
|
||||
Reference in New Issue
Block a user