Re-add proof of work

This commit is contained in:
nielsandriesse 2020-11-06 13:56:26 +11:00
parent d735568e94
commit 2d618cc6e9
8 changed files with 76 additions and 5 deletions

View File

@ -99,6 +99,7 @@ target 'SignalMessaging' do
end
target 'SessionMessagingKit' do
pod 'CryptoSwift', :inhibit_warnings => true
pod 'PromiseKit', :inhibit_warnings => true
pod 'SwiftProtobuf', '~> 1.5.0', :inhibit_warnings => true
end

View File

@ -332,6 +332,6 @@ SPEC CHECKSUMS:
YYImage: 6db68da66f20d9f169ceb94dfb9947c3867b9665
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
PODFILE CHECKSUM: 58acf63b2164dadf743187b6a52154721c1c01dd
PODFILE CHECKSUM: 4d6ed1d0ef2a98ce221ebfffc9ae860d4703ec47
COCOAPODS: 1.10.0.rc.1

2
Pods

@ -1 +1 @@
Subproject commit 03a39c064860412e9e69b99f19dd85cd5a9b8aad
Subproject commit 855baeb2e72e3f90eb0cdcbc682162175db2bec8

View File

@ -13,11 +13,13 @@ public enum SendingPipeline {
public enum Error : LocalizedError {
case protoConversionFailed
case protoSerializationFailed
case proofOfWorkCalculationFailed
public var errorDescription: String? {
switch self {
case .protoConversionFailed: return "Couldn't convert message to proto."
case .protoSerializationFailed: return "Couldn't serialize proto."
case .proofOfWorkCalculationFailed: return "Proof of work calculation failed."
}
}
}
@ -35,8 +37,10 @@ public enum SendingPipeline {
let recipient = ""
let base64EncodedData = data.base64EncodedString()
let ttl: UInt64 = 2 * 24 * 60 * 60 * 1000
let timestamp: UInt64 = 0
let nonce = ""
guard let (timestamp, nonce) = ProofOfWork.calculate(ttl: ttl, publicKey: recipient, data: base64EncodedData) else {
SNLog("Proof of work calculation failed.")
return Promise(error: Error.proofOfWorkCalculationFailed)
}
let snodeMessage = SnodeMessage(recipient: recipient, data: base64EncodedData, ttl: ttl, timestamp: timestamp, nonce: nonce)
let _ = SnodeAPI.sendMessage(snodeMessage)
return Promise.value(())

View File

@ -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) }
}
}

View File

@ -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)
}
}

View File

@ -18,9 +18,10 @@ public enum SnodeAPI {
private static let snodeFailureThreshold = 4
private static let targetSwarmSnodeCount = 2
internal static var powDifficulty: UInt = 1
/// - Note: Changing this on the fly is not recommended.
internal static var useOnionRequests = true
public static var powDifficulty: UInt = 1
// MARK: Error
public enum Error : LocalizedError {

View File

@ -618,6 +618,8 @@
C3BBE0A82554D4DE0050F1E3 /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5D92553860B00C340D1 /* JSON.swift */; };
C3BBE0A92554D4DE0050F1E3 /* HTTP.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5BC255385EE00C340D1 /* HTTP.swift */; };
C3BBE0AA2554D4DE0050F1E3 /* Dictionary+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5D52553860A00C340D1 /* Dictionary+Description.swift */; };
C3BBE0B52554F0E10050F1E3 /* ProofOfWork.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BBE0B42554F0E10050F1E3 /* ProofOfWork.swift */; };
C3BBE0C72554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BBE0C62554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift */; };
C3C2A5A3255385C100C340D1 /* SessionSnodeKit.h in Headers */ = {isa = PBXBuildFile; fileRef = C3C2A5A1255385C100C340D1 /* SessionSnodeKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
C3C2A5A6255385C100C340D1 /* SessionSnodeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A59F255385C100C340D1 /* SessionSnodeKit.framework */; };
C3C2A5A7255385C100C340D1 /* SessionSnodeKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A59F255385C100C340D1 /* SessionSnodeKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@ -1609,6 +1611,8 @@
C3AECBEA24EF5244005743DE /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = translations/fa.lproj/Localizable.strings; sourceTree = "<group>"; };
C3BBE0752554CDA60050F1E3 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = "<group>"; };
C3BBE07F2554CDD70050F1E3 /* Storage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Storage.swift; sourceTree = "<group>"; };
C3BBE0B42554F0E10050F1E3 /* ProofOfWork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProofOfWork.swift; sourceTree = "<group>"; };
C3BBE0C62554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FixedWidthInteger+BigEndian.swift"; sourceTree = "<group>"; };
C3C2A59F255385C100C340D1 /* SessionSnodeKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SessionSnodeKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C3C2A5A1255385C100C340D1 /* SessionSnodeKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SessionSnodeKit.h; sourceTree = "<group>"; };
C3C2A5A2255385C100C340D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -3243,6 +3247,15 @@
path = SwiftCSV;
sourceTree = "<group>";
};
C3BBE0B32554F0D30050F1E3 /* Utilities */ = {
isa = PBXGroup;
children = (
C3BBE0C62554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift */,
C3BBE0B42554F0E10050F1E3 /* ProofOfWork.swift */,
);
path = Utilities;
sourceTree = "<group>";
};
C3C2A5A0255385C100C340D1 /* SessionSnodeKit */ = {
isa = PBXGroup;
children = (
@ -3319,6 +3332,7 @@
C3BBE07F2554CDD70050F1E3 /* Storage.swift */,
C300A5BB2554AFFB00555489 /* Messages */,
C300A5F02554B08500555489 /* Pipelines */,
C3BBE0B32554F0D30050F1E3 /* Utilities */,
);
path = SessionMessagingKit;
sourceTree = "<group>";
@ -4878,6 +4892,7 @@
C3C2A74D2553A39700C340D1 /* VisibleMessage.swift in Sources */,
C3C2A7562553A3AB00C340D1 /* VisibleMessage+Quote.swift in Sources */,
C300A5FC2554B0A000555489 /* ReceivingPipeline.swift in Sources */,
C3BBE0B52554F0E10050F1E3 /* ProofOfWork.swift in Sources */,
C3BBE0802554CDD70050F1E3 /* Storage.swift in Sources */,
C3C2A7842553AAF300C340D1 /* SNProto.swift in Sources */,
C3C2A7682553A3D900C340D1 /* VisibleMessage+Contact.swift in Sources */,
@ -4890,6 +4905,7 @@
C3C2A75F2553A3C500C340D1 /* VisibleMessage+LinkPreview.swift in Sources */,
C3C2A74425539EB700C340D1 /* Message.swift in Sources */,
C300A5C92554B04E00555489 /* SessionRequest.swift in Sources */,
C3BBE0C72554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift in Sources */,
C300A5B22554AF9800555489 /* VisibleMessage+Profile.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;