session-ios/SessionMessagingKit/Utilities/ProofOfWork.swift
Morgan Pretty 03fb5cbeeb Cleanup and tweaks
Fixed some compilation issues.
Removed an unused dependency.
Cleaned up the Podfile to minimise duplication.
Pointed at an oxen fork of SignalCoreKit instead of a personal one.
2022-01-25 12:05:45 +11:00

36 lines
1.5 KiB
Swift

import SessionSnodeKit
import SessionUtilitiesKit
enum ProofOfWork {
/// A modified version of [Bitmessage's Proof of Work Implementation](https://bitmessage.org/wiki/Proof_of_work).
static func calculate(ttl: UInt64, publicKey: String, data: String) -> (timestamp: UInt64, base64EncodedNonce: String)? {
let nonceSize = MemoryLayout<UInt64>.size
// Get millisecond timestamp
let timestamp = NSDate.millisecondTimestamp()
// Construct payload
let payloadAsString = String(timestamp) + String(ttl) + publicKey + data
let payload = payloadAsString.bytes
// Calculate target
let numerator = UInt64.max
let difficulty = UInt64(1)
let totalSize = UInt64(payload.count + nonceSize)
let ttlInSeconds = ttl / 1000
let denominator = difficulty * (totalSize + (ttlInSeconds * totalSize) / UInt64(UInt16.max))
let target = numerator / denominator
// Calculate proof of work
var value = UInt64.max
let payloadHash = payload.sha512()
var nonce = UInt64(0)
while value > target {
nonce = nonce &+ 1
let hash = (nonce.bigEndianBytes + payloadHash).sha512()
guard let newValue = UInt64(fromBigEndianBytes: [UInt8](hash[0..<nonceSize])) else { return nil }
value = newValue
}
// Encode as base 64
let base64EncodedNonce = nonce.bigEndianBytes.toBase64()
// Return
return (timestamp, base64EncodedNonce)
}
}