Merge pull request #5 from loki-project/mikunj/pow-fix

PoW Fixes
pull/6/head
Niels Andriesse 5 years ago committed by GitHub
commit 3c61239374
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -466,6 +466,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = E08CB8D0C89F4717B2D51D41 /* Pods-LokiKit.debug.xcconfig */; baseConfigurationReference = E08CB8D0C89F4717B2D51D41 /* Pods-LokiKit.debug.xcconfig */;
buildSettings = { buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = ""; CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
@ -480,7 +481,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@loader_path/Frameworks", "@loader_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-network.Loki-Messenger.LokiKit"; PRODUCT_BUNDLE_IDENTIFIER = "com.niels-andriesse.loki-network.Loki-Messenger.LokiKit";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -493,6 +494,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = D5C29CCA1A7CDF6063649ED2 /* Pods-LokiKit.release.xcconfig */; baseConfigurationReference = D5C29CCA1A7CDF6063649ED2 /* Pods-LokiKit.release.xcconfig */;
buildSettings = { buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = ""; CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
@ -507,7 +509,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@loader_path/Frameworks", "@loader_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-network.Loki-Messenger.LokiKit"; PRODUCT_BUNDLE_IDENTIFIER = "com.niels-andriesse.loki-network.Loki-Messenger.LokiKit";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;

@ -1,8 +1,8 @@
enum BuildConfiguration { public enum BuildConfiguration {
case debug, production case debug, production
static let current: BuildConfiguration = { public static let current: BuildConfiguration = {
#if DEBUG #if DEBUG
return .debug return .debug
#else #else

@ -4,8 +4,8 @@ import CryptoSwift
public enum Mnemonic { public enum Mnemonic {
public struct Language : Hashable { public struct Language : Hashable {
let filename: String fileprivate let filename: String
let prefixLength: Int fileprivate let prefixLength: Int
public static let english = Language(filename: "english", prefixLength: 3) public static let english = Language(filename: "english", prefixLength: 3)
public static let japanese = Language(filename: "japanese", prefixLength: 3) public static let japanese = Language(filename: "japanese", prefixLength: 3)
@ -20,11 +20,12 @@ public enum Mnemonic {
self.prefixLength = prefixLength self.prefixLength = prefixLength
} }
func loadWordSet() -> [String] { fileprivate func loadWordSet() -> [String] {
if let cachedResult = Language.wordSetCache[self] { if let cachedResult = Language.wordSetCache[self] {
return cachedResult return cachedResult
} else { } else {
let url = Bundle.main.url(forResource: filename, withExtension: "txt")! let bundleID = "com.niels-andriesse.loki-network.Loki-Messenger.LokiKit"
let url = Bundle(identifier: bundleID)!.url(forResource: filename, withExtension: "txt")!
let contents = try! String(contentsOf: url) let contents = try! String(contentsOf: url)
let result = contents.split(separator: ",").map { String($0) } let result = contents.split(separator: ",").map { String($0) }
Language.wordSetCache[self] = result Language.wordSetCache[self] = result
@ -32,7 +33,7 @@ public enum Mnemonic {
} }
} }
func loadTruncatedWordSet() -> [String] { fileprivate func loadTruncatedWordSet() -> [String] {
if let cachedResult = Language.truncatedWordSetCache[self] { if let cachedResult = Language.truncatedWordSetCache[self] {
return cachedResult return cachedResult
} else { } else {

@ -5,47 +5,43 @@ private extension UInt64 {
init(_ decimal: Decimal) { init(_ decimal: Decimal) {
self.init(truncating: decimal as NSDecimalNumber) self.init(truncating: decimal as NSDecimalNumber)
} }
}
// UInt8 Array specific stuff we need
private extension Array where Element == UInt8 {
// Convert a UInt64 into an array of size 8 // Convert a UInt8 array to a UInt64
init(_ uint64: UInt64) { init(_ bytes: [UInt8]) {
let array = stride(from: 0, to: 64, by: 8).reversed().map { precondition(bytes.count <= MemoryLayout<UInt64>.size)
UInt8(uint64 >> $0 & 0x000000FF) var value: UInt64 = 0
for byte in bytes {
value <<= 8
value |= UInt64(byte)
} }
self.init(array) self.init(value)
}
static func > (lhs: [UInt8], rhs: [UInt8]) -> Bool {
guard lhs.count == rhs.count else { return false }
guard let (lhsElement, rhsElement) = zip(lhs, rhs).first(where: { $0 != $1 }) else { return false }
return lhsElement > rhsElement
} }
}
/// Increment the UInt8 array by a given amount
private extension MutableCollection where Element == UInt8, Index == Int {
/// Increment every element by the given amount
/// ///
/// - Parameter amount: The amount to increment by /// - Parameter amount: The amount to increment by
/// - Returns: The incrememnted array /// - Returns: The incremented collection
func increment(by amount: Int) -> [UInt8] { func increment(by amount: Int) -> Self {
var newNonce = self var result = self
var increment = amount var increment = amount
for i in (0..<newNonce.count).reversed() { for i in (0..<result.count).reversed() {
guard increment > 0 else { break } guard increment > 0 else { break }
let sum = Int(newNonce[i]) + increment let sum = Int(result[i]) + increment
newNonce[i] = UInt8(sum % 256) result[i] = UInt8(sum % 256)
increment = sum / 256 increment = sum / 256
} }
return newNonce return result
} }
} }
/** /**
* The main logic which handles proof of work. * The main proof of work logic.
* *
* This was copied from the messenger desktop. * This was copied from the desktop messenger.
* Ref: libloki/proof-of-work.js * Ref: libloki/proof-of-work.js
*/ */
public enum ProofOfWork { public enum ProofOfWork {
@ -59,33 +55,39 @@ public enum ProofOfWork {
} }
}() }()
struct Configuration { public struct Configuration {
var pubKey: String var pubKey: String
var data: String var data: String
var timestamp: Date var timestamp: Date
var ttl: Int var ttl: Int
var payload: [UInt8] { var payload: [UInt8] {
let timestampString = String(Int(timestamp.timeIntervalSince1970)) let timestampString = String(Int(timestamp.timeIntervalSince1970))
let ttlString = String(ttl) let ttlString = String(ttl)
let payloadString = timestampString + ttlString + pubKey + data let payloadString = timestampString + ttlString + pubKey + data
return payloadString.bytes return payloadString.bytes
} }
public init(pubKey: String, data: String, timestamp: Date, ttl: Int) {
self.pubKey = pubKey
self.data = data
self.timestamp = timestamp
self.ttl = ttl
}
} }
/// Calculate a proof of work with the given configuration
/// Calculate a proof of work for the given configuration
/// ///
/// Ref: https://bitmessage.org/wiki/Proof_of_work /// Ref: https://bitmessage.org/wiki/Proof_of_work
/// ///
/// - Parameter config: The configuration data /// - Parameter config: The configuration
/// - Returns: A nonce string or nil if it failed /// - Returns: A nonce string or nil if it failed
static func calculate(with config: Configuration) -> String? { public static func calculate(with config: Configuration) -> String? {
let payload = config.payload let payload = config.payload
let target = calcTarget(ttl: config.ttl, payloadLength: payload.count, nonceTrials: nonceTrialCount) let target = calcTarget(ttl: config.ttl, payloadLength: payload.count, nonceTrials: nonceTrialCount)
// Start with most the max value we can // Start with the max value
var trialValue = [UInt8](repeating: UInt8.max, count: nonceLength) var trialValue = UInt64.max
let initialHash = payload.sha512() let initialHash = payload.sha512()
var nonce = [UInt8](repeating: 0, count: nonceLength) var nonce = [UInt8](repeating: 0, count: nonceLength)
@ -93,17 +95,18 @@ public enum ProofOfWork {
while trialValue > target { while trialValue > target {
nonce = nonce.increment(by: 1) nonce = nonce.increment(by: 1)
// This is different to the bitmessage pow // This is different to the bitmessage POW
// resultHash = hash(nonce + hash(data)) ==> hash(nonce + initialHash) // resultHash = hash(nonce + hash(data)) ==> hash(nonce + initialHash)
let resultHash = (nonce + initialHash).sha512() let resultHash = (nonce + initialHash).sha512()
trialValue = Array(resultHash[0..<8]) let trialValueArray = Array(resultHash[0..<8])
trialValue = UInt64(trialValueArray)
} }
return nonce.toBase64() return nonce.toBase64()
} }
/// Calculate the UInt8 target we need to reach /// Calculate the target we need to reach
private static func calcTarget(ttl: Int, payloadLength: Int, nonceTrials: Int) -> [UInt8] { private static func calcTarget(ttl: Int, payloadLength: Int, nonceTrials: Int) -> UInt64 {
let two16 = UInt64(pow(2, 16) - 1) let two16 = UInt64(pow(2, 16) - 1)
let two64 = UInt64(pow(2, 64) - 1) let two64 = UInt64(pow(2, 64) - 1)
@ -118,8 +121,7 @@ public enum ProofOfWork {
let innerFrac = ttlMult / two16 let innerFrac = ttlMult / two16
let lenPlusInnerFrac = totalLength + innerFrac let lenPlusInnerFrac = totalLength + innerFrac
let denominator = UInt64(nonceTrials) * lenPlusInnerFrac let denominator = UInt64(nonceTrials) * lenPlusInnerFrac
let targetNum = two64 / denominator
return [UInt8](targetNum) return two64 / denominator
} }
} }

@ -1,4 +1,4 @@
@import UIKit #import <UIKit/UIKit.h>
//! Project version number for LokiKit. //! Project version number for LokiKit.
FOUNDATION_EXPORT double LokiKitVersionNumber; FOUNDATION_EXPORT double LokiKitVersionNumber;

@ -44,11 +44,11 @@ PODS:
- CocoaLumberjack - CocoaLumberjack
- SignalCoreKit - SignalCoreKit
- libPhoneNumber-iOS (0.9.13) - libPhoneNumber-iOS (0.9.13)
- LokiKit (0.0.1): - LokiKit (1.0.0):
- CryptoSwift - CryptoSwift
- Curve25519Kit - Curve25519Kit
- SignalCoreKit - SignalCoreKit
- LokiKit/Tests (0.0.1): - LokiKit/Tests (1.0.0):
- CryptoSwift - CryptoSwift
- Curve25519Kit - Curve25519Kit
- SignalCoreKit - SignalCoreKit
@ -304,7 +304,7 @@ SPEC CHECKSUMS:
GRKOpenSSLFramework: 8a3735ad41e7dc1daff460467bccd32ca5d6ae3e GRKOpenSSLFramework: 8a3735ad41e7dc1daff460467bccd32ca5d6ae3e
HKDFKit: 3b6dbbb9d59c221cc6c52c3aa915700cbf24e376 HKDFKit: 3b6dbbb9d59c221cc6c52c3aa915700cbf24e376
libPhoneNumber-iOS: e444379ac18bbfbdefad571da735b2cd7e096caa libPhoneNumber-iOS: e444379ac18bbfbdefad571da735b2cd7e096caa
LokiKit: e18a5ac18b9f2b788b0fa7d0619d9a2a0511dd54 LokiKit: 75ed73c7fcc09fef1f2ec053c7eabf139e015890
Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b
PromiseKit: c609029bdd801f792551a504c695c7d3098b42cd PromiseKit: c609029bdd801f792551a504c695c7d3098b42cd
PureLayout: f08c01b8dec00bb14a1fefa3de4c7d9c265df85e PureLayout: f08c01b8dec00bb14a1fefa3de4c7d9c265df85e
@ -312,7 +312,7 @@ SPEC CHECKSUMS:
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
SignalCoreKit: c2d8132cdedb95d35eb2f8ae7eac0957695d0a8b SignalCoreKit: c2d8132cdedb95d35eb2f8ae7eac0957695d0a8b
SignalMetadataKit: 6fa5e9a53c7f104568662521a2f3874672ff7a02 SignalMetadataKit: 6fa5e9a53c7f104568662521a2f3874672ff7a02
SignalServiceKit: 81b569196f3da6c3964f33b688f7b9ea2bc9a271 SignalServiceKit: 001d38050259216a4478a0a485d761d38add073d
SQLCipher: efbdb52cdbe340bcd892b1b14297df4e07241b7f SQLCipher: efbdb52cdbe340bcd892b1b14297df4e07241b7f
SSZipArchive: cefe1364104a0231268a5deb8495bdf2861f52f0 SSZipArchive: cefe1364104a0231268a5deb8495bdf2861f52f0
Starscream: ef3ece99d765eeccb67de105bfa143f929026cf5 Starscream: ef3ece99d765eeccb67de105bfa143f929026cf5
@ -322,4 +322,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: c2f870c82713a0d73cf24dfe89e1a37ade0bc166 PODFILE CHECKSUM: c2f870c82713a0d73cf24dfe89e1a37ade0bc166
COCOAPODS: 1.5.3 COCOAPODS: 1.6.1

@ -1 +1 @@
Subproject commit cd96e7f7fc60e82a3e70392800105b542057194e Subproject commit 0089714d28c67530fced6131c527c58b3a4302d1

@ -3245,7 +3245,7 @@
files = ( files = (
); );
inputPaths = ( inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Signal/Pods-Signal-frameworks.sh", "${PODS_ROOT}/Target Support Files/Pods-Signal/Pods-Signal-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework", "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework",
"${BUILT_PRODUCTS_DIR}/AxolotlKit/AxolotlKit.framework", "${BUILT_PRODUCTS_DIR}/AxolotlKit/AxolotlKit.framework",
"${BUILT_PRODUCTS_DIR}/CocoaLumberjack/CocoaLumberjack.framework", "${BUILT_PRODUCTS_DIR}/CocoaLumberjack/CocoaLumberjack.framework",
@ -3253,7 +3253,6 @@
"${BUILT_PRODUCTS_DIR}/Curve25519Kit/Curve25519Kit.framework", "${BUILT_PRODUCTS_DIR}/Curve25519Kit/Curve25519Kit.framework",
"${PODS_ROOT}/GRKOpenSSLFramework/OpenSSL-iOS/bin/openssl.framework", "${PODS_ROOT}/GRKOpenSSLFramework/OpenSSL-iOS/bin/openssl.framework",
"${BUILT_PRODUCTS_DIR}/HKDFKit/HKDFKit.framework", "${BUILT_PRODUCTS_DIR}/HKDFKit/HKDFKit.framework",
"${BUILT_PRODUCTS_DIR}/LokiKit/LokiKit.framework",
"${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework", "${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework",
"${BUILT_PRODUCTS_DIR}/PromiseKit/PromiseKit.framework", "${BUILT_PRODUCTS_DIR}/PromiseKit/PromiseKit.framework",
"${BUILT_PRODUCTS_DIR}/PureLayout/PureLayout.framework", "${BUILT_PRODUCTS_DIR}/PureLayout/PureLayout.framework",
@ -3279,7 +3278,6 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Curve25519Kit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Curve25519Kit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HKDFKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HKDFKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LokiKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PureLayout.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PureLayout.framework",
@ -3298,7 +3296,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Signal/Pods-Signal-frameworks.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Signal/Pods-Signal-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
6565655F4068F9E5CDC5687F /* [CP] Check Pods Manifest.lock */ = { 6565655F4068F9E5CDC5687F /* [CP] Check Pods Manifest.lock */ = {
@ -3325,7 +3323,7 @@
files = ( files = (
); );
inputPaths = ( inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-SignalTests/Pods-SignalTests-frameworks.sh", "${PODS_ROOT}/Target Support Files/Pods-SignalTests/Pods-SignalTests-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework", "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework",
"${BUILT_PRODUCTS_DIR}/AxolotlKit/AxolotlKit.framework", "${BUILT_PRODUCTS_DIR}/AxolotlKit/AxolotlKit.framework",
"${BUILT_PRODUCTS_DIR}/CocoaLumberjack/CocoaLumberjack.framework", "${BUILT_PRODUCTS_DIR}/CocoaLumberjack/CocoaLumberjack.framework",
@ -3333,7 +3331,6 @@
"${BUILT_PRODUCTS_DIR}/Curve25519Kit/Curve25519Kit.framework", "${BUILT_PRODUCTS_DIR}/Curve25519Kit/Curve25519Kit.framework",
"${PODS_ROOT}/GRKOpenSSLFramework/OpenSSL-iOS/bin/openssl.framework", "${PODS_ROOT}/GRKOpenSSLFramework/OpenSSL-iOS/bin/openssl.framework",
"${BUILT_PRODUCTS_DIR}/HKDFKit/HKDFKit.framework", "${BUILT_PRODUCTS_DIR}/HKDFKit/HKDFKit.framework",
"${BUILT_PRODUCTS_DIR}/LokiKit/LokiKit.framework",
"${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework", "${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework",
"${BUILT_PRODUCTS_DIR}/PromiseKit/PromiseKit.framework", "${BUILT_PRODUCTS_DIR}/PromiseKit/PromiseKit.framework",
"${BUILT_PRODUCTS_DIR}/PureLayout/PureLayout.framework", "${BUILT_PRODUCTS_DIR}/PureLayout/PureLayout.framework",
@ -3358,7 +3355,6 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Curve25519Kit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Curve25519Kit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HKDFKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HKDFKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LokiKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PureLayout.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PureLayout.framework",
@ -3376,7 +3372,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SignalTests/Pods-SignalTests-frameworks.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SignalTests/Pods-SignalTests-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
F4C416F20E3CB0B25DC10C56 /* [CP] Check Pods Manifest.lock */ = { F4C416F20E3CB0B25DC10C56 /* [CP] Check Pods Manifest.lock */ = {

Loading…
Cancel
Save