mirror of https://github.com/oxen-io/session-ios
Re-add proof of work
parent
d735568e94
commit
2d618cc6e9
@ -1 +1 @@
|
||||
Subproject commit 03a39c064860412e9e69b99f19dd85cd5a9b8aad
|
||||
Subproject commit 855baeb2e72e3f90eb0cdcbc682162175db2bec8
|
@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
internal extension FixedWidthInteger {
|
||||
|
||||
init?(fromBigEndianBytes bytes: [UInt8]) {
|
||||
guard bytes.count == MemoryLayout<Self>.size else { return nil }
|
||||
self = bytes.reduce(0) { ($0 << 8) | Self($1) }
|
||||
}
|
||||
|
||||
var bigEndianBytes: [UInt8] {
|
||||
return withUnsafeBytes(of: bigEndian) { [UInt8]($0) }
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
import SessionUtilities
|
||||
import SessionSnodeKit
|
||||
|
||||
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(SnodeAPI.powDifficulty)
|
||||
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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue