diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 291555a9..a47113a5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,6 +11,7 @@ on: pull_request: branches: - master + - alpha # Allows you to run this workflow manually from the Actions tab workflow_dispatch: diff --git a/Sources/TorusUtils/AbstractTorusUtils.swift b/Sources/TorusUtils/AbstractTorusUtils.swift index 6408e820..8d01ed79 100644 --- a/Sources/TorusUtils/AbstractTorusUtils.swift +++ b/Sources/TorusUtils/AbstractTorusUtils.swift @@ -1,11 +1,10 @@ import BigInt -import FetchNodeDetails -import CryptoSwift import CommonSources +import FetchNodeDetails import Foundation public protocol AbstractTorusUtils { - func retrieveShares(endpoints: [String], torusNodePubs: [TorusNodePubModel], indexes: [BigUInt], verifier: String, verifierParams: VerifierParams, idToken: String, extraParams: [String:Codable]) async throws -> TorusKey + func retrieveShares(endpoints: [String], torusNodePubs: [TorusNodePubModel], indexes: [BigUInt], verifier: String, verifierParams: VerifierParams, idToken: String, extraParams: [String: Codable]) async throws -> TorusKey - func getPublicAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, extendedVerifierId :String?) async throws -> TorusPublicKey + func getPublicAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, extendedVerifierId: String?) async throws -> TorusPublicKey } diff --git a/Sources/TorusUtils/Constants.swift b/Sources/TorusUtils/Constants.swift index 1e9805f1..e5af863f 100644 --- a/Sources/TorusUtils/Constants.swift +++ b/Sources/TorusUtils/Constants.swift @@ -1,4 +1,4 @@ -enum JRPC_METHODS { +enum JRPC_METHODS { static let GET_OR_SET_KEY = "GetPubKeyOrKeyAssign" static let COMMITMENT_REQUEST = "CommitmentRequest" static let IMPORT_SHARE = "ImportShare" diff --git a/Sources/TorusUtils/Convenience/Array+Extension.swift b/Sources/TorusUtils/Convenience/Array+Extension.swift deleted file mode 100755 index b7323d93..00000000 --- a/Sources/TorusUtils/Convenience/Array+Extension.swift +++ /dev/null @@ -1,16 +0,0 @@ -// web3swift -// -// Created by Alex Vlasov. -// Copyright © 2018 Alex Vlasov. All rights reserved. -// - -import Foundation - -extension Array { - public func split(intoChunksOf chunkSize: Int) -> [[Element]] { - return stride(from: 0, to: count, by: chunkSize).map { - let endIndex = ($0.advanced(by: chunkSize) > self.count) ? self.count - $0 : chunkSize - return Array(self[$0 ..< $0.advanced(by: endIndex)]) - } - } -} diff --git a/Sources/TorusUtils/Convenience/Base58.swift b/Sources/TorusUtils/Convenience/Base58.swift deleted file mode 100755 index f7077440..00000000 --- a/Sources/TorusUtils/Convenience/Base58.swift +++ /dev/null @@ -1,167 +0,0 @@ -// web3swift -// -// Created by Alex Vlasov. -// Copyright © 2018 Alex Vlasov. All rights reserved. -// - -import Foundation - -struct Base58 { - static let base58Alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" - - // Encode - static func base58FromBytes(_ bytes: [UInt8]) -> String { - var bytes = bytes - var zerosCount = 0 - var length = 0 - - for b in bytes { - if b != 0 { break } - zerosCount += 1 - } - - bytes.removeFirst(zerosCount) - - let size = bytes.count * 138 / 100 + 1 - - var base58: [UInt8] = Array(repeating: 0, count: size) - for b in bytes { - var carry = Int(b) - var i = 0 - - for j in 0 ... base58.count - 1 where carry != 0 || i < length { - carry += 256 * Int(base58[base58.count - j - 1]) - base58[base58.count - j - 1] = UInt8(carry % 58) - carry /= 58 - i += 1 - } - - assert(carry == 0) - - length = i - } - - // skip leading zeros - var zerosToRemove = 0 - var str = "" - for b in base58 { - if b != 0 { break } - zerosToRemove += 1 - } - base58.removeFirst(zerosToRemove) - - while 0 < zerosCount { - str = "\(str)1" - zerosCount -= 1 - } - - for b in base58 { - // str = "\(str)\(base58Alphabet[String.Index(encodedOffset: Int(b))])" - str = "\(str)\(base58Alphabet[String.Index(utf16Offset: Int(b), in: base58Alphabet)])" - } - - return str - } - - // Decode - static func bytesFromBase58(_ base58: String) -> [UInt8] { - // remove leading and trailing whitespaces - let string = base58.trimmingCharacters(in: CharacterSet.whitespaces) - - guard !string.isEmpty else { return [] } - - var zerosCount = 0 - var length = 0 - for c in string { - if c != "1" { break } - zerosCount += 1 - } - - let size = string.lengthOfBytes(using: String.Encoding.utf8) * 733 / 1000 + 1 - zerosCount - var base58: [UInt8] = Array(repeating: 0, count: size) - for c in string where c != " " { - // search for base58 character - guard let base58Index = base58Alphabet.index(of: c) else { return [] } - -// var carry = base58Index.encodedOffset - var carry = base58Index.utf16Offset(in: base58Alphabet) - var i = 0 - for j in 0 ... base58.count where carry != 0 || i < length { - carry += 58 * Int(base58[base58.count - j - 1]) - base58[base58.count - j - 1] = UInt8(carry % 256) - carry /= 256 - i += 1 - } - - assert(carry == 0) - length = i - } - - // skip leading zeros - var zerosToRemove = 0 - - for b in base58 { - if b != 0 { break } - zerosToRemove += 1 - } - base58.removeFirst(zerosToRemove) - - var result: [UInt8] = Array(repeating: 0, count: zerosCount) - for b in base58 { - result.append(b) - } - return result - } -} - -extension Array where Element == UInt8 { - public var base58EncodedString: String { - guard !isEmpty else { return "" } - return Base58.base58FromBytes(self) - } - - public var base58CheckEncodedString: String { - var bytes = self - let checksum = [UInt8](bytes.sha256().sha256()[0 ..< 4]) - - bytes.append(contentsOf: checksum) - - return Base58.base58FromBytes(bytes) - } -} - -extension String { - public var base58EncodedString: String { - return [UInt8](utf8).base58EncodedString - } - - public var base58DecodedData: Data? { - let bytes = Base58.bytesFromBase58(self) - return Data(bytes) - } - - public var base58CheckDecodedData: Data? { - guard let bytes = base58CheckDecodedBytes else { return nil } - return Data(bytes) - } - - public var base58CheckDecodedBytes: [UInt8]? { - var bytes = Base58.bytesFromBase58(self) - guard 4 <= bytes.count else { return nil } - - let checksum = [UInt8](bytes[bytes.count - 4 ..< bytes.count]) - bytes = [UInt8](bytes[0 ..< bytes.count - 4]) - - let calculatedChecksum = [UInt8](bytes.sha256().sha256()[0 ... 3]) - if checksum != calculatedChecksum { return nil } - - return bytes - } - -// public var littleEndianHexToUInt: UInt { -// let data = Data.fromHex(self)! -// let revensed = -// return UInt(sel) -// return UInt(self.dataWithHexString().bytes.reversed().fullHexString,radix: 16)! -// } -} diff --git a/Sources/TorusUtils/Convenience/BigUInt+Extensions.swift b/Sources/TorusUtils/Convenience/BigUInt+Extensions.swift deleted file mode 100755 index 2cd2896e..00000000 --- a/Sources/TorusUtils/Convenience/BigUInt+Extensions.swift +++ /dev/null @@ -1,16 +0,0 @@ -//// -//// RIPEMD160_SO.swift -//// web3swift -//// -//// Created by Alexander Vlasov on 10.01.2018. -//// -// -// import Foundation -// import struct BigInt.BigUInt -// -// public extension BigUInt { -// init?(_ naturalUnits: String, _ ethereumUnits: Web3.Utils.Units) { -// guard let value = Web3.Utils.parseToBigUInt(naturalUnits, units: ethereumUnits) else {return nil} -// self = value -// } -// } diff --git a/Sources/TorusUtils/Convenience/CryptoExtensions.swift b/Sources/TorusUtils/Convenience/CryptoExtensions.swift deleted file mode 100755 index 5f25a073..00000000 --- a/Sources/TorusUtils/Convenience/CryptoExtensions.swift +++ /dev/null @@ -1,20 +0,0 @@ -// web3swift -// -// Created by Alex Vlasov. -// Copyright © 2018 Alex Vlasov. All rights reserved. -// -// -// import Foundation -// import CryptoSwift -// -// func toByteArray(_ value: T) -> [UInt8] { -// var value = value -// return withUnsafeBytes(of: &value) { Array($0) } -// } -// -// func scrypt (password: String, salt: Data, length: Int, N: Int, R: Int, P: Int) -> Data? { -// guard let passwordData = password.data(using: .utf8) else {return nil} -// guard let deriver = try? Scrypt(password: passwordData.bytes, salt: salt.bytes, dkLen: length, N: N, r: R, p: P) else {return nil} -// guard let result = try? deriver.calculate() else {return nil} -// return Data(result) -// } diff --git a/Sources/TorusUtils/Convenience/Data+Extension.swift b/Sources/TorusUtils/Convenience/Data+Extension.swift deleted file mode 100755 index d0c9206a..00000000 --- a/Sources/TorusUtils/Convenience/Data+Extension.swift +++ /dev/null @@ -1,154 +0,0 @@ -// web3swift -// -// Created by Alex Vlasov. -// Copyright © 2018 Alex Vlasov. All rights reserved. -// - -import Foundation - -public extension Data { - static func fromArray(values: [T]) -> Data { - return values.withUnsafeBufferPointer { - return Data(buffer: $0) - } - } - - func toArray(type: T.Type) throws -> [T] { - return try withUnsafeBytes { (body: UnsafeRawBufferPointer) in - if let bodyAddress = body.baseAddress, body.count > 0 { - let pointer = bodyAddress.assumingMemoryBound(to: T.self) - return [T](UnsafeBufferPointer(start: pointer, count: self.count / MemoryLayout.stride)) - } else { - throw Web3Error.dataError - } - } - } - - // func toArray(type: T.Type) throws -> [T] { - // return try self.withUnsafeBytes { (body: UnsafeRawBufferPointer) in - // if let bodyAddress = body.baseAddress, body.count > 0 { - // let pointer = bodyAddress.assumingMemoryBound(to: T.self) - // return [T](UnsafeBufferPointer(start: pointer, count: self.count/MemoryLayout.stride)) - // } else { - // throw Web3Error.dataError - // } - // } - // } - - func constantTimeComparisonTo(_ other: Data?) -> Bool { - guard let rhs = other else { return false } - guard count == rhs.count else { return false } - var difference = UInt8(0x00) - for i in 0 ..< count { // compare full length - difference |= self[i] ^ rhs[i] // constant time - } - return difference == UInt8(0x00) - } - - static func zero(_ data: inout Data) { - let count = data.count - data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in - body.baseAddress?.assumingMemoryBound(to: UInt8.self).initialize(repeating: 0, count: count) - } - } - - // static func zero(_ data: inout Data) { - // let count = data.count - // data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in - // body.baseAddress?.assumingMemoryBound(to: UInt8.self).initialize(repeating: 0, count: count) - // } - // } - - static func randomBytes(length: Int) -> Data? { - for _ in 0 ... 1024 { - var data = Data(repeating: 0, count: length) - let result = data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) -> Int32? in - if let bodyAddress = body.baseAddress, body.count > 0 { - let pointer = bodyAddress.assumingMemoryBound(to: UInt8.self) - return SecRandomCopyBytes(kSecRandomDefault, 32, pointer) - } else { - return nil - } - } - if let notNilResult = result, notNilResult == errSecSuccess { - return data - } - } - return nil - } - - // static func randomBytes(length: Int) -> Data? { - // for _ in 0...1024 { - // var data = Data(repeating: 0, count: length) - // let result = data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) -> Int32? in - // if let bodyAddress = body.baseAddress, body.count > 0 { - // let pointer = bodyAddress.assumingMemoryBound(to: UInt8.self) - // return SecRandomCopyBytes(kSecRandomDefault, 32, pointer) - // } else { - // return nil - // } - // } - // if let notNilResult = result, notNilResult == errSecSuccess { - // return data - // } - // } - // return nil - // } - - static func fromHex(_ hex: String) -> Data? { - let string = hex.lowercased().stripHexPrefix() - let array = [UInt8](hex: string) - if array.count == 0 { - if hex == "0x" || hex == "" { - return Data() - } else { - return nil - } - } - return Data(array) - } - - func bitsInRange(_ startingBit: Int, _ length: Int) -> UInt64? { // return max of 8 bytes for simplicity, non-public - if startingBit + length / 8 > count, length > 64, startingBit > 0, length >= 1 { return nil } - let bytes = self[(startingBit / 8) ..< (startingBit + length + 7) / 8] - let padding = Data(repeating: 0, count: 8 - bytes.count) - let padded = bytes + padding - guard padded.count == 8 else { return nil } - let pointee = padded.withUnsafeBytes { (body: UnsafeRawBufferPointer) in - body.baseAddress?.assumingMemoryBound(to: UInt64.self).pointee - } - guard let ptee = pointee else { return nil } - var uintRepresentation = UInt64(bigEndian: ptee) - uintRepresentation = uintRepresentation << (startingBit % 8) - uintRepresentation = uintRepresentation >> UInt64(64 - length) - return uintRepresentation - } - - static func randomOfLength(_ length: Int) -> Data? { - var data = [UInt8](repeating: 0, count: length) - let result = SecRandomCopyBytes(kSecRandomDefault, - data.count, - &data) - if result == errSecSuccess { - return Data(data) - } - - return nil - } - - // func bitsInRange(_ startingBit:Int, _ length:Int) -> UInt64? { //return max of 8 bytes for simplicity, non-public - // if startingBit + length / 8 > self.count, length > 64, startingBit > 0, length >= 1 {return nil} - // let bytes = self[(startingBit/8) ..< (startingBit+length+7)/8] - // let padding = Data(repeating: 0, count: 8 - bytes.count) - // let padded = bytes + padding - // guard padded.count == 8 else {return nil} - // let pointee = padded.withUnsafeBytes { (body: UnsafeRawBufferPointer) in - // body.baseAddress?.assumingMemoryBound(to: UInt64.self).pointee - // } - // guard let ptee = pointee else {return nil} - // var uintRepresentation = UInt64(bigEndian: ptee) - // uintRepresentation = uintRepresentation << (startingBit % 8) - // uintRepresentation = uintRepresentation >> UInt64(64 - length) - // return uintRepresentation - // } -} diff --git a/Sources/TorusUtils/Convenience/Decodable+Extensions.swift b/Sources/TorusUtils/Convenience/Decodable+Extensions.swift deleted file mode 100644 index 74eb4423..00000000 --- a/Sources/TorusUtils/Convenience/Decodable+Extensions.swift +++ /dev/null @@ -1,146 +0,0 @@ -// -// DecodingContainer+AnyCollection.swift -// AnyDecodable -// -// Created by levantAJ on 1/18/19. -// Copyright © 2019 levantAJ. All rights reserved. -// -import Foundation - -struct AnyCodingKey: CodingKey { - var stringValue: String - var intValue: Int? - - init?(stringValue: String) { - self.stringValue = stringValue - } - - init?(intValue: Int) { - self.intValue = intValue - stringValue = String(intValue) - } -} - -extension KeyedDecodingContainer { - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - /// - throws: `DecodingError.typeMismatch` if the encountered encoded value - /// is not convertible to the requested type. - /// - throws: `DecodingError.keyNotFound` if `self` does not have an entry - /// for the given key. - /// - throws: `DecodingError.valueNotFound` if `self` has a null entry for - /// the given key. - public func decode(_ type: [Any].Type, forKey key: KeyedDecodingContainer.Key) throws -> [Any] { - var values = try nestedUnkeyedContainer(forKey: key) - return try values.decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - /// - throws: `DecodingError.typeMismatch` if the encountered encoded value - /// is not convertible to the requested type. - /// - throws: `DecodingError.keyNotFound` if `self` does not have an entry - /// for the given key. - /// - throws: `DecodingError.valueNotFound` if `self` has a null entry for - /// the given key. - public func decode(_ type: [String: Any].Type, forKey key: KeyedDecodingContainer.Key) throws -> [String: Any] { - let values = try nestedContainer(keyedBy: AnyCodingKey.self, forKey: key) - return try values.decode(type) - } - - /// Decodes a value of the given type for the given key, if present. - /// - /// This method returns `nil` if the container does not have a value - /// associated with `key`, or if the value is null. The difference between - /// these states can be distinguished with a `contains(_:)` call. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A decoded value of the requested type, or `nil` if the - /// `Decoder` does not have an entry associated with the given key, or if - /// the value is a null value. - /// - throws: `DecodingError.typeMismatch` if the encountered encoded value - /// is not convertible to the requested type. - public func decodeIfPresent(_ type: [Any].Type, forKey key: KeyedDecodingContainer.Key) throws -> [Any]? { - guard contains(key), - try decodeNil(forKey: key) == false else { return nil } - return try decode(type, forKey: key) - } - - /// Decodes a value of the given type for the given key, if present. - /// - /// This method returns `nil` if the container does not have a value - /// associated with `key`, or if the value is null. The difference between - /// these states can be distinguished with a `contains(_:)` call. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A decoded value of the requested type, or `nil` if the - /// `Decoder` does not have an entry associated with the given key, or if - /// the value is a null value. - /// - throws: `DecodingError.typeMismatch` if the encountered encoded value - /// is not convertible to the requested type. - public func decodeIfPresent(_ type: [String: Any].Type, forKey key: KeyedDecodingContainer.Key) throws -> [String: Any]? { - guard contains(key), - try decodeNil(forKey: key) == false else { return nil } - return try decode(type, forKey: key) - } -} - -private extension KeyedDecodingContainer { - func decode(_ type: [String: Any].Type) throws -> [String: Any] { - var dictionary: [String: Any] = [:] - for key in allKeys { - if try decodeNil(forKey: key) { - dictionary[key.stringValue] = NSNull() - } else if let bool = try? decode(Bool.self, forKey: key) { - dictionary[key.stringValue] = bool - } else if let string = try? decode(String.self, forKey: key) { - dictionary[key.stringValue] = string - } else if let int = try? decode(Int.self, forKey: key) { - dictionary[key.stringValue] = int - } else if let double = try? decode(Double.self, forKey: key) { - dictionary[key.stringValue] = double - } else if let dict = try? decode([String: Any].self, forKey: key) { - dictionary[key.stringValue] = dict - } else if let array = try? decode([Any].self, forKey: key) { - dictionary[key.stringValue] = array - } - } - return dictionary - } -} - -private extension UnkeyedDecodingContainer { - mutating func decode(_ type: [Any].Type) throws -> [Any] { - var elements: [Any] = [] - while !isAtEnd { - if try decodeNil() { - elements.append(NSNull()) - } else if let int = try? decode(Int.self) { - elements.append(int) - } else if let bool = try? decode(Bool.self) { - elements.append(bool) - } else if let double = try? decode(Double.self) { - elements.append(double) - } else if let string = try? decode(String.self) { - elements.append(string) - } else if let values = try? nestedContainer(keyedBy: AnyCodingKey.self), - let element = try? values.decode([String: Any].self) { - elements.append(element) - } else if var values = try? nestedUnkeyedContainer(), - let element = try? values.decode([Any].self) { - elements.append(element) - } - } - return elements - } -} diff --git a/Sources/TorusUtils/Convenience/Dictionary+Extension.swift b/Sources/TorusUtils/Convenience/Dictionary+Extension.swift deleted file mode 100755 index 964bbd28..00000000 --- a/Sources/TorusUtils/Convenience/Dictionary+Extension.swift +++ /dev/null @@ -1,18 +0,0 @@ -// web3swift -// -// Created by Alex Vlasov. -// Copyright © 2018 Alex Vlasov. All rights reserved. -// - -import Foundation - -extension Dictionary where Key == String, Value: Equatable { - func keyForValue(value: Value) -> String? { - for key in keys { - if self[key] == value { - return key - } - } - return nil - } -} diff --git a/Sources/TorusUtils/Convenience/Encodable+Extensions.swift b/Sources/TorusUtils/Convenience/Encodable+Extensions.swift deleted file mode 100644 index 7a8e8cbf..00000000 --- a/Sources/TorusUtils/Convenience/Encodable+Extensions.swift +++ /dev/null @@ -1,130 +0,0 @@ -// -// EncodingContainer+AnyCollection.swift -// AnyDecodable -// -// Created by ShopBack on 1/19/19. -// Copyright © 2019 levantAJ. All rights reserved. -// -import Foundation - -extension KeyedEncodingContainer { - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - /// - throws: `EncodingError.invalidValue` if the given value is invalid in - /// the current context for this format. - public mutating func encode(_ value: [String: Any], forKey key: KeyedEncodingContainer.Key) throws { - var container = nestedContainer(keyedBy: AnyCodingKey.self, forKey: key) - try container.encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - /// - throws: `EncodingError.invalidValue` if the given value is invalid in - /// the current context for this format. - public mutating func encode(_ value: [Any], forKey key: KeyedEncodingContainer.Key) throws { - var container = nestedUnkeyedContainer(forKey: key) - try container.encode(value) - } - - /// Encodes the given value for the given key if it is not `nil`. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - /// - throws: `EncodingError.invalidValue` if the given value is invalid in - /// the current context for this format. - public mutating func encodeIfPresent(_ value: [String: Any]?, forKey key: KeyedEncodingContainer.Key) throws { - if let value = value { - var container = nestedContainer(keyedBy: AnyCodingKey.self, forKey: key) - try container.encode(value) - } else { - try encodeNil(forKey: key) - } - } - - /// Encodes the given value for the given key if it is not `nil`. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - /// - throws: `EncodingError.invalidValue` if the given value is invalid in - /// the current context for this format. - public mutating func encodeIfPresent(_ value: [Any]?, forKey key: KeyedEncodingContainer.Key) throws { - if let value = value { - var container = nestedUnkeyedContainer(forKey: key) - try container.encode(value) - } else { - try encodeNil(forKey: key) - } - } -} - -private extension KeyedEncodingContainer where K == AnyCodingKey { - mutating func encode(_ value: [String: Any]) throws { - for (k, v) in value { - let key = AnyCodingKey(stringValue: k)! - switch v { - case is NSNull: - try encodeNil(forKey: key) - case let string as String: - try encode(string, forKey: key) - case let int as Int: - try encode(int, forKey: key) - case let bool as Bool: - try encode(bool, forKey: key) - case let double as Double: - try encode(double, forKey: key) - case let dict as [String: Any]: - try encode(dict, forKey: key) - case let array as [Any]: - try encode(array, forKey: key) - default: - debugPrint("⚠️ Unsuported type!", v) - continue - } - } - } -} - -private extension UnkeyedEncodingContainer { - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - /// - throws: `EncodingError.invalidValue` if the given value is invalid in - /// the current context for this format. - mutating func encode(_ value: [Any]) throws { - for v in value { - switch v { - case is NSNull: - try encodeNil() - case let string as String: - try encode(string) - case let int as Int: - try encode(int) - case let bool as Bool: - try encode(bool) - case let double as Double: - try encode(double) - case let dict as [String: Any]: - try encode(dict) - case let array as [Any]: - var values = nestedUnkeyedContainer() - try values.encode(array) - default: - debugPrint("⚠️ Unsuported type!", v) - } - } - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - /// - throws: `EncodingError.invalidValue` if the given value is invalid in - /// the current context for this format. - mutating func encode(_ value: [String: Any]) throws { - var container = nestedContainer(keyedBy: AnyCodingKey.self) - try container.encode(value) - } -} diff --git a/Sources/TorusUtils/Convenience/NSRegularExpressionExtension.swift b/Sources/TorusUtils/Convenience/NSRegularExpressionExtension.swift deleted file mode 100755 index ff50f236..00000000 --- a/Sources/TorusUtils/Convenience/NSRegularExpressionExtension.swift +++ /dev/null @@ -1,80 +0,0 @@ -// web3swift -// -// Created by Alex Vlasov. -// Copyright © 2018 Alex Vlasov. All rights reserved. -// - -import Foundation - -extension NSRegularExpression { - typealias GroupNamesSearchResult = (NSTextCheckingResult, NSTextCheckingResult, Int) - - private func textCheckingResultsOfNamedCaptureGroups() -> [String: GroupNamesSearchResult] { - var groupnames = [String: GroupNamesSearchResult]() - - guard let greg = try? NSRegularExpression(pattern: "^\\(\\?<([\\w\\a_-]*)>$", options: NSRegularExpression.Options.dotMatchesLineSeparators) else { - // This never happens but the alternative is to make this method throwing - return groupnames - } - guard let reg = try? NSRegularExpression(pattern: "\\(.*?>", options: NSRegularExpression.Options.dotMatchesLineSeparators) else { - // This never happens but the alternative is to make this method throwing - return groupnames - } - let m = reg.matches(in: pattern, options: NSRegularExpression.MatchingOptions.withTransparentBounds, range: NSRange(location: 0, length: pattern.utf16.count)) - for (n, g) in m.enumerated() { - let r = pattern.range(from: g.range(at: 0)) - let gstring = String(pattern[r!]) - let gmatch = greg.matches(in: gstring, options: NSRegularExpression.MatchingOptions.anchored, range: NSRange(location: 0, length: gstring.utf16.count)) - if gmatch.count > 0 { - let r2 = gstring.range(from: gmatch[0].range(at: 1))! - groupnames[String(gstring[r2])] = (g, gmatch[0], n) - } - } - return groupnames - } - - func indexOfNamedCaptureGroups() throws -> [String: Int] { - var groupnames = [String: Int]() - for (name, (_, _, n)) in textCheckingResultsOfNamedCaptureGroups() { - groupnames[name] = n + 1 - } - return groupnames - } - - func rangesOfNamedCaptureGroups(match: NSTextCheckingResult) throws -> [String: Range] { - var ranges = [String: Range]() - for (name, (_, _, n)) in textCheckingResultsOfNamedCaptureGroups() { - ranges[name] = Range(match.range(at: n + 1)) - } - return ranges - } - - private func nameForIndex(_ index: Int, from: [String: GroupNamesSearchResult]) -> String? { - for (name, (_, _, n)) in from { - if (n + 1) == index { - return name - } - } - return nil - } - - func captureGroups(string: String, options: NSRegularExpression.MatchingOptions = []) -> [String: String] { - return captureGroups(string: string, options: options, range: NSRange(location: 0, length: string.utf16.count)) - } - - func captureGroups(string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> [String: String] { - var dict = [String: String]() - let matchResult = matches(in: string, options: options, range: range) - let names = textCheckingResultsOfNamedCaptureGroups() - for (_, m) in matchResult.enumerated() { - for i in 0 ..< m.numberOfRanges { - guard let r2 = string.range(from: m.range(at: i)) else { continue } - let g = String(string[r2]) - if let name = nameForIndex(i, from: names) { - dict[name] = g - } - } - } - return dict - } -} diff --git a/Sources/TorusUtils/Convenience/NativeTypesEncoding+Extensions.swift b/Sources/TorusUtils/Convenience/NativeTypesEncoding+Extensions.swift deleted file mode 100755 index 43962c98..00000000 --- a/Sources/TorusUtils/Convenience/NativeTypesEncoding+Extensions.swift +++ /dev/null @@ -1,91 +0,0 @@ -// web3swift -// -// Created by Alex Vlasov. -// Copyright © 2018 Alex Vlasov. All rights reserved. -// - -import BigInt -import Foundation - -extension Data { - func setLengthLeft(_ toBytes: UInt64, isNegative: Bool = false) -> Data? { - let existingLength = UInt64(count) - if existingLength == toBytes { - return Data(self) - } else if existingLength > toBytes { - return nil - } - var data: Data - if isNegative { - data = Data(repeating: UInt8(255), count: Int(toBytes - existingLength)) - } else { - data = Data(repeating: UInt8(0), count: Int(toBytes - existingLength)) - } - data.append(self) - return data - } - - func setLengthRight(_ toBytes: UInt64, isNegative: Bool = false) -> Data? { - let existingLength = UInt64(count) - if existingLength == toBytes { - return Data(self) - } else if existingLength > toBytes { - return nil - } - var data: Data = Data() - data.append(self) - if isNegative { - data.append(Data(repeating: UInt8(255), count: Int(toBytes - existingLength))) - } else { - data.append(Data(repeating: UInt8(0), count: Int(toBytes - existingLength))) - } - return data - } -} - -extension BigInt { - func toTwosComplement() -> Data { - if sign == BigInt.Sign.plus { - return magnitude.serialize() - } else { - let serializedLength = magnitude.serialize().count - let MAX = BigUInt(1) << (serializedLength * 8) - let twoComplement = MAX - magnitude - return twoComplement.serialize() - } - } -} - -extension BigUInt { - func abiEncode(bits: UInt64) -> Data? { - let data = serialize() - let paddedLength = UInt64(ceil(Double(bits) / 8.0)) - let padded = data.setLengthLeft(paddedLength) - return padded - } -} - -extension BigInt { - func abiEncode(bits: UInt64) -> Data? { - let isNegative = self < BigInt(0) - let data = toTwosComplement() - let paddedLength = UInt64(ceil(Double(bits) / 8.0)) - let padded = data.setLengthLeft(paddedLength, isNegative: isNegative) - return padded - } -} - -extension BigInt { - static func fromTwosComplement(data: Data) -> BigInt { - let isPositive = ((data[0] & 128) >> 7) == 0 - if isPositive { - let magnitude = BigUInt(data) - return BigInt(magnitude) - } else { - let MAX = (BigUInt(1) << (data.count * 8)) - let magnitude = MAX - BigUInt(data) - let bigint = BigInt(0) - BigInt(magnitude) - return bigint - } - } -} diff --git a/Sources/TorusUtils/Convenience/RIPEMD160+StackOveflow.swift b/Sources/TorusUtils/Convenience/RIPEMD160+StackOveflow.swift deleted file mode 100755 index 1fe02d44..00000000 --- a/Sources/TorusUtils/Convenience/RIPEMD160+StackOveflow.swift +++ /dev/null @@ -1,534 +0,0 @@ -//// -//// RIPEMD160_SO.swift -//// web3swift -//// -//// Created by Alexander Vlasov on 10.01.2018. -//// -// -//// From https://stackoverflow.com/questions/43091858/swift-hash-a-string-using-hash-hmac-with-ripemd160/43191938 -// -// import Foundation -// -// public struct RIPEMD160 { -// -// private var MDbuf: (UInt32, UInt32, UInt32, UInt32, UInt32) -// private var buffer: Data -// private var count: Int64 // Total # of bytes processed. -// -// public init() { -// MDbuf = (0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0) -// buffer = Data() -// count = 0 -// } -// -// private mutating func compress(_ X: UnsafePointer) { -// -// // *** Helper functions (originally macros in rmd160.h) *** -// -// /* ROL(x, n) cyclically rotates x over n bits to the left */ -// /* x must be of an unsigned 32 bits type and 0 <= n < 32. */ -// func ROL(_ x: UInt32, _ n: UInt32) -> UInt32 { -// return (x << n) | ( x >> (32 - n)) -// } -// -// /* the five basic functions F(), G() and H() */ -// -// func F(_ x: UInt32, _ y: UInt32, _ z: UInt32) -> UInt32 { -// return x ^ y ^ z -// } -// -// func G(_ x: UInt32, _ y: UInt32, _ z: UInt32) -> UInt32 { -// return (x & y) | (~x & z) -// } -// -// func H(_ x: UInt32, _ y: UInt32, _ z: UInt32) -> UInt32 { -// return (x | ~y) ^ z -// } -// -// func I(_ x: UInt32, _ y: UInt32, _ z: UInt32) -> UInt32 { -// return (x & z) | (y & ~z) -// } -// -// func J(_ x: UInt32, _ y: UInt32, _ z: UInt32) -> UInt32 { -// return x ^ (y | ~z) -// } -// -// /* the ten basic operations FF() through III() */ -// -// func FF(_ a: inout UInt32, _ b: UInt32, _ c: inout UInt32, _ d: UInt32, _ e: UInt32, _ x: UInt32, _ s: UInt32) { -// a = a &+ F(b, c, d) &+ x -// a = ROL(a, s) &+ e -// c = ROL(c, 10) -// } -// -// func GG(_ a: inout UInt32, _ b: UInt32, _ c: inout UInt32, _ d: UInt32, _ e: UInt32, _ x: UInt32, _ s: UInt32) { -// a = a &+ G(b, c, d) &+ x &+ 0x5a827999 -// a = ROL(a, s) &+ e -// c = ROL(c, 10) -// } -// -// func HH(_ a: inout UInt32, _ b: UInt32, _ c: inout UInt32, _ d: UInt32, _ e: UInt32, _ x: UInt32, _ s: UInt32) { -// a = a &+ H(b, c, d) &+ x &+ 0x6ed9eba1 -// a = ROL(a, s) &+ e -// c = ROL(c, 10) -// } -// -// func II(_ a: inout UInt32, _ b: UInt32, _ c: inout UInt32, _ d: UInt32, _ e: UInt32, _ x: UInt32, _ s: UInt32) { -// a = a &+ I(b, c, d) &+ x &+ 0x8f1bbcdc -// a = ROL(a, s) &+ e -// c = ROL(c, 10) -// } -// -// func JJ(_ a: inout UInt32, _ b: UInt32, _ c: inout UInt32, _ d: UInt32, _ e: UInt32, _ x: UInt32, _ s: UInt32) { -// a = a &+ J(b, c, d) &+ x &+ 0xa953fd4e -// a = ROL(a, s) &+ e -// c = ROL(c, 10) -// } -// -// func FFF(_ a: inout UInt32, _ b: UInt32, _ c: inout UInt32, _ d: UInt32, _ e: UInt32, _ x: UInt32, _ s: UInt32) { -// a = a &+ F(b, c, d) &+ x -// a = ROL(a, s) &+ e -// c = ROL(c, 10) -// } -// -// func GGG(_ a: inout UInt32, _ b: UInt32, _ c: inout UInt32, _ d: UInt32, _ e: UInt32, _ x: UInt32, _ s: UInt32) { -// a = a &+ G(b, c, d) &+ x &+ 0x7a6d76e9 -// a = ROL(a, s) &+ e -// c = ROL(c, 10) -// } -// -// func HHH(_ a: inout UInt32, _ b: UInt32, _ c: inout UInt32, _ d: UInt32, _ e: UInt32, _ x: UInt32, _ s: UInt32) { -// a = a &+ H(b, c, d) &+ x &+ 0x6d703ef3 -// a = ROL(a, s) &+ e -// c = ROL(c, 10) -// } -// -// func III(_ a: inout UInt32, _ b: UInt32, _ c: inout UInt32, _ d: UInt32, _ e: UInt32, _ x: UInt32, _ s: UInt32) { -// a = a &+ I(b, c, d) &+ x &+ 0x5c4dd124 -// a = ROL(a, s) &+ e -// c = ROL(c, 10) -// } -// -// func JJJ(_ a: inout UInt32, _ b: UInt32, _ c: inout UInt32, _ d: UInt32, _ e: UInt32, _ x: UInt32, _ s: UInt32) { -// a = a &+ J(b, c, d) &+ x &+ 0x50a28be6 -// a = ROL(a, s) &+ e -// c = ROL(c, 10) -// } -// -// // *** The function starts here *** -// -// var (aa, bb, cc, dd, ee) = MDbuf -// var (aaa, bbb, ccc, ddd, eee) = MDbuf -// -// /* round 1 */ -// FF(&aa, bb, &cc, dd, ee, X[ 0], 11) -// FF(&ee, aa, &bb, cc, dd, X[ 1], 14) -// FF(&dd, ee, &aa, bb, cc, X[ 2], 15) -// FF(&cc, dd, &ee, aa, bb, X[ 3], 12) -// FF(&bb, cc, &dd, ee, aa, X[ 4], 5) -// FF(&aa, bb, &cc, dd, ee, X[ 5], 8) -// FF(&ee, aa, &bb, cc, dd, X[ 6], 7) -// FF(&dd, ee, &aa, bb, cc, X[ 7], 9) -// FF(&cc, dd, &ee, aa, bb, X[ 8], 11) -// FF(&bb, cc, &dd, ee, aa, X[ 9], 13) -// FF(&aa, bb, &cc, dd, ee, X[10], 14) -// FF(&ee, aa, &bb, cc, dd, X[11], 15) -// FF(&dd, ee, &aa, bb, cc, X[12], 6) -// FF(&cc, dd, &ee, aa, bb, X[13], 7) -// FF(&bb, cc, &dd, ee, aa, X[14], 9) -// FF(&aa, bb, &cc, dd, ee, X[15], 8) -// -// /* round 2 */ -// GG(&ee, aa, &bb, cc, dd, X[ 7], 7) -// GG(&dd, ee, &aa, bb, cc, X[ 4], 6) -// GG(&cc, dd, &ee, aa, bb, X[13], 8) -// GG(&bb, cc, &dd, ee, aa, X[ 1], 13) -// GG(&aa, bb, &cc, dd, ee, X[10], 11) -// GG(&ee, aa, &bb, cc, dd, X[ 6], 9) -// GG(&dd, ee, &aa, bb, cc, X[15], 7) -// GG(&cc, dd, &ee, aa, bb, X[ 3], 15) -// GG(&bb, cc, &dd, ee, aa, X[12], 7) -// GG(&aa, bb, &cc, dd, ee, X[ 0], 12) -// GG(&ee, aa, &bb, cc, dd, X[ 9], 15) -// GG(&dd, ee, &aa, bb, cc, X[ 5], 9) -// GG(&cc, dd, &ee, aa, bb, X[ 2], 11) -// GG(&bb, cc, &dd, ee, aa, X[14], 7) -// GG(&aa, bb, &cc, dd, ee, X[11], 13) -// GG(&ee, aa, &bb, cc, dd, X[ 8], 12) -// -// /* round 3 */ -// HH(&dd, ee, &aa, bb, cc, X[ 3], 11) -// HH(&cc, dd, &ee, aa, bb, X[10], 13) -// HH(&bb, cc, &dd, ee, aa, X[14], 6) -// HH(&aa, bb, &cc, dd, ee, X[ 4], 7) -// HH(&ee, aa, &bb, cc, dd, X[ 9], 14) -// HH(&dd, ee, &aa, bb, cc, X[15], 9) -// HH(&cc, dd, &ee, aa, bb, X[ 8], 13) -// HH(&bb, cc, &dd, ee, aa, X[ 1], 15) -// HH(&aa, bb, &cc, dd, ee, X[ 2], 14) -// HH(&ee, aa, &bb, cc, dd, X[ 7], 8) -// HH(&dd, ee, &aa, bb, cc, X[ 0], 13) -// HH(&cc, dd, &ee, aa, bb, X[ 6], 6) -// HH(&bb, cc, &dd, ee, aa, X[13], 5) -// HH(&aa, bb, &cc, dd, ee, X[11], 12) -// HH(&ee, aa, &bb, cc, dd, X[ 5], 7) -// HH(&dd, ee, &aa, bb, cc, X[12], 5) -// -// /* round 4 */ -// II(&cc, dd, &ee, aa, bb, X[ 1], 11) -// II(&bb, cc, &dd, ee, aa, X[ 9], 12) -// II(&aa, bb, &cc, dd, ee, X[11], 14) -// II(&ee, aa, &bb, cc, dd, X[10], 15) -// II(&dd, ee, &aa, bb, cc, X[ 0], 14) -// II(&cc, dd, &ee, aa, bb, X[ 8], 15) -// II(&bb, cc, &dd, ee, aa, X[12], 9) -// II(&aa, bb, &cc, dd, ee, X[ 4], 8) -// II(&ee, aa, &bb, cc, dd, X[13], 9) -// II(&dd, ee, &aa, bb, cc, X[ 3], 14) -// II(&cc, dd, &ee, aa, bb, X[ 7], 5) -// II(&bb, cc, &dd, ee, aa, X[15], 6) -// II(&aa, bb, &cc, dd, ee, X[14], 8) -// II(&ee, aa, &bb, cc, dd, X[ 5], 6) -// II(&dd, ee, &aa, bb, cc, X[ 6], 5) -// II(&cc, dd, &ee, aa, bb, X[ 2], 12) -// -// /* round 5 */ -// JJ(&bb, cc, &dd, ee, aa, X[ 4], 9) -// JJ(&aa, bb, &cc, dd, ee, X[ 0], 15) -// JJ(&ee, aa, &bb, cc, dd, X[ 5], 5) -// JJ(&dd, ee, &aa, bb, cc, X[ 9], 11) -// JJ(&cc, dd, &ee, aa, bb, X[ 7], 6) -// JJ(&bb, cc, &dd, ee, aa, X[12], 8) -// JJ(&aa, bb, &cc, dd, ee, X[ 2], 13) -// JJ(&ee, aa, &bb, cc, dd, X[10], 12) -// JJ(&dd, ee, &aa, bb, cc, X[14], 5) -// JJ(&cc, dd, &ee, aa, bb, X[ 1], 12) -// JJ(&bb, cc, &dd, ee, aa, X[ 3], 13) -// JJ(&aa, bb, &cc, dd, ee, X[ 8], 14) -// JJ(&ee, aa, &bb, cc, dd, X[11], 11) -// JJ(&dd, ee, &aa, bb, cc, X[ 6], 8) -// JJ(&cc, dd, &ee, aa, bb, X[15], 5) -// JJ(&bb, cc, &dd, ee, aa, X[13], 6) -// -// /* parallel round 1 */ -// JJJ(&aaa, bbb, &ccc, ddd, eee, X[ 5], 8) -// JJJ(&eee, aaa, &bbb, ccc, ddd, X[14], 9) -// JJJ(&ddd, eee, &aaa, bbb, ccc, X[ 7], 9) -// JJJ(&ccc, ddd, &eee, aaa, bbb, X[ 0], 11) -// JJJ(&bbb, ccc, &ddd, eee, aaa, X[ 9], 13) -// JJJ(&aaa, bbb, &ccc, ddd, eee, X[ 2], 15) -// JJJ(&eee, aaa, &bbb, ccc, ddd, X[11], 15) -// JJJ(&ddd, eee, &aaa, bbb, ccc, X[ 4], 5) -// JJJ(&ccc, ddd, &eee, aaa, bbb, X[13], 7) -// JJJ(&bbb, ccc, &ddd, eee, aaa, X[ 6], 7) -// JJJ(&aaa, bbb, &ccc, ddd, eee, X[15], 8) -// JJJ(&eee, aaa, &bbb, ccc, ddd, X[ 8], 11) -// JJJ(&ddd, eee, &aaa, bbb, ccc, X[ 1], 14) -// JJJ(&ccc, ddd, &eee, aaa, bbb, X[10], 14) -// JJJ(&bbb, ccc, &ddd, eee, aaa, X[ 3], 12) -// JJJ(&aaa, bbb, &ccc, ddd, eee, X[12], 6) -// -// /* parallel round 2 */ -// III(&eee, aaa, &bbb, ccc, ddd, X[ 6], 9) -// III(&ddd, eee, &aaa, bbb, ccc, X[11], 13) -// III(&ccc, ddd, &eee, aaa, bbb, X[ 3], 15) -// III(&bbb, ccc, &ddd, eee, aaa, X[ 7], 7) -// III(&aaa, bbb, &ccc, ddd, eee, X[ 0], 12) -// III(&eee, aaa, &bbb, ccc, ddd, X[13], 8) -// III(&ddd, eee, &aaa, bbb, ccc, X[ 5], 9) -// III(&ccc, ddd, &eee, aaa, bbb, X[10], 11) -// III(&bbb, ccc, &ddd, eee, aaa, X[14], 7) -// III(&aaa, bbb, &ccc, ddd, eee, X[15], 7) -// III(&eee, aaa, &bbb, ccc, ddd, X[ 8], 12) -// III(&ddd, eee, &aaa, bbb, ccc, X[12], 7) -// III(&ccc, ddd, &eee, aaa, bbb, X[ 4], 6) -// III(&bbb, ccc, &ddd, eee, aaa, X[ 9], 15) -// III(&aaa, bbb, &ccc, ddd, eee, X[ 1], 13) -// III(&eee, aaa, &bbb, ccc, ddd, X[ 2], 11) -// -// /* parallel round 3 */ -// HHH(&ddd, eee, &aaa, bbb, ccc, X[15], 9) -// HHH(&ccc, ddd, &eee, aaa, bbb, X[ 5], 7) -// HHH(&bbb, ccc, &ddd, eee, aaa, X[ 1], 15) -// HHH(&aaa, bbb, &ccc, ddd, eee, X[ 3], 11) -// HHH(&eee, aaa, &bbb, ccc, ddd, X[ 7], 8) -// HHH(&ddd, eee, &aaa, bbb, ccc, X[14], 6) -// HHH(&ccc, ddd, &eee, aaa, bbb, X[ 6], 6) -// HHH(&bbb, ccc, &ddd, eee, aaa, X[ 9], 14) -// HHH(&aaa, bbb, &ccc, ddd, eee, X[11], 12) -// HHH(&eee, aaa, &bbb, ccc, ddd, X[ 8], 13) -// HHH(&ddd, eee, &aaa, bbb, ccc, X[12], 5) -// HHH(&ccc, ddd, &eee, aaa, bbb, X[ 2], 14) -// HHH(&bbb, ccc, &ddd, eee, aaa, X[10], 13) -// HHH(&aaa, bbb, &ccc, ddd, eee, X[ 0], 13) -// HHH(&eee, aaa, &bbb, ccc, ddd, X[ 4], 7) -// HHH(&ddd, eee, &aaa, bbb, ccc, X[13], 5) -// -// /* parallel round 4 */ -// GGG(&ccc, ddd, &eee, aaa, bbb, X[ 8], 15) -// GGG(&bbb, ccc, &ddd, eee, aaa, X[ 6], 5) -// GGG(&aaa, bbb, &ccc, ddd, eee, X[ 4], 8) -// GGG(&eee, aaa, &bbb, ccc, ddd, X[ 1], 11) -// GGG(&ddd, eee, &aaa, bbb, ccc, X[ 3], 14) -// GGG(&ccc, ddd, &eee, aaa, bbb, X[11], 14) -// GGG(&bbb, ccc, &ddd, eee, aaa, X[15], 6) -// GGG(&aaa, bbb, &ccc, ddd, eee, X[ 0], 14) -// GGG(&eee, aaa, &bbb, ccc, ddd, X[ 5], 6) -// GGG(&ddd, eee, &aaa, bbb, ccc, X[12], 9) -// GGG(&ccc, ddd, &eee, aaa, bbb, X[ 2], 12) -// GGG(&bbb, ccc, &ddd, eee, aaa, X[13], 9) -// GGG(&aaa, bbb, &ccc, ddd, eee, X[ 9], 12) -// GGG(&eee, aaa, &bbb, ccc, ddd, X[ 7], 5) -// GGG(&ddd, eee, &aaa, bbb, ccc, X[10], 15) -// GGG(&ccc, ddd, &eee, aaa, bbb, X[14], 8) -// -// /* parallel round 5 */ -// FFF(&bbb, ccc, &ddd, eee, aaa, X[12] , 8) -// FFF(&aaa, bbb, &ccc, ddd, eee, X[15] , 5) -// FFF(&eee, aaa, &bbb, ccc, ddd, X[10] , 12) -// FFF(&ddd, eee, &aaa, bbb, ccc, X[ 4] , 9) -// FFF(&ccc, ddd, &eee, aaa, bbb, X[ 1] , 12) -// FFF(&bbb, ccc, &ddd, eee, aaa, X[ 5] , 5) -// FFF(&aaa, bbb, &ccc, ddd, eee, X[ 8] , 14) -// FFF(&eee, aaa, &bbb, ccc, ddd, X[ 7] , 6) -// FFF(&ddd, eee, &aaa, bbb, ccc, X[ 6] , 8) -// FFF(&ccc, ddd, &eee, aaa, bbb, X[ 2] , 13) -// FFF(&bbb, ccc, &ddd, eee, aaa, X[13] , 6) -// FFF(&aaa, bbb, &ccc, ddd, eee, X[14] , 5) -// FFF(&eee, aaa, &bbb, ccc, ddd, X[ 0] , 15) -// FFF(&ddd, eee, &aaa, bbb, ccc, X[ 3] , 13) -// FFF(&ccc, ddd, &eee, aaa, bbb, X[ 9] , 11) -// FFF(&bbb, ccc, &ddd, eee, aaa, X[11] , 11) -// -// /* combine results */ -// MDbuf = (MDbuf.1 &+ cc &+ ddd, -// MDbuf.2 &+ dd &+ eee, -// MDbuf.3 &+ ee &+ aaa, -// MDbuf.4 &+ aa &+ bbb, -// MDbuf.0 &+ bb &+ ccc) -// } -// -// public mutating func update(data: Data) throws { -// try data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in -// if let bodyAddress = body.baseAddress, body.count > 0 { -// var ptr = bodyAddress.assumingMemoryBound(to: UInt8.self) -// var length = data.count -// var X = [UInt32](repeating: 0, count: 16) -// -// // Process remaining bytes from last call: -// if buffer.count > 0 && buffer.count + length >= 64 { -// let amount = 64 - buffer.count -// buffer.append(ptr, count: amount) -// try buffer.withUnsafeBytes { (body: UnsafeRawBufferPointer) in -// if let bodyAddress = body.baseAddress, body.count > 0 { -// let pointer = bodyAddress.assumingMemoryBound(to: Void.self) -// _ = memcpy(&X, pointer, 64) -// } else { -// throw Web3Error.dataError -// } -// } -// compress(X) -// ptr += amount -// length -= amount -// } -// // Process 64 byte chunks: -// while length >= 64 { -// memcpy(&X, ptr, 64) -// compress(X) -// ptr += 64 -// length -= 64 -// } -// // Save remaining unprocessed bytes: -// buffer = Data(bytes: ptr, count: length) -// } else { -// throw Web3Error.dataError -// } -// } -// count += Int64(data.count) -// } -// -// public mutating func finalize() throws -> Data { -// var X = [UInt32](repeating: 0, count: 16) -// /* append the bit m_n == 1 */ -// buffer.append(0x80) -// try buffer.withUnsafeBytes { (body: UnsafeRawBufferPointer) in -// if let bodyAddress = body.baseAddress, body.count > 0 { -// let pointer = bodyAddress.assumingMemoryBound(to: Void.self) -// _ = memcpy(&X, pointer, buffer.count) -// } else { -// throw Web3Error.dataError -// } -// } -// -// if (count & 63) > 55 { -// /* length goes to next block */ -// compress(X) -// X = [UInt32](repeating: 0, count: 16) -// } -// -// /* append length in bits */ -// let lswlen = UInt32(truncatingIfNeeded: count) -// let mswlen = UInt32(UInt64(count) >> 32) -// X[14] = lswlen << 3 -// X[15] = (lswlen >> 29) | (mswlen << 3) -// compress(X) -// -// var data = Data(count: 20) -// try data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in -// if let bodyAddress = body.baseAddress, body.count > 0 { -// let pointer = bodyAddress.assumingMemoryBound(to: UInt32.self) -// pointer[0] = MDbuf.0 -// pointer[1] = MDbuf.1 -// pointer[2] = MDbuf.2 -// pointer[3] = MDbuf.3 -// pointer[4] = MDbuf.4 -// } else { -// throw Web3Error.dataError -// } -// } -// -// buffer = Data() -// -// return data -// } -// -// // public mutating func update(data: Data) throws { -// // try data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in -// // -// // if let bodyAddress = body.baseAddress, body.count > 0 { -// // var ptr = bodyAddress.assumingMemoryBound(to: UInt8.self) -// // var length = data.count -// // var X = [UInt32](repeating: 0, count: 16) -// // -// // // Process remaining bytes from last call: -// // if buffer.count > 0 && buffer.count + length >= 64 { -// // let amount = 64 - buffer.count -// // buffer.append(ptr, count: amount) -// // try buffer.withUnsafeBytes { (body: UnsafeRawBufferPointer) in -// // if let bodyAddress = body.baseAddress, body.count > 0 { -// // let pointer = bodyAddress.assumingMemoryBound(to: Void.self) -// // _ = memcpy(&X, pointer, 64) -// // } else { -// // throw Web3Error.dataError -// // } -// // } -// // compress(X) -// // ptr += amount -// // length -= amount -// // } -// // // Process 64 byte chunks: -// // while length >= 64 { -// // memcpy(&X, ptr, 64) -// // compress(X) -// // ptr += 64 -// // length -= 64 -// // } -// // // Save remaining unprocessed bytes: -// // buffer = Data(bytes: ptr, count: length) -// // } else { -// // throw Web3Error.dataError -// // } -// // -// // } -// // count += Int64(data.count) -// // } -// // -// // public mutating func finalize() throws -> Data { -// // var X = [UInt32](repeating: 0, count: 16) -// // /* append the bit m_n == 1 */ -// // buffer.append(0x80) -// // try buffer.withUnsafeBytes { (body: UnsafeRawBufferPointer) in -// // if let bodyAddress = body.baseAddress, body.count > 0 { -// // let pointer = bodyAddress.assumingMemoryBound(to: Void.self) -// // _ = memcpy(&X, pointer, buffer.count) -// // } else { -// // throw Web3Error.dataError -// // } -// // } -// // -// // if (count & 63) > 55 { -// // /* length goes to next block */ -// // compress(X) -// // X = [UInt32](repeating: 0, count: 16) -// // } -// // -// // /* append length in bits */ -// // let lswlen = UInt32(truncatingIfNeeded: count) -// // let mswlen = UInt32(UInt64(count) >> 32) -// // X[14] = lswlen << 3 -// // X[15] = (lswlen >> 29) | (mswlen << 3) -// // compress(X) -// // -// // var data = Data(count: 20) -// // try data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in -// // if let bodyAddress = body.baseAddress, body.count > 0 { -// // let pointer = bodyAddress.assumingMemoryBound(to: UInt32.self) -// // pointer[0] = MDbuf.0 -// // pointer[1] = MDbuf.1 -// // pointer[2] = MDbuf.2 -// // pointer[3] = MDbuf.3 -// // pointer[4] = MDbuf.4 -// // } else { -// // throw Web3Error.dataError -// // } -// // } -// // -// // buffer = Data() -// // -// // return data -// // } -// } -// -// public extension RIPEMD160 { -// -// static func hash(message: Data) throws -> Data { -// var md = RIPEMD160() -// try md.update(data: message) -// return try md.finalize() -// // return try md.finalize() -// } -// -// static func hash(message: String) throws -> Data { -// return try RIPEMD160.hash(message: message.data(using: .utf8)!) -// // return try RIPEMD160.hash(message: message.data(using: .utf8)!) -// } -// } -// -// public extension RIPEMD160 { -// -// static func hmac(key: Data, message: Data) throws -> Data { -// -// var key = key -// key.count = 64 // Truncate to 64 bytes or fill-up with zeros. -// -// // let outerKeyPad = Data(bytes: key.map { $0 ^ 0x5c }) -// // let innerKeyPad = Data(bytes: key.map { $0 ^ 0x36 }) -// let outerKeyPad = Data(key.map { $0 ^ 0x5c }) -// let innerKeyPad = Data(key.map { $0 ^ 0x36 }) -// -// var innerMd = RIPEMD160() -// try innerMd.update(data: innerKeyPad) -// try innerMd.update(data: message) -// // try innerMd.update(data: innerKeyPad) -// // try innerMd.update(data: message) -// -// var outerMd = RIPEMD160() -// try outerMd.update(data: outerKeyPad) -// try outerMd.update(data: innerMd.finalize()) -// // try outerMd.update(data: outerKeyPad) -// // try outerMd.update(data: innerMd.finalize()) -// -// return try outerMd.finalize() -// // return try outerMd.finalize() -// } -// -// static func hmac(key: Data, message: String) throws -> Data { -// return try RIPEMD160.hmac(key: key, message: message.data(using: .utf8)!) -// // return try RIPEMD160.hmac(key: key, message: message.data(using: .utf8)!) -// } -// -// static func hmac(key: String, message: String) throws -> Data { -// return try RIPEMD160.hmac(key: key.data(using: .utf8)!, message: message) -// // return try RIPEMD160.hmac(key: key.data(using: .utf8)!, message: message) -// } -// } diff --git a/Sources/TorusUtils/Convenience/String+Extension.swift b/Sources/TorusUtils/Convenience/String+Extension.swift deleted file mode 100755 index 54005bfc..00000000 --- a/Sources/TorusUtils/Convenience/String+Extension.swift +++ /dev/null @@ -1,149 +0,0 @@ -// web3swift -// -// Created by Alex Vlasov. -// Copyright © 2018 Alex Vlasov. All rights reserved. -// - -import Foundation - -extension String { - var fullRange: Range { - return startIndex ..< endIndex - } - - var fullNSRange: NSRange { - return NSRange(fullRange, in: self) - } - - func index(of char: Character) -> Index? { - guard let range = range(of: String(char)) else { - return nil - } - return range.lowerBound - } - - func split(intoChunksOf chunkSize: Int) -> [String] { - var output = [String]() - let splittedString = map { $0 } - .split(intoChunksOf: chunkSize) - splittedString.forEach { - output.append($0.map { String($0) }.joined(separator: "")) - } - return output - } - - subscript(bounds: CountableClosedRange) -> String { - let start = index(startIndex, offsetBy: bounds.lowerBound) - let end = index(startIndex, offsetBy: bounds.upperBound) - return String(self[start ... end]) - } - - subscript(bounds: CountableRange) -> String { - let start = index(startIndex, offsetBy: bounds.lowerBound) - let end = index(startIndex, offsetBy: bounds.upperBound) - return String(self[start ..< end]) - } - - subscript(bounds: CountablePartialRangeFrom) -> String { - let start = index(startIndex, offsetBy: bounds.lowerBound) - let end = endIndex - return String(self[start ..< end]) - } - - func leftPadding(toLength: Int, withPad character: Character) -> String { - let stringLength = count - if stringLength < toLength { - return String(repeatElement(character, count: toLength - stringLength)) + self - } else { - return String(suffix(toLength)) - } - } - - func interpretAsBinaryData() -> Data? { - let padded = padding(toLength: ((count + 7) / 8) * 8, withPad: "0", startingAt: 0) - let byteArray = padded.split(intoChunksOf: 8).map { UInt8(strtoul($0, nil, 2)) } - return Data(byteArray) - } - - func hasHexPrefix() -> Bool { - return hasPrefix("0x") - } - - func stripHexPrefix() -> String { - if hasPrefix("0x") { - let indexStart = index(startIndex, offsetBy: 2) - return String(self[indexStart...]) - } - return self - } - - func addHexPrefix() -> String { - if !hasPrefix("0x") { - return "0x" + self - } - return self - } - - func stripLeadingZeroes() -> String? { - let hex = addHexPrefix() - guard let matcher = try? NSRegularExpression(pattern: "^(?0x)0*(?[0-9a-fA-F]*)$", options: NSRegularExpression.Options.dotMatchesLineSeparators) else { return nil } - let match = matcher.captureGroups(string: hex, options: NSRegularExpression.MatchingOptions.anchored) - guard let prefix = match["prefix"] else { return nil } - guard let end = match["end"] else { return nil } - if end != "" { - return prefix + end - } - return "0x0" - } - - func matchingStrings(regex: String) -> [[String]] { - guard let regex = try? NSRegularExpression(pattern: regex, options: []) else { return [] } - let nsString = self as NSString - let results = regex.matches(in: self, options: [], range: NSRange(location: 0, length: nsString.length)) - return results.map { result in - (0 ..< result.numberOfRanges).map { result.range(at: $0).location != NSNotFound - ? nsString.substring(with: result.range(at: $0)) - : "" - } - } - } - - func range(from nsRange: NSRange) -> Range? { - guard - let from16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location, limitedBy: utf16.endIndex), - let to16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location + nsRange.length, limitedBy: utf16.endIndex), - let from = from16.samePosition(in: self), - let to = to16.samePosition(in: self) - else { return nil } - return from ..< to - } - - var asciiValue: Int { - let s = unicodeScalars - return Int(s[s.startIndex].value) - } -} - -extension Character { - var asciiValue: Int { - let s = String(self).unicodeScalars - return Int(s[s.startIndex].value) - } -} - -extension String { - func toChecksumAddress() -> String { - let lowerCaseAddress = stripHexPrefix().lowercased() - let arr = Array(lowerCaseAddress) - let hash = Array(lowerCaseAddress.sha3(.keccak256)) - var result = "0x" - for i in 0 ... lowerCaseAddress.count - 1 { - if let val = Int(String(hash[i]), radix: 16), val >= 8 { - result.append(arr[i].uppercased()) - } else { - result.append(arr[i]) - } - } - return result - } -} diff --git a/Sources/TorusUtils/DataModels.swift b/Sources/TorusUtils/DataModels.swift index c497b4f3..9795185f 100644 --- a/Sources/TorusUtils/DataModels.swift +++ b/Sources/TorusUtils/DataModels.swift @@ -2,9 +2,9 @@ import BigInt import Foundation public struct TaskGroupResponse { - public var data: Data - public var urlResponse: URLResponse - public var index: Int + public var data: Data + public var urlResponse: URLResponse + public var index: Int public init(data: Data, urlResponse: URLResponse, index: Int) { self.data = data @@ -44,9 +44,9 @@ public struct GetPublicAddressResult { public var metadataNonce: BigUInt? public var pubNonce: PubNonce? public var nodeIndexes: [Int]? - public var upgarded : Bool? + public var upgarded: Bool? - public init(address: String, typeOfUser: TypeOfUser? = nil, x: String? = nil, y: String? = nil, metadataNonce: BigUInt? = nil, pubNonce: PubNonce? = nil, nodeIndexes:[Int]? = [] , upgraded : Bool? = false) { + public init(address: String, typeOfUser: TypeOfUser? = nil, x: String? = nil, y: String? = nil, metadataNonce: BigUInt? = nil, pubNonce: PubNonce? = nil, nodeIndexes: [Int]? = [], upgraded: Bool? = false) { self.typeOfUser = typeOfUser self.address = address self.x = x @@ -54,7 +54,7 @@ public struct GetPublicAddressResult { self.metadataNonce = metadataNonce self.pubNonce = pubNonce self.nodeIndexes = nodeIndexes - self.upgarded = upgraded + upgarded = upgraded } } @@ -72,10 +72,10 @@ public struct GetOrSetNonceResult: Codable { self.ifps = ifps self.upgraded = upgraded } - + public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - + typeOfUser = try container.decodeIfPresent(String.self, forKey: .typeOfUser) nonce = try container.decodeIfPresent(String.self, forKey: .nonce) pubNonce = try container.decodeIfPresent(PubNonce.self, forKey: .pubNonce) @@ -92,11 +92,11 @@ public struct PubNonce: Codable, Equatable { self.x = x self.y = y } - + public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.x = try container.decode(String.self, forKey: .x) - self.y = try container.decode(String.self, forKey: .y) + x = try container.decode(String.self, forKey: .x) + y = try container.decode(String.self, forKey: .y) } } @@ -117,38 +117,35 @@ public struct UserTypeAndAddress { } public struct NonceMetadataParams: Codable { - public struct SetNonceData: Codable { - public var operation: String? - public var data: String? - public var timestamp: String? - - public init(operation: String? = nil, data: String? = nil, timestamp: String? = nil) { - self.operation = operation - self.data = data - self.timestamp = timestamp - } - } - - public var namespace: String? - public var pub_key_X: String - public var pub_key_Y: String - public var set_data: SetNonceData - public var signature: String - - public init(pub_key_X: String, pub_key_Y: String, setData: SetNonceData, signature: String, namespace: String? = nil) { - self.namespace = namespace - self.pub_key_X = pub_key_X - self.pub_key_Y = pub_key_Y - set_data = setData - self.signature = signature - } - } + public struct SetNonceData: Codable { + public var operation: String? + public var data: String? + public var timestamp: String? + + public init(operation: String? = nil, data: String? = nil, timestamp: String? = nil) { + self.operation = operation + self.data = data + self.timestamp = timestamp + } + } + public var namespace: String? + public var pub_key_X: String + public var pub_key_Y: String + public var set_data: SetNonceData + public var signature: String + public init(pub_key_X: String, pub_key_Y: String, setData: SetNonceData, signature: String, namespace: String? = nil) { + self.namespace = namespace + self.pub_key_X = pub_key_X + self.pub_key_Y = pub_key_Y + set_data = setData + self.signature = signature + } +} typealias StringifiedType = [String: Codable] - public struct MetadataParams: Codable { public struct SetData: Codable { public var data: String diff --git a/Sources/TorusUtils/Extensions/Data+Extension.swift b/Sources/TorusUtils/Extensions/Data+Extension.swift new file mode 100755 index 00000000..7878a496 --- /dev/null +++ b/Sources/TorusUtils/Extensions/Data+Extension.swift @@ -0,0 +1,11 @@ +import Foundation + +public extension Data { + var hexString: String { + return map { String(format: "%02x", $0) }.joined() + } + + func addLeading0sForLength64() -> Data { + Data(hex: hexString.addLeading0sForLength64()) + } +} diff --git a/Sources/TorusUtils/Extensions/HelperExtension.swift b/Sources/TorusUtils/Extensions/HelperExtension.swift deleted file mode 100644 index d60dc8ce..00000000 --- a/Sources/TorusUtils/Extensions/HelperExtension.swift +++ /dev/null @@ -1,48 +0,0 @@ -// -// File.swift -// -// -// Created by Dhruv Jaiswal on 09/04/23. -// - -import Foundation -import BigInt - -// Necessary for decryption - -extension Sequence where Element == UInt8 { - var data: Data { .init(self) } - var hexa: String { map { .init(format: "%02x", $0) }.joined() } -} - -extension Data { - init?(hexString: String) { - let length = hexString.count / 2 - var data = Data(capacity: length) - for i in 0 ..< length { - let j = hexString.index(hexString.startIndex, offsetBy: i * 2) - let k = hexString.index(j, offsetBy: 2) - let bytes = hexString[j ..< k] - if var byte = UInt8(bytes, radix: 16) { - data.append(&byte, count: 1) - } else { - return nil - } - } - self = data - } - - func addLeading0sForLength64() -> Data { - Data(hex: toHexString().addLeading0sForLength64()) - } -} - - -extension BigUInt { - init?(hex: String) { - guard let result = BigUInt(hex, radix: 16) else{ - return nil - } - self = result - } -} diff --git a/Sources/TorusUtils/Extensions/OSLog+categories.swift b/Sources/TorusUtils/Extensions/OSLog+categories.swift index 4444d508..795d5da7 100644 --- a/Sources/TorusUtils/Extensions/OSLog+categories.swift +++ b/Sources/TorusUtils/Extensions/OSLog+categories.swift @@ -1,10 +1,3 @@ -// -// File.swift -// -// -// Created by Shubham on 7/9/21. -// - import Foundation import os @@ -17,21 +10,7 @@ public struct TorusUtilsLogger { static let core = OSLog(subsystem: subsystem, category: "core") } -@available(macOS 10.15, iOS 13.0, *) func getTorusLogger(log: OSLog = .default, type: OSLogType = .default) -> OSLog { var logCheck: OSLog { utilsLogType.rawValue <= type.rawValue ? log : TorusUtilsLogger.inactiveLog } return logCheck } - -// @available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) -// func log(_ message: StaticString, dso: UnsafeRawPointer? = #dsohandle, log: OSLog = .default, type: OSLogType = .default, _ args: CVarArg...){ -// var logCheck: OSLog -// if(utilsLogType.rawValue <= type.rawValue){ -// logCheck = log -// }else{ -// logCheck = TorusUtilsLogger.inactiveLog -// } -// -// // TODO: fix the variadic parameter limitation in swift -// os_log(message, dso: dso, log: logCheck, type: type, args) -// } diff --git a/Sources/TorusUtils/Extensions/Sequence+Extension.swift b/Sources/TorusUtils/Extensions/Sequence+Extension.swift new file mode 100644 index 00000000..8b10b1e7 --- /dev/null +++ b/Sources/TorusUtils/Extensions/Sequence+Extension.swift @@ -0,0 +1,7 @@ +import BigInt +import Foundation + +extension Sequence where Element == UInt8 { + var data: Data { .init(self) } + var hexa: String { map { .init(format: "%02x", $0) }.joined() } +} diff --git a/Sources/TorusUtils/Extensions/StringExtension.swift b/Sources/TorusUtils/Extensions/String+Extension.swift old mode 100644 new mode 100755 similarity index 51% rename from Sources/TorusUtils/Extensions/StringExtension.swift rename to Sources/TorusUtils/Extensions/String+Extension.swift index 803ad6fc..92b80d51 --- a/Sources/TorusUtils/Extensions/StringExtension.swift +++ b/Sources/TorusUtils/Extensions/String+Extension.swift @@ -1,53 +1,38 @@ -// -// File.swift -// -// -// Created by Dhruv Jaiswal on 23/11/22. -// - import Foundation -extension String { - func padLeft(padChar: Character, count: Int) -> String { - let str = self - if str.count >= count { - return str - } - var resultStr = "" - while str.count < count - str.count { - resultStr.append(padChar) - } - resultStr.append(str) - return resultStr +extension String { + func hasHexPrefix() -> Bool { + return hasPrefix("0x") } - mutating func stripPaddingLeft(padChar: Character) { - while self.count > 1 && self.first == padChar { - self.removeFirst() + func addHexPrefix() -> String { + if !hasPrefix("0x") { + return "0x" + self } + return self } - func fromBase64() -> String? { - guard let data = Data(base64Encoded: self) else { - return nil + func stripHexPrefix() -> String { + if hasPrefix("0x") { + let indexStart = index(startIndex, offsetBy: 2) + return String(self[indexStart...]) } - return String(data: data, encoding: .utf8) + return self } - func toBase64() -> String { - return Data(utf8).base64EncodedString() + func has04Prefix() -> Bool { + return hasPrefix("04") } - func strip04Prefix() -> String { - if hasPrefix("04") { - let indexStart = index(startIndex, offsetBy: 2) - return String(self[indexStart...]) + func add04Prefix() -> String { + if !hasPrefix("04") { + return "04" + self } return self } - func strip0xPrefix() -> String { - if hasPrefix("0x") { + func strip04Prefix() -> String { + if hasPrefix("04") { let indexStart = index(startIndex, offsetBy: 2) return String(self[indexStart...]) } @@ -61,12 +46,25 @@ extension String { } else { return self } - // String(format: "%064d", self) } - - + func customBytes() -> Array { - data(using: String.Encoding.utf8, allowLossyConversion: true)?.bytes ?? Array(utf8) + data(using: String.Encoding.utf8, allowLossyConversion: true)?.bytes ?? Array(utf8) + } + + func toChecksumAddress() -> String { + let lowerCaseAddress = stripHexPrefix().lowercased() + let arr = Array(lowerCaseAddress) + let hash = Array(lowerCaseAddress.sha3(.keccak256)) + var result = String() + for i in 0 ... lowerCaseAddress.count - 1 { + if let val = Int(String(hash[i]), radix: 16), val >= 8 { + result.append(arr[i].uppercased()) + } else { + result.append(arr[i]) + } + } + return result.addHexPrefix() } } diff --git a/Sources/TorusUtils/Extensions/TorusUtils+extension.swift b/Sources/TorusUtils/Extensions/TorusUtils+extension.swift index 1b774d49..699198cc 100644 --- a/Sources/TorusUtils/Extensions/TorusUtils+extension.swift +++ b/Sources/TorusUtils/Extensions/TorusUtils+extension.swift @@ -1,27 +1,16 @@ -// -// TorusUtils+extension.swift -// -// -// Created by Shubham on 25/3/20. -// - -//import FetchNodeDetails -import Foundation import CryptoSwift - +import Foundation #if canImport(secp256k1) -import secp256k1 + import secp256k1 #endif +import AnyCodable import BigInt +import CommonSources import CryptoKit -import OSLog - import FetchNodeDetails -import CommonSources -import AnyCodable +import OSLog extension TorusUtils { - // MARK: - utils internal func combinations(elements: ArraySlice, k: Int) -> [[T]] { @@ -72,16 +61,16 @@ extension TorusUtils { } return nil } - + internal func isLegacyNetwork() -> Bool { if case .legacy = network { return true } return false } - + internal func isMigratedLegacyNetwork() -> Bool { - if case .legacy(let legacyNetwork) = network { + if case let .legacy(legacyNetwork) = network { let legacyRoute = legacyNetwork.migration_map if !legacyRoute.migrationCompleted { return true @@ -91,96 +80,71 @@ extension TorusUtils { return false } - - // MARK: - metadata API + internal func getMetadata(dictionary: [String: String]) async throws -> BigUInt { - let encoded: Data? - do { - encoded = try JSONSerialization.data(withJSONObject: dictionary, options: []) - } catch { - throw error - } - - guard let encodedUnwrapped = encoded else { - throw TorusUtilError.runtime("Unable to serialize dictionary into JSON. \(dictionary)") - } - var request = try! makeUrlRequest(url: "\(self.legacyMetadataHost)/get") - request.httpBody = encodedUnwrapped - do { - let val = try await urlSession.data(for: request) - let data = try JSONSerialization.jsonObject(with: val.0) as? [String: Any] ?? [:] - os_log("getMetadata: %@", log: getTorusLogger(log: TorusUtilsLogger.network, type: .info), type: .info, data) - guard - let msg: String = data["message"] as? String, - let ret = BigUInt(msg, radix: 16) - else { - throw TorusUtilError.decodingFailed("Message value not correct or nil in \(data)") - } - return ret - } catch { - return BigUInt("0", radix: 16)! + let encoded = try JSONSerialization.data(withJSONObject: dictionary, options: [.sortedKeys]) + + var request = try makeUrlRequest(url: "\(legacyMetadataHost)/get") + request.httpBody = encoded + let val = try await urlSession.data(for: request) + let data = try JSONSerialization.jsonObject(with: val.0) as? [String: Any] ?? [:] + os_log("getMetadata: %@", log: getTorusLogger(log: TorusUtilsLogger.network, type: .info), type: .info, data) + guard + let msg: String = data["message"] as? String, + let ret = BigUInt(msg, radix: 16) + else { + throw TorusUtilError.decodingFailed("Message value not correct or nil in \(data)") } + return ret } - + internal func getOrSetNonce(x: String, y: String, privateKey: String? = nil, getOnly: Bool = false) async throws -> GetOrSetNonceResult { - var data: Data - let msg = getOnly ? "getNonce" : "getOrSetNonce" - do { - if privateKey != nil { - let val = try generateParams(message: msg, privateKey: privateKey!) - data = try JSONEncoder().encode(val) - } else { - let dict: [String: Any] = ["pub_key_X": x, "pub_key_Y": y, "set_data": ["data": msg]] - data = try JSONSerialization.data(withJSONObject: dict) - } - var request = try! makeUrlRequest(url: "\(self.legacyMetadataHost)/get_or_set_nonce") - request.httpBody = data - let val = try await urlSession.data(for: request) - let decoded = try JSONDecoder().decode(GetOrSetNonceResult.self, from: val.0) - return decoded - } catch let error { - throw error - } + var data: Data + let msg = getOnly ? "getNonce" : "getOrSetNonce" + if privateKey != nil { + let val = try generateParams(message: msg, privateKey: privateKey!) + let encoder = JSONEncoder() + encoder.outputFormatting = .sortedKeys + data = try encoder.encode(val) + } else { + let dict: [String: Any] = ["pub_key_X": x, "pub_key_Y": y, "set_data": ["data": msg]] + data = try JSONSerialization.data(withJSONObject: dict, options: .sortedKeys) } - + var request = try makeUrlRequest(url: "\(legacyMetadataHost)/get_or_set_nonce") + request.httpBody = data + let val = try await urlSession.data(for: request) + let decoded = try JSONDecoder().decode(GetOrSetNonceResult.self, from: val.0) + return decoded + } + internal func generateParams(message: String, privateKey: String) throws -> MetadataParams { - do { - - let privKeyData = Data(hex: privateKey) - // this pubkey is not being padded in backend as well on web, so do not pad here. - guard let publicKey = SECP256K1.privateToPublic(privateKey: privKeyData)?.subdata(in: 1 ..< 65).toHexString() - else { - throw TorusUtilError.runtime("invalid priv key") - } + let privKey = try secp256k1.Signing.PrivateKey(dataRepresentation: Data(hex: privateKey), format: .uncompressed) + let publicKey = privKey.publicKey.dataRepresentation.hexString - let timeStamp = String(BigUInt(serverTimeOffset + Date().timeIntervalSince1970), radix: 16) - let setData: MetadataParams.SetData = .init(data: message, timestamp: timeStamp) - let encodedData = try JSONEncoder().encode(setData) - -// let hash = encodedData.web3.keccak256 - let hash = keccak256Data(encodedData) - guard let sigData = SECP256K1.signForRecovery(hash: hash, privateKey: privKeyData).serializedSignature else { - throw TorusUtilError.runtime("sign for recovery hash failed") - } - var pubKeyX = String(publicKey.prefix(64)) - var pubKeyY = String(publicKey.suffix(64)) + let timeStamp = String(BigUInt(serverTimeOffset + Date().timeIntervalSince1970), radix: 16) + let setData: MetadataParams.SetData = .init(data: message, timestamp: timeStamp) + let encoder = JSONEncoder() + encoder.outputFormatting = .sortedKeys + let encodedData = try encoder + .encode(setData) - return .init(pub_key_X: pubKeyX, pub_key_Y: pubKeyY, setData: setData, signature: sigData.base64EncodedString()) - } catch let error { - throw error + let hash = keccak256Data(encodedData) + guard let sigData = secp256k1.signForRecovery(hash: hash, privateKey: privKey.dataRepresentation).serializedSignature + else { + throw TorusUtilError.runtime("sign for recovery hash failed") } + + return .init(pub_key_X: String(publicKey.suffix(128).prefix(64)), pub_key_Y: String(publicKey.suffix(64)), setData: setData, signature: sigData.base64EncodedString()) } - - // MARK: - getShareOrKeyAssign - + private func getShareOrKeyAssign(endpoints: [String], nodeSigs: [CommitmentRequestResponse], verifier: String, verifierParams: VerifierParams, idToken: String, extraParams: [String: Any] = [:]) async throws -> [URLRequest] { - let session = createURLSession() - let threshold = Int(endpoints.count / 2) + 1 + _ = createURLSession() + _ = Int(endpoints.count / 2) + 1 var rpcdata: Data = Data() - + let loadedStrings = extraParams let valueDict = ["idtoken": idToken, "nodesignatures": nodeSigs, @@ -188,84 +152,71 @@ extension TorusUtils { "verifier_id": verifierParams.verifier_id, "extended_verifier_id": verifierParams.extended_verifier_id, ] as [String: Codable] - + let keepingCurrent = loadedStrings.merging(valueDict) { current, _ in current } let finalItem = keepingCurrent.merging(verifierParams.additionalParams) { current, _ in current } - - let params = ["encrypted": "yes", - "use_temp": true, - "one_key_flow": true, - "item": AnyCodable([finalItem]) + + let params = ["encrypted": "yes", + "use_temp": true, + "one_key_flow": true, + "item": AnyCodable([finalItem]), ] as [String: AnyCodable] - + let dataForRequest = ["jsonrpc": "2.0", "id": 10, "method": AnyCodable(JRPC_METHODS.GET_SHARE_OR_KEY_ASSIGN), - "params": AnyCodable(params) - ] as [String: AnyCodable] - - do { - rpcdata = try JSONEncoder().encode(dataForRequest) - } catch { - os_log("get share or key assign - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) - } -// print("rpcdata", String(data: rpcdata, encoding: .utf8)!) + "params": AnyCodable(params), + ] as [String: AnyCodable] - // Create Array of URLRequest Promises + // do { + let encoder = JSONEncoder() + encoder.outputFormatting = .sortedKeys + rpcdata = try encoder.encode(dataForRequest) + // } catch { + // os_log("get share or key assign - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) + // } + // Create Array of URLRequest Promises var requestArray = [URLRequest]() for endpoint in endpoints { - do { - var request = try makeUrlRequest(url: endpoint, httpMethod: .post) - request.httpBody = rpcdata - requestArray.append(request) - } catch { - throw error - } + var request = try makeUrlRequest(url: endpoint, httpMethod: .post) + request.httpBody = rpcdata + requestArray.append(request) } - + return requestArray } - - private func reconstructKey(decryptedShares: [Int: String], thresholdPublicKey: KeyAssignment.PublicKey) throws -> String? { - // run lagrange interpolation on all subsets, faster in the optimistic scenario than berlekamp-welch due to early exit - let allCombis = kCombinations(s: decryptedShares.count, k: 3) - var returnedKey: String? = nil + let allCombis = combinations(elements: Array(0 ..< decryptedShares.count), k: 3) + var returnedKey: String? - for j in 0.. TorusKey { - let session = createURLSession() let threshold = (endpoints.count / 2) + 1 - guard - let sessionAuthKey = generatePrivateKeyData()?.toHexString(), - let publicKey = SECP256K1.privateToPublic(privateKey: Data(hex:sessionAuthKey))?.subdata(in: 1 ..< 65) - else { - throw TorusUtilError.runtime("Unable to generate SECP256K1 keypair.") - } + + let sessionAuthKey = try secp256k1.KeyAgreement.PrivateKey(format: .uncompressed) + let serializedPublicKey = sessionAuthKey.publicKey.dataRepresentation.hexString // Split key in 2 parts, X and Y - // let publicKeyHex = publicKey.toHexString() - let pubKeyX = publicKey.prefix(publicKey.count / 2).toHexString().addLeading0sForLength64() - let pubKeyY = publicKey.suffix(publicKey.count / 2).toHexString().addLeading0sForLength64() - - // Hash the token from OAuth login + let pubKeyX = String(serializedPublicKey.suffix(128).prefix(64)) + let pubKeyY = String(serializedPublicKey.suffix(64)) + // Hash the token from OAuth login let timestamp = String(Int(getTimestamp())) let hashedToken = idToken.sha3(.keccak256) - - let nodeSigs = try await commitmentRequest(endpoints: endpoints, verifier: verifier, pubKeyX: pubKeyX, pubKeyY: pubKeyY, timestamp: timestamp, tokenCommitment: hashedToken) os_log("retrieveShares - data after commitment request: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, nodeSigs) var promiseArrRequest = [URLRequest]() - - // TODO: make sure we have only complete requests in promiseArrRequest? + // TODO: make sure we have only complete requests in promiseArrRequest? promiseArrRequest = try await getShareOrKeyAssign(endpoints: endpoints, nodeSigs: nodeSigs, verifier: verifier, verifierParams: verifierParams, idToken: idToken, extraParams: extraParams) - - - var thresholdNonceData : GetOrSetNonceResult? + + var thresholdNonceData: GetOrSetNonceResult? var pubkeyArr = [KeyAssignment.PublicKey]() var isNewKeyArr: [String] = [] var completeShareRequestResponseArr = [ShareRequestResult]() - var thresholdPublicKey : KeyAssignment.PublicKey? - + var thresholdPublicKey: KeyAssignment.PublicKey? + try await withThrowingTaskGroup(of: Result.self, body: { group in - for (i, rq) in promiseArrRequest.enumerated() { group.addTask { do { @@ -333,75 +273,67 @@ extension TorusUtils { for try await val in group { do { switch val { - - case.success(let model): + case let .success(model): let data = model.data let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data) os_log("retrieveShare promise - reponse: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, decoded.message ?? "") - + if decoded.error != nil { os_log("retrieveShare promise - decode error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, decoded.error?.message ?? "") throw TorusUtilError.runtime(decoded.error?.message ?? "") } - + // Ensure that we don't add bad data to result arrays. guard let decodedResult = decoded.result as? ShareRequestResult else { throw TorusUtilError.decodingFailed("ShareReqeust error decoding error : \(decoded), can't decode into shareRequestResult") } - + isNewKeyArr.append(decodedResult.isNewKey) completeShareRequestResponseArr.append(decodedResult) let keyObj = decodedResult.keys if let first = keyObj.first { - let pubkey = first.publicKey let nonceData = first.nonceData let pubNonce = nonceData?.pubNonce?.x - - + pubkeyArr.append(pubkey) if thresholdNonceData == nil && verifierParams.extended_verifier_id == nil { if pubNonce != "" { thresholdNonceData = nonceData } } - // pubkeyArr.append(pubkey) guard let result = thresholdSame(arr: pubkeyArr, threshold: threshold) else { throw TorusUtilError.thresholdError } - + thresholdPublicKey = result - - if (thresholdPublicKey?.X == nil) { + + if thresholdPublicKey?.X == nil { throw TorusUtilError.thresholdError } - + if thresholdNonceData == nil && verifierParams.extended_verifier_id == nil && !isLegacyNetwork() { throw TorusUtilError.metadataNonceMissing } - return } - - case.failure(let error): + case let .failure(error): throw error } } catch { os_log("retrieveShare promise - share request error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug)) } } - + os_log("retrieveShare - invalid result from nodes, threshold number of public key results are not matching", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error) throw TorusUtilError.thresholdError }) - - + // optimistically run lagrange interpolation once threshold number of shares have been received // this is matched against the user public key to ensure that shares are consistent // Note: no need of thresholdMetadataNonce for extended_verifier_id key if completeShareRequestResponseArr.count >= threshold { - if thresholdPublicKey?.X != nil && (thresholdNonceData != nil && thresholdNonceData?.pubNonce?.x != "" || verifierParams.extended_verifier_id != nil || isLegacyNetwork()) { // Code block to execute if all conditions are true var shares = [String]() @@ -409,78 +341,75 @@ extension TorusUtils { var sessionTokenPromises = [String?]() var nodeIndexes = [Int]() var sessionTokenData = [SessionToken?]() - + guard let isNewKey = thresholdSame(arr: isNewKeyArr, threshold: threshold) else { os_log("retrieveShare - invalid result from nodes, threshold number of is_new_key results are not matching", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error) throw TorusUtilError.thresholdError } - + for currentShareResponse in completeShareRequestResponseArr { let sessionTokens = currentShareResponse.sessionTokens let sessionTokenMetadata = currentShareResponse.sessionTokenMetadata let sessionTokenSigs = currentShareResponse.sessionTokenSigs let sessionTokenSigMetadata = currentShareResponse.sessionTokenSigMetadata let keys = currentShareResponse.keys - + if sessionTokenSigs.count > 0 { // decrypt sessionSig if enc metadata is sent - if (sessionTokenSigMetadata.first?.ephemPublicKey != nil) { - sessionTokenSigPromises.append(try? decryptNodeData(eciesData: sessionTokenSigMetadata[0], ciphertextHex: sessionTokenSigs[0], privKey: sessionAuthKey)) + if sessionTokenSigMetadata.first?.ephemPublicKey != nil { + sessionTokenSigPromises.append(try? decryptNodeData(eciesData: sessionTokenSigMetadata[0], ciphertextHex: sessionTokenSigs[0], privKey: sessionAuthKey.rawRepresentation.hexString.addLeading0sForLength64())) } else { sessionTokenSigPromises.append(sessionTokenSigs[0]) } } else { sessionTokenSigPromises.append(nil) } - + if sessionTokens.count > 0 { - if (sessionTokenMetadata.first?.ephemPublicKey != nil) { - sessionTokenPromises.append(try? decryptNodeData(eciesData: sessionTokenMetadata[0], ciphertextHex: sessionTokens[0], privKey: sessionAuthKey)) + if sessionTokenMetadata.first?.ephemPublicKey != nil { + sessionTokenPromises.append(try? decryptNodeData(eciesData: sessionTokenMetadata[0], ciphertextHex: sessionTokens[0], privKey: sessionAuthKey.rawRepresentation.hexString.addLeading0sForLength64())) } else { sessionTokenPromises.append(sessionTokenSigs[0]) } } else { sessionTokenPromises.append(nil) } - + if keys.count > 0 { let latestKey = currentShareResponse.keys[0] nodeIndexes.append(Int(latestKey.nodeIndex)) - let data = Data(base64Encoded: latestKey.share, options: [] )! + let data = Data(base64Encoded: latestKey.share, options: [])! guard let ciphertextHex = String(data: data, encoding: .ascii) else { throw TorusUtilError.decodingFailed() } - var decryptedShare = try decryptNodeData(eciesData: latestKey.shareMetadata, ciphertextHex: ciphertextHex, privKey: sessionAuthKey) + let decryptedShare = try decryptNodeData(eciesData: latestKey.shareMetadata, ciphertextHex: ciphertextHex, privKey: sessionAuthKey.rawRepresentation.hexString.addLeading0sForLength64()) shares.append(decryptedShare.addLeading0sForLength64()) } else { os_log("retrieveShare - 0 keys returned from nodes", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error) throw TorusUtilError.thresholdError } - } - - + let validTokens = sessionTokenPromises.filter { token in if let _ = token { return true } return false } - + if verifierParams.extended_verifier_id == nil && validTokens.count < threshold { os_log("retrieveShare - Insufficient number of session tokens from nodes, required: %@, found: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, threshold, validTokens.count) throw TorusUtilError.apiRequestFailed } - let validSigs = sessionTokenSigPromises.filter { sig in if let _ = sig { return true } return false } - + if verifierParams.extended_verifier_id == nil && validSigs.count < threshold { os_log("retrieveShare - Insufficient number of session signatures from nodes, required: %@, found: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, threshold, validSigs.count) throw TorusUtilError.apiRequestFailed @@ -491,79 +420,72 @@ extension TorusUtils { sessionTokenData.append(nil) } else { let token = x! - let signature = sessionTokenSigPromises[index]//.toHexString() + let signature = sessionTokenSigPromises[index] let nodePubX = completeShareRequestResponseArr[index].nodePubX let nodePubY = completeShareRequestResponseArr[index].nodePubY sessionTokenData.append(SessionToken(token: token, signature: signature!, node_pubx: nodePubX, node_puby: nodePubY)) } } - - let sharesWithIndex = shares.enumerated().reduce(into: [ Int : String ]()) { acc, current in + + let sharesWithIndex = shares.enumerated().reduce(into: [Int: String]()) { acc, current in let (index, curr) = current acc[nodeIndexes[index]] = curr } - + let returnedKey = try reconstructKey(decryptedShares: sharesWithIndex, thresholdPublicKey: thresholdPublicKey!) - if (returnedKey == nil) { + if returnedKey == nil { throw TorusUtilError.privateKeyDeriveFailed } - + guard let oAuthKey = returnedKey else { throw TorusUtilError.privateKeyDeriveFailed } - -// let decryptedPubKey = SECP256K1.privateToPublic(privateKey: Data(hex: oAuthKey) )?.toHexString() - - let oAuthKeyBigInt = BigInt(oAuthKey , radix: 16)! - - guard let derivedPrivateKeyData = Data(hexString: oAuthKey) else { - throw TorusUtilError.privateKeyDeriveFailed - } - - let oAuthPubKey = SECP256K1.privateToPublic(privateKey: derivedPrivateKeyData.addLeading0sForLength64())?.toHexString() - let oauthPubKeyX = String(oAuthPubKey!.suffix(128).prefix(64)) - let oauthPubKeyY = String(oAuthPubKey!.suffix(64)) - + + let derivedPrivateKey = try secp256k1.KeyAgreement.PrivateKey(dataRepresentation: Data(hex: oAuthKey), format: .uncompressed) + + let oAuthPubKey = derivedPrivateKey.publicKey.dataRepresentation.hexString + let oAuthPubKeyX = String(oAuthPubKey.suffix(128).prefix(64)) + let oAuthPubKeyY = String(oAuthPubKey.suffix(64)) + var metadataNonce = BigInt(thresholdNonceData?.nonce ?? "0", radix: 16) ?? BigInt(0) - let privateKeyWithNonce = (oAuthKeyBigInt + metadataNonce).modulus(modulusValue) var pubKeyNonceResult: PubNonce? var typeOfUser: UserType = .v1 - - var finalPubKey = "04" + oauthPubKeyX.addLeading0sForLength64() + oauthPubKeyY.addLeading0sForLength64() + + var finalPubKey = oAuthPubKey if verifierParams.extended_verifier_id != nil { typeOfUser = .v2 // For TSS key, no need to add pub nonce finalPubKey = String(finalPubKey.suffix(128)) - } else if case .legacy(_) = self.network { - if (self.enableOneKey) { + } else if case .legacy = self.network { + if self.enableOneKey { // get or set nonce based on isNewKey variable - let nonceResult = try await getOrSetNonce(x: oauthPubKeyX, y: oauthPubKeyY, privateKey: oAuthKey, getOnly: isNewKey == "false") + let nonceResult = try await getOrSetNonce(x: oAuthPubKeyX, y: oAuthPubKeyY, privateKey: oAuthKey, getOnly: isNewKey == "false") // BigInt( Data(hex: nonceResult.nonce ?? "0")) - metadataNonce = BigInt( nonceResult.nonce ?? "0", radix: 16)! + metadataNonce = BigInt(nonceResult.nonce ?? "0", radix: 16)! let usertype = nonceResult.typeOfUser - - if (usertype == "v2") { + + if usertype == "v2" { let pubNonceX = nonceResult.pubNonce?.x let pubNonceY = nonceResult.pubNonce?.y typeOfUser = .v2 - let pubkey2 = "04" + pubNonceX!.addLeading0sForLength64() + pubNonceY!.addLeading0sForLength64() - let combined = combinePublicKeys(keys: [finalPubKey, pubkey2], compressed: false) + let pubkey2 = (pubNonceX!.addLeading0sForLength64() + pubNonceY!.addLeading0sForLength64()).add04Prefix() + let combined = try combinePublicKeys(keys: [finalPubKey, pubkey2], compressed: false) finalPubKey = combined pubKeyNonceResult = .init(x: pubNonceX!, y: pubNonceY!) } else { typeOfUser = .v1 // for imported keys in legacy networks - metadataNonce = BigInt(try await getMetadata(dictionary: ["pub_key_X": oauthPubKeyX, "pub_key_Y": oauthPubKeyY])) - let privateKeyWithNonce = ((BigInt(oAuthKey, radix: 16)!) + BigInt(metadataNonce)).modulus(modulusValue) + metadataNonce = BigInt(try await getMetadata(dictionary: ["pub_key_X": oAuthPubKeyX, "pub_key_Y": oAuthPubKeyY])) + let privateKeyWithNonce = (BigInt(oAuthKey, radix: 16)! + BigInt(metadataNonce)).modulus(modulusValue) finalPubKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64() } } else { typeOfUser = .v1 // for imported keys in legacy networks - metadataNonce = BigInt(try await getMetadata(dictionary: ["pub_key_X": oauthPubKeyX, "pub_key_Y": oauthPubKeyY])) - let privateKeyWithNonce = ((BigInt(oAuthKey, radix: 16)!) + BigInt(metadataNonce)).modulus(modulusValue) + metadataNonce = BigInt(try await getMetadata(dictionary: ["pub_key_X": oAuthPubKeyX, "pub_key_Y": oAuthPubKeyY])) + let privateKeyWithNonce = (BigInt(oAuthKey, radix: 16)! + BigInt(metadataNonce)).modulus(modulusValue) finalPubKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64() } } else { @@ -571,40 +493,35 @@ extension TorusUtils { let pubNonceX = thresholdNonceData!.pubNonce!.x let pubNonceY = thresholdNonceData!.pubNonce!.y - let pubkey2 = "04" + pubNonceX.addLeading0sForLength64() + pubNonceY.addLeading0sForLength64() - let combined = combinePublicKeys(keys: [finalPubKey, pubkey2], compressed: false) + let pubkey2 = (pubNonceX.addLeading0sForLength64() + pubNonceY.addLeading0sForLength64()).add04Prefix() + let combined = try combinePublicKeys(keys: [finalPubKey, pubkey2], compressed: false) finalPubKey = combined pubKeyNonceResult = .init(x: pubNonceX, y: pubNonceY) } + let oAuthKeyAddress = generateAddressFromPubKey(publicKeyX: oAuthPubKeyX, publicKeyY: oAuthPubKeyY) - - let (oAuthKeyX, oAuthKeyY) = try getPublicKeyPointFromPubkeyString(pubKey: oAuthPubKey!) - let oAuthKeyAddress = generateAddressFromPubKey(publicKeyX: oAuthKeyX, publicKeyY: oAuthKeyY) - - var finalPrivKey = "" - + if typeOfUser == .v1 || (typeOfUser == .v2 && metadataNonce > BigInt(0)) { let privateKeyWithNonce = ((BigInt(oAuthKey, radix: 16) ?? BigInt(0)) + metadataNonce).modulus(modulusValue) finalPrivKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64() - } - - let (finalPubX , finalPubY) = try getPublicKeyPointFromPubkeyString(pubKey: finalPubKey) + + let (finalPubX, finalPubY) = try getPublicKeyPointFromPubkeyString(pubKey: finalPubKey) // deriving address from pub key coz pubkey is always available // but finalPrivKey won't be available for v2 user upgraded to 2/n let finalEvmAddress = generateAddressFromPubKey(publicKeyX: finalPubX, publicKeyY: finalPubY) - + var isUpgraded: Bool? - + switch typeOfUser { case .v1: isUpgraded = nil case .v2: isUpgraded = metadataNonce == BigInt(0) } - + return TorusKey( finalKeyData: .init( evmAddress: finalEvmAddress, @@ -614,13 +531,13 @@ extension TorusUtils { ), oAuthKeyData: .init( evmAddress: oAuthKeyAddress, - X: oAuthKeyX, - Y: oAuthKeyY, + X: oAuthPubKeyX, + Y: oAuthPubKeyY, privKey: oAuthKey ), sessionData: .init( sessionTokenData: sessionTokenData, - sessionAuthKey: sessionAuthKey + sessionAuthKey: sessionAuthKey.rawRepresentation.hexString.addLeading0sForLength64() ), metadata: .init( pubNonce: pubKeyNonceResult, @@ -630,9 +547,7 @@ extension TorusUtils { ), nodesData: .init(nodeIndexes: nodeIndexes) ) - } - } throw TorusUtilError.retrieveOrImportShareError } @@ -641,7 +556,7 @@ extension TorusUtils { internal func commitmentRequest(endpoints: [String], verifier: String, pubKeyX: String, pubKeyY: String, timestamp: String, tokenCommitment: String) async throws -> [CommitmentRequestResponse] { let session = createURLSession() - + let threshold = Int(endpoints.count / 4) * 3 + 1 let encoder = JSONEncoder() var failedLookUpCount = 0 @@ -654,7 +569,7 @@ extension TorusUtils { "verifieridentifier": verifier, "timestamp": timestamp] ) - + guard let rpcdata = try? encoder.encode(jsonRPCRequest) else { throw TorusUtilError.runtime("Unable to encode request. \(jsonRPCRequest)") @@ -664,18 +579,13 @@ extension TorusUtils { var nodeSignatures = [CommitmentRequestResponse]() var requestArr = [URLRequest]() for (_, el) in endpoints.enumerated() { - do { - var rq = try makeUrlRequest(url: el) - rq.httpBody = rpcdata - requestArr.append(rq) - } catch { - throw error - } + var rq = try makeUrlRequest(url: el) + rq.httpBody = rpcdata + requestArr.append(rq) } return try await withThrowingTaskGroup(of: Result.self, body: { group in for (i, rq) in requestArr.enumerated() { - group.addTask { do { let val = try await session.data(for: rq) @@ -690,7 +600,7 @@ extension TorusUtils { do { try Task.checkCancellation() switch val { - case.success(let model): + case let .success(model): let data = model.data let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data) os_log("commitmentRequest - reponse: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, decoded.message ?? "") @@ -705,7 +615,7 @@ extension TorusUtils { guard let response = decoded.result as? CommitmentRequestResponse else { - throw TorusUtilError.decodingFailed("\(decoded.result) is not a CommitmentRequestResponse") + throw TorusUtilError.decodingFailed("CommitmentRequestResponse could not be decoded") } // Check if k+t responses are back @@ -716,64 +626,71 @@ extension TorusUtils { session.invalidateAndCancel() return nodeSignatures } - case.failure(let error): + case let .failure(error): os_log("commitmentRequest - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) } } catch { failedLookUpCount += 1 - os_log("commitmentRequest - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) + os_log("commitmentRequest - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) if failedLookUpCount > endpoints.count - threshold { - os_log("commitmentRequest - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, TorusUtilError.runtime("threshold node unavailable").localizedDescription) - session.invalidateAndCancel() + os_log("commitmentRequest - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, TorusUtilError.runtime("threshold node unavailable").localizedDescription) + session.invalidateAndCancel() throw error - } + } } } throw TorusUtilError.commitmentRequestFailed }) } - + internal func convertMetadataToNonce(params: [String: Any]?) -> BigUInt { guard let params = params, let message = params["message"] as? String else { return BigUInt(0) } return BigUInt(message, radix: 16)! } - - internal func decryptNodeData(eciesData: EciesHex, ciphertextHex: String, privKey: String, padding: Padding = .pkcs7) throws -> String { + internal func decryptNodeData(eciesData: EciesHex, ciphertextHex: String, privKey: String, padding: Padding = .pkcs7) throws -> String { let eciesOpts = ECIES( iv: eciesData.iv, ephemPublicKey: eciesData.ephemPublicKey, ciphertext: ciphertextHex, mac: eciesData.mac ) - - let decryptedSigBuffer = try decrypt(privateKey: privKey, opts: eciesOpts, padding: padding).toHexString() + + let decryptedSigBuffer = try decrypt(privateKey: privKey, opts: eciesOpts, padding: padding).hexString return decryptedSigBuffer } - public func encryptData(privkeyHex: String, _ dataToEncrypt: String) throws -> String { - guard let pubKey = SECP256K1.privateToPublic(privateKey: privkeyHex.hexa.data)?.toHexString() else { - throw TorusUtilError.runtime("Invalid private key hex") - } + let privKey = try secp256k1.KeyAgreement.PrivateKey(dataRepresentation: Data(hex: privkeyHex), format: .uncompressed) + let pubKey = privKey.publicKey.dataRepresentation.hexString let encParams = try encrypt(publicKey: pubKey, msg: dataToEncrypt, opts: nil) let data = try JSONEncoder().encode(encParams) guard let string = String(data: data, encoding: .utf8) else { throw TorusUtilError.runtime("Invalid String from enc Params") } return string } - + + internal func randomBytes(ofLength length: Int) throws -> [UInt8] { + var bytes = [UInt8](repeating: 0, count: length) + let status = SecRandomCopyBytes(kSecRandomDefault, length, &bytes) + if status == errSecSuccess { + return bytes + } + throw TorusUtilError.runtime("Failed to generate secure random bytes") + } + public func encrypt(publicKey: String, msg: String, opts: Ecies? = nil) throws -> Ecies { - let ephemPrivateKey = try secp256k1.KeyAgreement.PrivateKey(); - let ephemPublicKey = ephemPrivateKey.publicKey; - - let sharedSecret = try SECP256K1.ecdh(publicKey: ephemPublicKey, privateKey: ephemPrivateKey) - - let encryptionKey = sharedSecret[0..<32].bytes - let macKey = sharedSecret[32..<64].bytes - let iv: [UInt8] = (opts?.iv ?? SECP256K1.randomBytes(length: 16)?.toHexString())?.hexa ?? [] - + let ephemPrivateKey = try secp256k1.KeyAgreement.PrivateKey() + let ephemPublicKey = ephemPrivateKey.publicKey + + let sharedSecret = try secp256k1.ecdh(publicKey: ephemPublicKey, privateKey: ephemPrivateKey) + + let encryptionKey = sharedSecret[0 ..< 32].bytes + let macKey = sharedSecret[32 ..< 64].bytes + let random = try randomBytes(ofLength: 16) + let iv: [UInt8] = (opts?.iv ?? random.toHexString()).hexa + let aes = try AES(key: encryptionKey, blockMode: CBC(iv: iv), padding: .pkcs7) let ciphertext = try aes.encrypt(msg.customBytes()) var dataToMac: [UInt8] = iv @@ -784,42 +701,42 @@ extension TorusUtils { ciphertext: ciphertext.toHexString(), mac: mac?.toHexString() ?? "") } - // MARK: - decrypt shares internal func decryptIndividualShares(shares: [Int: RetrieveDecryptAndReconstuctResponseModel], privateKey: String) throws -> [Int: String] { - var result = [Int: String]() + var result = [Int: String]() - for (_, el) in shares.enumerated() { - let nodeIndex = el.key + for (_, el) in shares.enumerated() { + let nodeIndex = el.key - let publicKeyHex = el.value.ephemPublicKey - let sharedSecret = try SECP256K1.ecdhWithHex(pubKeyHex: publicKeyHex, privateKeyHex: privateKey) + let publicKeyHex = el.value.ephemPublicKey + let sharedSecret = try secp256k1.ecdhWithHex(pubKeyHex: publicKeyHex, privateKeyHex: privateKey) - guard - let share = el.value.share.fromBase64()?.hexa - else { - throw TorusUtilError.decryptionFailed - } - - do { - // AES-CBCblock-256 - let aesKey = sharedSecret[0..<32].bytes - let _macKey = sharedSecret[32..<64].bytes // TODO check mac - let iv = el.value.iv.hexa - let aes = try AES(key: aesKey, blockMode: CBC(iv: iv), padding: .pkcs7) - let decryptData = try aes.decrypt(share) - result[nodeIndex] = decryptData.hexa - } catch let err { - result[nodeIndex] = TorusUtilError.decodingFailed(err.localizedDescription).debugDescription - } - if shares.count == result.count { - return result - } + guard + let data = Data(base64Encoded: el.value.share), + let share = String(data: data, encoding: .utf8)?.hexa + else { + throw TorusUtilError.decryptionFailed + } + + do { + // AES-CBCblock-256 + let aesKey = sharedSecret[0 ..< 32].bytes + _ = sharedSecret[32 ..< 64].bytes // TODO: check mac + let iv = el.value.iv.hexa + let aes = try AES(key: aesKey, blockMode: CBC(iv: iv), padding: .pkcs7) + let decryptData = try aes.decrypt(share) + result[nodeIndex] = decryptData.hexa + } catch let err { + result[nodeIndex] = TorusUtilError.decodingFailed(err.localizedDescription).debugDescription + } + if shares.count == result.count { + return result } - throw TorusUtilError.runtime("decryptIndividualShares func failed") } - + throw TorusUtilError.runtime("decryptIndividualShares func failed") + } + // MARK: - Lagrange interpolation internal func thresholdLagrangeInterpolation(data filteredData: [Int: String], endpoints: [String], lookupPubkeyX: String, lookupPubkeyY: String) throws -> (String, String, String) { @@ -830,14 +747,11 @@ extension TorusUtils { shareIndexSet.forEach { sharesToInterpolate[$0] = filteredData[$0] } do { let data = try lagrangeInterpolation(shares: sharesToInterpolate) + let finalPrivateKey = try secp256k1.KeyAgreement.PrivateKey(dataRepresentation: Data(hex: data), format: .uncompressed) + let finalPublicKey = finalPrivateKey.publicKey.dataRepresentation.hexString // Split key in 2 parts, X and Y - let finalPrivateKey = Data(hex: data) - guard let publicKey = SECP256K1.privateToPublic(privateKey: finalPrivateKey)?.subdata(in: 1 ..< 65) else { - throw TorusUtilError.decodingFailed("\(data)") - } - let paddedPubKey = publicKey.toHexString().padLeft(padChar: "0", count: 128) - let pubKeyX = String(paddedPubKey.prefix(paddedPubKey.count / 2)) - let pubKeyY = String(paddedPubKey.suffix(paddedPubKey.count / 2)) + let pubKeyX = String(finalPublicKey.suffix(128).prefix(64)) + let pubKeyY = String(finalPublicKey.suffix(64)) os_log("retrieveDecryptAndReconstuct: private key rebuild %@ %@ %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, data, pubKeyX, pubKeyY) // Verify @@ -852,7 +766,7 @@ extension TorusUtils { } throw TorusUtilError.interpolationFailed } - + internal func lagrangeInterpolation(shares: [Int: String], offset: Int = 1) throws -> String { let secp256k1N = modulusValue @@ -894,30 +808,30 @@ extension TorusUtils { throw TorusUtilError.interpolationFailed } } - + // MARK: - getPubKeyOrKeyAssign - + internal func getPubKeyOrKeyAssign(endpoints: [String], verifier: String, verifierId: String, extendedVerifierId: String? = nil) async throws -> KeyLookupResult { // Encode data let encoder = JSONEncoder() let session = createURLSession() let threshold = (endpoints.count / 2) + 1 var failedLookupCount = 0 - + // flag to check if node with index 1 is queried for metadata var isNodeOneVisited = false - + let methodName = JRPC_METHODS.GET_OR_SET_KEY - - let params = GetPublicAddressOrKeyAssignParams(verifier: verifier, verifier_id: verifierId, extended_verifier_id: extendedVerifierId, one_key_flow: true, fetch_node_index: true ) + + let params = GetPublicAddressOrKeyAssignParams(verifier: verifier, verifier_id: verifierId, extended_verifier_id: extendedVerifierId, one_key_flow: true, fetch_node_index: true) let jsonRPCRequest = JSONRPCrequest( method: methodName, params: params ) - + guard let rpcdata = try? encoder.encode(jsonRPCRequest) - + else { throw TorusUtilError.encodingFailed("\(jsonRPCRequest)") } @@ -927,21 +841,17 @@ extension TorusUtils { var resultArray: [KeyLookupResponse] = [] var requestArray = [URLRequest]() for endpoint in endpoints { - do { - var request = try makeUrlRequest(url: endpoint) - request.httpBody = rpcdata - requestArray.append(request) - } catch { - throw error - } + var request = try makeUrlRequest(url: endpoint) + request.httpBody = rpcdata + requestArray.append(request) } - + var nonceResult: GetOrSetNonceResult? var nodeIndexesArray: [Int] = [] - var keyArray: [VerifierLookupResponse] = []; - + var keyArray: [VerifierLookupResponse?] = [] + return try await withThrowingTaskGroup(of: Result.self, returning: KeyLookupResult.self) { group in - + for (i, rq) in requestArray.enumerated() { group.addTask { do { @@ -952,75 +862,68 @@ extension TorusUtils { } } } - + // this is serial execution // TODO: convert this to some function implementation as we do in web for try await val in group { - do { switch val { - case .success(let model): + case let .success(model): // print( try JSONSerialization.jsonObject(with: model.data) ) let data = model.data - do { - - let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data) // User decoder to covert to struct - let result = decoded.result as? VerifierLookupResponse - - if let _ = decoded.error { - let error = KeyLookupError.createErrorFromString(errorString: "") - throw error - } else { - let decodedResult = result! - keyArray.append(decodedResult) - if let k = decodedResult.keys, - let key = k.first { - let model = KeyLookupResponse(pubKeyX: key.pub_key_X, pubKeyY: key.pub_key_Y, address: key.address, isNewKey: decodedResult.is_new_key) - - resultArray.append(model) - if let nonceData = key.nonce_data { - let pubNonceX = nonceData.pubNonce?.x - if pubNonceX != nil && pubNonceX != "" && nonceResult == nil { - nonceResult = key.nonce_data - } + let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data) // User decoder to covert to struct + let result = decoded.result as? VerifierLookupResponse + + if let _ = decoded.error { + let error = KeyLookupError.createErrorFromString(errorString: "") + throw error + } else { + let decodedResult = result! + keyArray.append(decodedResult) + if let k = decodedResult.keys, + let key = k.first { + let model = KeyLookupResponse(pubKeyX: key.pub_key_X, pubKeyY: key.pub_key_Y, address: key.address, isNewKey: decodedResult.is_new_key) + + resultArray.append(model) + if let nonceData = key.nonce_data { + let pubNonceX = nonceData.pubNonce?.x + if pubNonceX != nil && pubNonceX != "" && nonceResult == nil { + nonceResult = key.nonce_data } } - } - let keyResult = thresholdSame(arr: resultArray, threshold: threshold) // Check if threshold is satisfied - - // proceed if we have key result and either of nonceResult, extendedVerifierId, isLegacyNetwork is - // available - if (keyResult != nil && (nonceResult != nil || extendedVerifierId != nil || isLegacyNetwork())) { - if let keyResult = keyResult { - os_log("%@: fulfill: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, methodName, keyResult.description) - session.invalidateAndCancel() - keyArray.forEach( { result in - - if result.node_index == "1" { - isNodeOneVisited = true - } - if result != nil && result.node_index != "0" { - nodeIndexesArray.append(Int(result.node_index)!) - } - - }) - - return KeyLookupResult( keyResult: keyResult, nodeIndexes: nodeIndexesArray, nonceResult: nonceResult) - } + } + let keyResult = thresholdSame(arr: resultArray, threshold: threshold) // Check if threshold is satisfied + + // proceed if we have key result and either of nonceResult, extendedVerifierId, isLegacyNetwork is + // available + if keyResult != nil && (nonceResult != nil || extendedVerifierId != nil || isLegacyNetwork()) { + if let keyResult = keyResult { + os_log("%@: fulfill: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, methodName, keyResult.description) + session.invalidateAndCancel() + keyArray.forEach({ result in + + if result?.node_index == "1" { + isNodeOneVisited = true + } + if result != nil && result?.node_index != "0" { + nodeIndexesArray.append(Int(result!.node_index)!) + } + + }) + + return KeyLookupResult(keyResult: keyResult, nodeIndexes: nodeIndexesArray, nonceResult: nonceResult) } - throw NSError(domain: "condition not meet", code: 1001) - } catch let err { - throw err } + throw NSError(domain: "condition not meet", code: 1001) case let .failure(error): throw error } } catch { failedLookupCount += 1 os_log("%@: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, methodName, error.localizedDescription) - - if (isNodeOneVisited && failedLookupCount > (endpoints.count - threshold)) || (failedLookupCount == endpoints.count) { + + if (isNodeOneVisited && failedLookupCount > (endpoints.count - threshold)) || (failedLookupCount == endpoints.count) { os_log("%@: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, methodName, TorusUtilError.runtime("threshold nodes unavailable").localizedDescription) session.invalidateAndCancel() throw error @@ -1029,138 +932,119 @@ extension TorusUtils { } throw TorusUtilError.runtime("\(methodName) func failed") - } - } // MARK: - keylookup internal func awaitKeyLookup(endpoints: [String], verifier: String, verifierId: String, timeout: Int = 0) async throws -> KeyLookupResponse { - let durationInNanoseconds = UInt64(timeout * 1_000_000_000) + let durationInNanoseconds = UInt64(timeout * 1000000000) try await Task.sleep(nanoseconds: durationInNanoseconds) - do { - return try await keyLookup(endpoints: endpoints, verifier: verifier, verifierId: verifierId) - } catch { - throw error - } + return try await keyLookup(endpoints: endpoints, verifier: verifier, verifierId: verifierId) } - + internal func awaitLegacyKeyLookup(endpoints: [String], verifier: String, verifierId: String, timeout: Int = 0) async throws -> LegacyKeyLookupResponse { - let durationInNanoseconds = UInt64(timeout * 1_000_000_000) + let durationInNanoseconds = UInt64(timeout * 1000000000) try await Task.sleep(nanoseconds: durationInNanoseconds) + return try await legacyKeyLookup(endpoints: endpoints, verifier: verifier, verifierId: verifierId) + } + + internal func legacyKeyLookup(endpoints: [String], verifier: String, verifierId: String) async throws -> LegacyKeyLookupResponse { + // Enode data + let encoder = JSONEncoder() + let session = createURLSession() + let threshold = (endpoints.count / 2) + 1 + var failedLookupCount = 0 + let jsonRPCRequest = JSONRPCrequest( + method: JRPC_METHODS.LEGACY_VERIFIER_LOOKUP_REQUEST, + params: ["verifier": verifier, "verifier_id": verifierId]) + guard let rpcdata = try? encoder.encode(jsonRPCRequest) + else { + throw TorusUtilError.encodingFailed("\(jsonRPCRequest)") + } + var allowHostRequest = try makeUrlRequest(url: allowHost, httpMethod: .get) + allowHostRequest.addValue("torus-default", forHTTPHeaderField: "x-api-key") + allowHostRequest.addValue(verifier, forHTTPHeaderField: "Origin") do { - return try await legacyKeyLookup(endpoints: endpoints, verifier: verifier, verifierId: verifierId) + _ = try await session.data(for: allowHostRequest) } catch { + os_log("KeyLookup: signer allow: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) throw error } - } - - internal func legacyKeyLookup(endpoints: [String], verifier: String, verifierId: String) async throws -> LegacyKeyLookupResponse { - // Enode data - let encoder = JSONEncoder() - let session = createURLSession() - let threshold = (endpoints.count / 2) + 1 - var failedLookupCount = 0 - let jsonRPCRequest = JSONRPCrequest( - method: JRPC_METHODS.LEGACY_VERIFIER_LOOKUP_REQUEST, - params: ["verifier": verifier, "verifier_id": verifierId]) - guard let rpcdata = try? encoder.encode(jsonRPCRequest) - else { - throw TorusUtilError.encodingFailed("\(jsonRPCRequest)") - } - var allowHostRequest = try makeUrlRequest(url: allowHost, httpMethod: .get) - allowHostRequest.addValue("torus-default", forHTTPHeaderField: "x-api-key") - allowHostRequest.addValue(verifier, forHTTPHeaderField: "Origin") - do { - _ = try await session.data(for: allowHostRequest) - } catch { - os_log("KeyLookup: signer allow: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) - throw error - } - // Create Array of URLRequest Promises + // Create Array of URLRequest Promises - var resultArray = [LegacyKeyLookupResponse]() - var requestArray = [URLRequest]() - for endpoint in endpoints { - do { - var request = try makeUrlRequest(url: endpoint) - request.httpBody = rpcdata - requestArray.append(request) - } catch { - throw error - } - } + var resultArray = [LegacyKeyLookupResponse]() + var requestArray = [URLRequest]() + for endpoint in endpoints { + var request = try makeUrlRequest(url: endpoint) + request.httpBody = rpcdata + requestArray.append(request) + } - return try await withThrowingTaskGroup(of: Result.self, body: {[unowned self] group in - for (i, rq) in requestArray.enumerated() { - group.addTask { - do { - let val = try await session.data(for: rq) - return .success(.init(data: val.0, urlResponse: val.1, index: i)) - } catch { - return .failure(error) - } + return try await withThrowingTaskGroup(of: Result.self, body: { [unowned self] group in + for (i, rq) in requestArray.enumerated() { + group.addTask { + do { + let val = try await session.data(for: rq) + return .success(.init(data: val.0, urlResponse: val.1, index: i)) + } catch { + return .failure(error) } } + } - for try await val in group { - do { - switch val { - case .success(let model): - let data = model.data - do { - let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data) // User decoder to covert to struct - os_log("keyLookup: API response: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, "\(decoded)") - - let result = decoded.result - let error = decoded.error - if let _ = error { - let error = KeyLookupError.createErrorFromString(errorString: decoded.error?.data ?? "") - throw error - } else { - guard - let decodedResult = result as? [String: [[String: String]]], - let k = decodedResult["keys"], - let keys = k.first, - let pubKeyX = keys["pub_key_X"], - let pubKeyY = keys["pub_key_Y"], - let keyIndex = keys["key_index"], - let address = keys["address"] - else { - throw TorusUtilError.decodingFailed("keys not found in \(result ?? "")") - } - let model = LegacyKeyLookupResponse(pubKeyX: pubKeyX, pubKeyY: pubKeyY, keyIndex: keyIndex, address: address) - resultArray.append(model) - } - let keyResult = thresholdSame(arr: resultArray, threshold: threshold) // Check if threshold is satisfied + for try await val in group { + do { + switch val { + case let .success(model): + let data = model.data + let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data) // User decoder to covert to struct + os_log("keyLookup: API response: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, "\(decoded)") - if let keyResult = keyResult { - os_log("keyLookup: fulfill: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, keyResult.description) - session.invalidateAndCancel() - return keyResult - } - } catch let err { - throw err - } - case let .failure(error): + let result = decoded.result + let error = decoded.error + if let _ = error { + let error = KeyLookupError.createErrorFromString(errorString: decoded.error?.data ?? "") throw error + } else { + guard + let decodedResult = result as? [String: [[String: String]]], + let k = decodedResult["keys"], + let keys = k.first, + let pubKeyX = keys["pub_key_X"], + let pubKeyY = keys["pub_key_Y"], + let keyIndex = keys["key_index"], + let address = keys["address"] + else { + throw TorusUtilError.decodingFailed("keys not found in \(result ?? "")") + } + let model = LegacyKeyLookupResponse(pubKeyX: pubKeyX, pubKeyY: pubKeyY, keyIndex: keyIndex, address: address) + resultArray.append(model) } - } catch { - failedLookupCount += 1 - os_log("keyLookup: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) - if failedLookupCount > (endpoints.count - threshold) { - os_log("keyLookup: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, TorusUtilError.runtime("threshold nodes unavailable").localizedDescription) + let keyResult = thresholdSame(arr: resultArray, threshold: threshold) // Check if threshold is satisfied + + if let keyResult = keyResult { + os_log("keyLookup: fulfill: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, keyResult.description) session.invalidateAndCancel() - throw error + return keyResult } + case let .failure(error): + throw error + } + } catch { + failedLookupCount += 1 + os_log("keyLookup: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) + if failedLookupCount > (endpoints.count - threshold) { + os_log("keyLookup: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, TorusUtilError.runtime("threshold nodes unavailable").localizedDescription) + session.invalidateAndCancel() + throw error } } - throw TorusUtilError.runtime("keyLookup func failed") - }) - } - + } + throw TorusUtilError.runtime("keyLookup func failed") + }) + } internal func keyLookup(endpoints: [String], verifier: String, verifierId: String) async throws -> KeyLookupResponse { // Enode data @@ -1190,16 +1074,12 @@ extension TorusUtils { var resultArray = [KeyLookupResponse]() var requestArray = [URLRequest]() for endpoint in endpoints { - do { - var request = try makeUrlRequest(url: endpoint) - request.httpBody = rpcdata - requestArray.append(request) - } catch { - throw error - } + var request = try makeUrlRequest(url: endpoint) + request.httpBody = rpcdata + requestArray.append(request) } - return try await withThrowingTaskGroup(of: Result.self, body: {[unowned self] group in + return try await withThrowingTaskGroup(of: Result.self, body: { [unowned self] group in for (i, rq) in requestArray.enumerated() { group.addTask { do { @@ -1214,44 +1094,39 @@ extension TorusUtils { for try await val in group { do { switch val { - case .success(let model): + case let .success(model): let data = model.data - do { - let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data) // User decoder to covert to struct - os_log("keyLookup: API response: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, "\(decoded)") - - // result of decoded data - let result = decoded.result - let error = decoded.error - print("decodedResult", result) - if let _ = error { - let error = KeyLookupError.createErrorFromString(errorString: decoded.error?.data ?? "") - throw error - } else { - guard - let decodedResult = result as? [String: [[String: Any]]], - - let k = decodedResult["keys"], - let keys = k.first, - let pubKeyX = keys["pub_key_X"] as? String, - let pubKeyY = keys["pub_key_Y"] as? String, - let address = keys["address"] as? String - else { - throw TorusUtilError.decodingFailed("keys not found in \(result )") - } - let isNewKey = keys["is_new_key"] as? Bool ?? false - let model = KeyLookupResponse(pubKeyX: pubKeyX, pubKeyY: pubKeyY, address: address, isNewKey: isNewKey) - resultArray.append(model) + let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data) // User decoder to covert to struct + os_log("keyLookup: API response: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, "\(decoded)") + + // result of decoded data + let result = decoded.result + let error = decoded.error + if let _ = error { + let error = KeyLookupError.createErrorFromString(errorString: decoded.error?.data ?? "") + throw error + } else { + guard + let decodedResult = result as? [String: [[String: Any]]], + + let k = decodedResult["keys"], + let keys = k.first, + let pubKeyX = keys["pub_key_X"] as? String, + let pubKeyY = keys["pub_key_Y"] as? String, + let address = keys["address"] as? String + else { + throw TorusUtilError.decodingFailed("key not found") } - let keyResult = thresholdSame(arr: resultArray, threshold: threshold) // Check if threshold is satisfied + let isNewKey = keys["is_new_key"] as? Bool ?? false + let model = KeyLookupResponse(pubKeyX: pubKeyX, pubKeyY: pubKeyY, address: address, isNewKey: isNewKey) + resultArray.append(model) + } + let keyResult = thresholdSame(arr: resultArray, threshold: threshold) // Check if threshold is satisfied - if let keyResult = keyResult { - os_log("keyLookup: fulfill: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, keyResult.description) - session.invalidateAndCancel() - return keyResult - } - } catch let err { - throw err + if let keyResult = keyResult { + os_log("keyLookup: fulfill: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, keyResult.description) + session.invalidateAndCancel() + return keyResult } case let .failure(error): throw error @@ -1259,7 +1134,7 @@ extension TorusUtils { } catch { failedLookupCount += 1 os_log("keyLookup: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) - if failedLookupCount > (endpoints.count - threshold) { + if failedLookupCount > (endpoints.count - threshold) { os_log("keyLookup: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, TorusUtilError.runtime("threshold nodes unavailable").localizedDescription) session.invalidateAndCancel() throw error @@ -1271,7 +1146,7 @@ extension TorusUtils { } // MARK: - key assignment - + internal func keyAssign(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, signerHost: String, network: TorusNetwork, firstPoint: Int? = nil, lastPoint: Int? = nil) async throws -> JSONRPCresponse { var nodeNum: Int = 0 var initialPoint: Int = 0 @@ -1297,104 +1172,94 @@ extension TorusUtils { os_log("newEndpoints2 : %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, endpoints) let SignerObject = JSONRPCrequest(method: JRPC_METHODS.LEGACY_KEY_ASSIGN, params: ["verifier": verifier, "verifier_id": verifierId]) + let rpcdata = try encoder.encode(SignerObject) + var request = try makeUrlRequest(url: signerHost) + request.addValue(torusNodePubs[nodeNum].getX().lowercased(), forHTTPHeaderField: "pubKeyX") + request.addValue(torusNodePubs[nodeNum].getY().lowercased(), forHTTPHeaderField: "pubKeyY") + switch network { + case let .legacy(network): request.addValue(network.path, forHTTPHeaderField: "network") + case let .sapphire(network): request.addValue(network.path, forHTTPHeaderField: "network") + } + + request.httpBody = rpcdata do { - let rpcdata = try encoder.encode(SignerObject) - var request = try! makeUrlRequest(url: signerHost) - request.addValue(torusNodePubs[nodeNum].getX().lowercased(), forHTTPHeaderField: "pubKeyX") - request.addValue(torusNodePubs[nodeNum].getY().lowercased(), forHTTPHeaderField: "pubKeyY") - switch network { - case .legacy(let network ) : request.addValue(network.path, forHTTPHeaderField: "network") - case .sapphire(let network ) : request.addValue(network.path, forHTTPHeaderField: "network") - } - - request.httpBody = rpcdata + let responseFromSignerData: (Data, URLResponse) = try await urlSession.data(for: request) + let decodedSignerResponse = try JSONDecoder().decode(SignerResponse.self, from: responseFromSignerData.0) + os_log("KeyAssign: responseFromSigner: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, "\(decodedSignerResponse)") + let keyassignRequest = KeyAssignRequest(params: ["verifier": verifier, "verifier_id": verifierId], signerResponse: decodedSignerResponse) + // Combine signer respose and request data + encoder.outputFormatting = .sortedKeys + let newData = try encoder.encode(keyassignRequest) + var request2 = try makeUrlRequest(url: endpoints[nodeNum]) + request2.httpBody = newData + let keyAssignRequestData: (Data, URLResponse) = try await urlSession.data(for: request2) do { - let responseFromSignerData: (Data, URLResponse) = try await urlSession.data(for: request) - let decodedSignerResponse = try JSONDecoder().decode(SignerResponse.self, from: responseFromSignerData.0) - os_log("KeyAssign: responseFromSigner: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, "\(decodedSignerResponse)") - let keyassignRequest = KeyAssignRequest(params: ["verifier": verifier, "verifier_id": verifierId], signerResponse: decodedSignerResponse) - // Combine signer respose and request data - encoder.outputFormatting = .sortedKeys - let newData = try encoder.encode(keyassignRequest) - var request2 = try makeUrlRequest(url: endpoints[nodeNum]) - request2.httpBody = newData - let keyAssignRequestData: (Data, URLResponse) = try await urlSession.data(for: request2) - do { - let decodedData = try JSONDecoder().decode(JSONRPCresponse.self, from: keyAssignRequestData.0) // User decoder to covert to struct + let decodedData = try JSONDecoder().decode(JSONRPCresponse.self, from: keyAssignRequestData.0) // User decoder to covert to struct - os_log("keyAssign: fullfill: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, "\(decodedData)") - return decodedData - } catch let err { - throw TorusUtilError.decodingFailed(err.localizedDescription) - } - } catch { - os_log("KeyAssign: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, "\(error)") - return try await keyAssign(endpoints: endpoints, torusNodePubs: torusNodePubs, verifier: verifier, verifierId: verifierId, signerHost: signerHost, network: network, firstPoint: initialPoint, lastPoint: nodeNum + 1) + os_log("keyAssign: fullfill: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, "\(decodedData)") + return decodedData + } catch let err { + throw TorusUtilError.decodingFailed(err.localizedDescription) } - } catch let err { - throw err + } catch { + os_log("KeyAssign: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, "\(error)") + return try await keyAssign(endpoints: endpoints, torusNodePubs: torusNodePubs, verifier: verifier, verifierId: verifierId, signerHost: signerHost, network: network, firstPoint: initialPoint, lastPoint: nodeNum + 1) } } - internal func generateNonceMetadataParams(message: String, privateKey: BigInt, nonce: BigInt?) throws -> NonceMetadataParams { - do { - - let privKeyData = Data(hex: privateKey.serialize().hexString.addLeading0sForLength64() ) - guard let publicKey = SECP256K1.privateToPublic(privateKey: privKeyData)?.subdata(in: 1 ..< 65).toHexString().padLeft(padChar: "0", count: 128) - else { - throw TorusUtilError.runtime("invalid priv key") - } - - let timeStamp = String(BigUInt(serverTimeOffset + Date().timeIntervalSince1970), radix: 16) - var setData: NonceMetadataParams.SetNonceData = .init(data: message, timestamp: timeStamp) - if (nonce != nil) { - setData.data = String(nonce!, radix: 16).addLeading0sForLength64() - } - let encodedData = try JSONEncoder().encode(setData) -// let hash = encodedData.web3.keccak256 - let hash = keccak256Data(encodedData) - guard let sigData = SECP256K1.signForRecovery(hash: hash, privateKey: privKeyData).serializedSignature else { - throw TorusUtilError.runtime("sign for recovery hash failed") - } - let pubKeyX = String(publicKey.prefix(64)) - let pubKeyY = String(publicKey.suffix(64)) - - return .init(pub_key_X: pubKeyX, pub_key_Y: pubKeyY, setData: setData, signature: sigData.base64EncodedString()) - } catch let error { - throw error - } - } - - internal func getPublicKeyPointFromPubkeyString( pubKey: String) throws -> (String, String) { - let publicKeyHashData = Data.fromHex(pubKey.strip04Prefix()) - guard publicKeyHashData?.count == 64 else { - throw "Invalid address," + let privKey = try secp256k1.Signing.PrivateKey(dataRepresentation: Data(hex: privateKey.magnitude.serialize().hexString.addLeading0sForLength64()), format: .uncompressed) + let publicKey = privKey.publicKey.dataRepresentation.hexString + + let timeStamp = String(BigUInt(serverTimeOffset + Date().timeIntervalSince1970), radix: 16) + var setData: NonceMetadataParams.SetNonceData = .init(data: message, timestamp: timeStamp) + if nonce != nil { + setData.data = String(nonce!, radix: 16).addLeading0sForLength64() + } + let encoder = JSONEncoder() + encoder.outputFormatting = .sortedKeys + let encodedData = try JSONEncoder() + .encode(setData) + let hash = keccak256Data(encodedData) + guard let sigData = secp256k1.signForRecovery(hash: hash, privateKey: privKey.dataRepresentation).serializedSignature + else { + throw TorusUtilError.runtime("sign for recovery hash failed") } - - let xCoordinateData = publicKeyHashData?.prefix(32).toHexString() - let yCoordinateData = publicKeyHashData?.suffix(32).toHexString() - - if let x = xCoordinateData, let y = yCoordinateData { - return (x, y) - }else { - throw "invalid address" + + return .init(pub_key_X: String(publicKey.suffix(128).prefix(64)), pub_key_Y: String(publicKey.suffix(64)), setData: setData, signature: sigData.base64EncodedString()) + } + + internal func getPublicKeyPointFromPubkeyString(pubKey: String) throws -> (String, String) { + let publicKeyHashData = Data(hex: pubKey.strip04Prefix()) + if !(publicKeyHashData.count == 64) { + throw "Invalid address," } + + let xCoordinateData = publicKeyHashData.prefix(32).toHexString() + let yCoordinateData = publicKeyHashData.suffix(32).toHexString() + + return (xCoordinateData, yCoordinateData) } - - internal func combinePublicKeys(keys: [String], compressed: Bool) -> String { - let data = keys.map({ Data.fromHex($0)! }) - let added = SECP256K1.combineSerializedPublicKeys(keys: data, outputCompressed: compressed) - return (added?.toHexString())! + + internal func combinePublicKeys(keys: [String], compressed: Bool) throws -> String { + let data = keys.map({ let key = Data(hex: $0) + return key + }) + let added = secp256k1.combineSerializedPublicKeys(keys: data, outputCompressed: compressed) + guard let result = added?.toHexString() + else { + throw TorusUtilError.runtime("Invalid public key after combining") + } + return result } - - internal func formatLegacyPublicData(finalKeyResult: KeyLookupResponse,enableOneKey: Bool, isNewKey: Bool) async throws -> TorusPublicKey { + + internal func formatLegacyPublicData(finalKeyResult: KeyLookupResponse, enableOneKey: Bool, isNewKey: Bool) async throws -> TorusPublicKey { var finalPubKey: String = "" var nonce: BigUInt = 0 var typeOfUser: TypeOfUser = .v1 var pubNonce: PubNonce? var result: TorusPublicKey - var nonceResult : GetOrSetNonceResult? + var nonceResult: GetOrSetNonceResult? let pubKeyX = finalKeyResult.pubKeyX let pubKeyY = finalKeyResult.pubKeyY let (oAuthX, oAuthY) = (pubKeyX.addLeading0sForLength64(), pubKeyY.addLeading0sForLength64()) @@ -1403,24 +1268,23 @@ extension TorusUtils { nonce = BigUInt(nonceResult?.nonce ?? "0") ?? 0 typeOfUser = .init(rawValue: nonceResult?.typeOfUser ?? ".v1") ?? .v1 if typeOfUser == .v1 { - finalPubKey = "04" + pubKeyX.addLeading0sForLength64() + pubKeyY.addLeading0sForLength64() + finalPubKey = (pubKeyX.addLeading0sForLength64() + pubKeyY.addLeading0sForLength64()).add04Prefix() if nonce != BigInt(0) { - guard let noncePublicKey = SECP256K1.privateToPublic(privateKey: BigUInt(nonce).serialize().addLeading0sForLength64()) else { - throw TorusUtilError.decryptionFailed - } - finalPubKey = combinePublicKeys(keys: [finalPubKey, noncePublicKey.toHexString()], compressed: false) + let noncePrivateKey = try secp256k1.KeyAgreement.PrivateKey(dataRepresentation: BigUInt(nonce).magnitude.serialize().addLeading0sForLength64(), format: .uncompressed) + let noncePublicKey = noncePrivateKey.publicKey.dataRepresentation + finalPubKey = try combinePublicKeys(keys: [finalPubKey, noncePublicKey.hexString], compressed: false) } else { - finalPubKey = String(finalPubKey.suffix(128)) + finalPubKey = String(finalPubKey) } } else if typeOfUser == .v2 { pubNonce = nonceResult?.pubNonce if nonceResult?.upgraded ?? false { - finalPubKey = "04" + pubKeyX.addLeading0sForLength64() + pubKeyY.addLeading0sForLength64() + finalPubKey = (pubKeyX.addLeading0sForLength64() + pubKeyY.addLeading0sForLength64()).add04Prefix() } else { guard nonceResult?.pubNonce != nil else { throw TorusUtilError.decodingFailed("No pub nonce found") } - finalPubKey = "04" + pubKeyX.addLeading0sForLength64() + pubKeyY.addLeading0sForLength64() - let ecpubKeys = "04" + (nonceResult?.pubNonce!.x.addLeading0sForLength64())! + (nonceResult?.pubNonce!.y.addLeading0sForLength64())! - finalPubKey = combinePublicKeys(keys: [finalPubKey, ecpubKeys], compressed: false) + finalPubKey = (pubKeyX.addLeading0sForLength64() + pubKeyY.addLeading0sForLength64()).add04Prefix() + let ecpubKeys = ((nonceResult?.pubNonce!.x.addLeading0sForLength64())! + (nonceResult?.pubNonce!.y.addLeading0sForLength64())!).add04Prefix() + finalPubKey = try combinePublicKeys(keys: [finalPubKey, ecpubKeys], compressed: false) } finalPubKey = String(finalPubKey.suffix(128)) } else { @@ -1432,29 +1296,28 @@ extension TorusUtils { nonce = localNonce let localPubkeyX = finalKeyResult.pubKeyX let localPubkeyY = finalKeyResult.pubKeyY - finalPubKey = "04" + localPubkeyX.addLeading0sForLength64() + localPubkeyY.addLeading0sForLength64() + finalPubKey = (localPubkeyX.addLeading0sForLength64() + localPubkeyY.addLeading0sForLength64()).add04Prefix() if localNonce != BigInt(0) { let nonce2 = BigInt(localNonce) - guard let noncePublicKey = SECP256K1.privateToPublic(privateKey: BigUInt(nonce2).serialize().addLeading0sForLength64()) else { - throw TorusUtilError.decryptionFailed - } - finalPubKey = combinePublicKeys(keys: [finalPubKey, noncePublicKey.toHexString()], compressed: false) + let noncePrivateKey = try secp256k1.KeyAgreement.PrivateKey(dataRepresentation: BigUInt(nonce2).magnitude.serialize().addLeading0sForLength64(), format: .uncompressed) + let noncePublicKey = noncePrivateKey.publicKey.dataRepresentation + finalPubKey = try combinePublicKeys(keys: [finalPubKey, noncePublicKey.hexString], compressed: false) } else { - finalPubKey = String(finalPubKey.suffix(128)) + finalPubKey = String(finalPubKey) } } - let finalX = String(finalPubKey.prefix(64)) + let finalX = String(finalPubKey.suffix(128).prefix(64)) let finalY = String(finalPubKey.suffix(64)) let oAuthAddress = generateAddressFromPubKey(publicKeyX: oAuthX, publicKeyY: oAuthY) let finalAddress = generateAddressFromPubKey(publicKeyX: finalX, publicKeyY: finalY) var usertype = "" - switch typeOfUser{ - case .v1: - usertype = "v1" - case .v2: - usertype = "v2" + switch typeOfUser { + case .v1: + usertype = "v1" + case .v2: + usertype = "v2" } result = TorusPublicKey( @@ -1478,19 +1341,18 @@ extension TorusUtils { ) return result } - + internal func tupleToArray(_ tuple: Any) -> [UInt8] { - // var result = [UInt8]() let tupleMirror = Mirror(reflecting: tuple) let tupleElements = tupleMirror.children.map({ $0.value as! UInt8 }) return tupleElements } public func decrypt(privateKey: String, opts: ECIES, padding: Padding = .pkcs7) throws -> Data { - let sharedSecret = try SECP256K1.ecdhWithHex(pubKeyHex: opts.ephemPublicKey, privateKeyHex: privateKey) - - let aesKey = sharedSecret[0..<32].bytes - let _aesMac = sharedSecret[32..<64].bytes // TODO check mac + let sharedSecret = try secp256k1.ecdhWithHex(pubKeyHex: opts.ephemPublicKey, privateKeyHex: privateKey) + + let aesKey = sharedSecret[0 ..< 32].bytes + _ = sharedSecret[32 ..< 64].bytes // TODO: check mac let iv = opts.iv.hexa let aes = try AES(key: aesKey, blockMode: CBC(iv: iv), padding: padding) @@ -1498,13 +1360,12 @@ extension TorusUtils { let data = Data(plaintext) return data } - } extension Array where Element == UInt8 { func uint8Reverse() -> Array { var revArr = [Element]() - for arrayIndex in stride(from: self.count - 1, through: 0, by: -1) { + for arrayIndex in stride(from: count - 1, through: 0, by: -1) { revArr.append(self[arrayIndex]) } return revArr diff --git a/Sources/TorusUtils/Extensions/URLSessionExtension.swift b/Sources/TorusUtils/Extensions/URLSessionExtension.swift deleted file mode 100644 index 87ace02e..00000000 --- a/Sources/TorusUtils/Extensions/URLSessionExtension.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// File.swift -// -// -// Created by Dhruv Jaiswal on 17/11/22. -// - -import Foundation -/* -Fix for the issue - https://www.swiftbysundell.com/articles/making-async-system-apis-backward-compatible/ -*/ - -@available(iOS, deprecated: 15.0, message: "Use the built-in API instead") -extension URLSession { - func data(for request: URLRequest, delegate: URLSessionTaskDelegate? = nil) async throws -> (Data, URLResponse) { - try await withCheckedThrowingContinuation { continuation in - let task = self.dataTask(with: request) { data, response, error in - guard let data = data, let response = response else { - let error = error ?? URLError(.badServerResponse) - return continuation.resume(throwing: error) - } - - continuation.resume(returning: (data, response)) - } - - task.resume() - } - } -} diff --git a/Sources/TorusUtils/Convenience/SECP256k1.swift b/Sources/TorusUtils/Extensions/secp256k1+Extension.swift old mode 100755 new mode 100644 similarity index 68% rename from Sources/TorusUtils/Convenience/SECP256k1.swift rename to Sources/TorusUtils/Extensions/secp256k1+Extension.swift index cda919ca..faea89bb --- a/Sources/TorusUtils/Convenience/SECP256k1.swift +++ b/Sources/TorusUtils/Extensions/secp256k1+Extension.swift @@ -1,138 +1,38 @@ import Foundation - #if canImport(secp256k1) import secp256k1 #endif -public struct SECP256K1 { - public struct UnmarshaledSignature { - public var v: UInt8 = 0 - public var r = Data(repeating: 0, count: 32) - public var s = Data(repeating: 0, count: 32) - - public init(v: UInt8, r: Data, s: Data) { - self.v = v - self.r = r - self.s = s - } - } -} - -extension SECP256K1 { - static let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) - +extension secp256k1 { public static func ecdh(publicKey: secp256k1.KeyAgreement.PublicKey, privateKey: secp256k1.KeyAgreement.PrivateKey) throws -> [UInt8] { - let copyx : secp256k1.KeyAgreement.PrivateKey.HashFunctionType = { - (out, x, y, data) -> Int32 in + let copyx: secp256k1.KeyAgreement.PrivateKey.HashFunctionType = { + out, x, _, _ -> Int32 in guard let out = out, let x = x else { - return 0; + return 0 } out.initialize(from: x, count: 32) return 1 } - - let sharedSecret = try! privateKey.sharedSecretFromKeyAgreement(with: publicKey, handler: copyx) + + let sharedSecret = try privateKey.sharedSecretFromKeyAgreement(with: publicKey, handler: copyx) let hash = sharedSecret.bytes.sha512() - + return hash } - + public static func ecdhWithHex(pubKeyHex: String, privateKeyHex: String) throws -> [UInt8] { let privateKeyBytes = try privateKeyHex.bytes let privateKey = try secp256k1.KeyAgreement.PrivateKey(dataRepresentation: privateKeyBytes) - + let publicKeyBytes = try pubKeyHex.bytes let publicKey = try secp256k1.KeyAgreement.PublicKey(dataRepresentation: publicKeyBytes, format: .uncompressed) - + let sharedSecret = try ecdh(publicKey: publicKey, privateKey: privateKey) return sharedSecret } - public static func signForRecovery(hash: Data, privateKey: Data, useExtraEntropy: Bool = false) -> (serializedSignature: Data?, rawSignature: Data?) { - if hash.count != 32 || privateKey.count != 32 { - return (nil, nil) } - if !SECP256K1.verifyPrivateKey(privateKey: privateKey) { - return (nil, nil) - } - for _ in 0 ... 1024 { - guard var recoverableSignature = SECP256K1.recoverableSign(hash: hash, privateKey: privateKey, useExtraEntropy: useExtraEntropy) else { - continue - } - guard let truePublicKey = SECP256K1.privateKeyToPublicKey(privateKey: privateKey) else { continue } - guard let recoveredPublicKey = SECP256K1.recoverPublicKey(hash: hash, recoverableSignature: &recoverableSignature) else { continue } - if !SECP256K1.constantTimeComparison(Data(toByteArray(truePublicKey.data)), Data(toByteArray(recoveredPublicKey.data))) { - continue - } - guard let serializedSignature = SECP256K1.serializeSignature(recoverableSignature: &recoverableSignature) else { continue } - let rawSignature = Data(toByteArray(recoverableSignature)) - return (serializedSignature, rawSignature) - } - return (nil, nil) - } - - public static func privateToPublic(privateKey: Data, compressed: Bool = false) -> Data? { - if privateKey.count != 32 { return nil } - guard var publicKey = SECP256K1.privateKeyToPublicKey(privateKey: privateKey) else { return nil } - guard let serializedKey = serializePublicKey(publicKey: &publicKey, compressed: compressed) else { return nil } - return serializedKey - } - - public static func combineSerializedPublicKeys(keys: [Data], outputCompressed: Bool = false) -> Data? { - let numToCombine = keys.count - guard numToCombine >= 1 else { return nil } - var storage = ContiguousArray() - let arrayOfPointers = UnsafeMutablePointer?>.allocate(capacity: numToCombine) - defer { - arrayOfPointers.deinitialize(count: numToCombine) - arrayOfPointers.deallocate() - } - for i in 0 ..< numToCombine { - let key = keys[i] - guard let pubkey = SECP256K1.parsePublicKey(serializedKey: key) else { return nil } - storage.append(pubkey) - } - for i in 0 ..< numToCombine { - withUnsafePointer(to: &storage[i]) { (ptr) -> Void in - arrayOfPointers.advanced(by: i).pointee = ptr - } - } - let immutablePointer = UnsafePointer(arrayOfPointers) - var publicKey: secp256k1_pubkey = secp256k1_pubkey() - let result = withUnsafeMutablePointer(to: &publicKey) { (pubKeyPtr: UnsafeMutablePointer) -> Int32 in - let res = secp256k1_ec_pubkey_combine(context!, pubKeyPtr, immutablePointer, numToCombine) - return res - } - if result == 0 { - return nil - } - let serializedKey = SECP256K1.serializePublicKey(publicKey: &publicKey, compressed: outputCompressed) - return serializedKey - } - - internal static func recoverPublicKey(hash: Data, recoverableSignature: inout secp256k1_ecdsa_recoverable_signature) -> secp256k1_pubkey? { - guard hash.count == 32 else { return nil } - var publicKey: secp256k1_pubkey = secp256k1_pubkey() - let result = hash.withUnsafeBytes({ (hashRawBufferPointer: UnsafeRawBufferPointer) -> Int32? in - if let hashRawPointer = hashRawBufferPointer.baseAddress, hashRawBufferPointer.count > 0 { - let hashPointer = hashRawPointer.assumingMemoryBound(to: UInt8.self) - return withUnsafePointer(to: &recoverableSignature, { (signaturePointer: UnsafePointer) -> Int32 in - withUnsafeMutablePointer(to: &publicKey, { (pubKeyPtr: UnsafeMutablePointer) -> Int32 in - let res = secp256k1_ecdsa_recover(context!, pubKeyPtr, - signaturePointer, hashPointer) - return res - }) - }) - } else { - return nil - } - }) - guard let res = result, res != 0 else { - return nil - } - return publicKey - } - - internal static func privateKeyToPublicKey(privateKey: Data) -> secp256k1_pubkey? { + private static func privateKeyToPublicKey(privateKey: Data) -> secp256k1_pubkey? { + let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) if privateKey.count != 32 { return nil } var publicKey = secp256k1_pubkey() let result = privateKey.withUnsafeBytes { (pkRawBufferPointer: UnsafeRawBufferPointer) -> Int32? in @@ -152,51 +52,58 @@ extension SECP256K1 { return publicKey } - public static func serializePublicKey(publicKey: inout secp256k1_pubkey, compressed: Bool = false) -> Data? { - var keyLength = compressed ? 33 : 65 - var serializedPubkey = Data(repeating: 0x00, count: keyLength) - let result = serializedPubkey.withUnsafeMutableBytes { (serializedPubkeyRawBuffPointer) -> Int32? in - if let serializedPkRawPointer = serializedPubkeyRawBuffPointer.baseAddress, serializedPubkeyRawBuffPointer.count > 0 { - let serializedPubkeyPointer = serializedPkRawPointer.assumingMemoryBound(to: UInt8.self) - return withUnsafeMutablePointer(to: &keyLength, { (keyPtr: UnsafeMutablePointer) -> Int32 in - withUnsafeMutablePointer(to: &publicKey, { (pubKeyPtr: UnsafeMutablePointer) -> Int32 in - let res = secp256k1_ec_pubkey_serialize(context!, - serializedPubkeyPointer, - keyPtr, - pubKeyPtr, - UInt32(compressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED)) - return res - }) - }) + // TODO: Translate below functions to secp256k1 objects and methods. + + private static func constantTimeComparison(_ lhs: Data, _ rhs: Data) -> Bool { + guard lhs.count == rhs.count else { return false } + var difference = UInt8(0x00) + for i in 0 ..< lhs.count { // compare full length + difference |= lhs[i] ^ rhs[i] // constant time + } + return difference == UInt8(0x00) + } + + private static func toByteArray(_ value: T) -> [UInt8] { + var value = value + return withUnsafeBytes(of: &value) { Array($0) } + } + + public static func verifyPrivateKey(privateKey: Data) -> Bool { + let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) + if privateKey.count != 32 { return false } + let result = privateKey.withUnsafeBytes { privateKeyRBPointer -> Int32? in + if let privateKeyRPointer = privateKeyRBPointer.baseAddress, privateKeyRBPointer.count > 0 { + let privateKeyPointer = privateKeyRPointer.assumingMemoryBound(to: UInt8.self) + let res = secp256k1_ec_seckey_verify(context!, privateKeyPointer) + return res } else { return nil } } - guard let res = result, res != 0 else { - return nil + guard let res = result, res == 1 else { + return false } - return Data(serializedPubkey) + return true } - internal static func parsePublicKey(serializedKey: Data) -> secp256k1_pubkey? { - guard serializedKey.count == 33 || serializedKey.count == 65 else { - return nil - } - let keyLen: Int = Int(serializedKey.count) - var publicKey = secp256k1_pubkey() - let result = serializedKey.withUnsafeBytes { (serializedKeyRawBufferPointer: UnsafeRawBufferPointer) -> Int32? in - if let serializedKeyRawPointer = serializedKeyRawBufferPointer.baseAddress, serializedKeyRawBufferPointer.count > 0 { - let serializedKeyPointer = serializedKeyRawPointer.assumingMemoryBound(to: UInt8.self) - - let res = withUnsafeMutablePointer(to: &publicKey) { - secp256k1_ec_pubkey_parse(context!, $0, serializedKeyPointer, keyLen) - } - - return res + private static func recoverPublicKey(hash: Data, recoverableSignature: inout secp256k1_ecdsa_recoverable_signature) -> secp256k1_pubkey? { + let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) + guard hash.count == 32 else { return nil } + var publicKey: secp256k1_pubkey = secp256k1_pubkey() + let result = hash.withUnsafeBytes({ (hashRawBufferPointer: UnsafeRawBufferPointer) -> Int32? in + if let hashRawPointer = hashRawBufferPointer.baseAddress, hashRawBufferPointer.count > 0 { + let hashPointer = hashRawPointer.assumingMemoryBound(to: UInt8.self) + return withUnsafePointer(to: &recoverableSignature, { (signaturePointer: UnsafePointer) -> Int32 in + withUnsafeMutablePointer(to: &publicKey, { (pubKeyPtr: UnsafeMutablePointer) -> Int32 in + let res = secp256k1_ecdsa_recover(context!, pubKeyPtr, + signaturePointer, hashPointer) + return res + }) + }) } else { return nil } - } + }) guard let res = result, res != 0 else { return nil } @@ -204,6 +111,7 @@ extension SECP256K1 { } public static func parseSignature(signature: Data) -> secp256k1_ecdsa_recoverable_signature? { + let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) guard signature.count == 65 else { return nil } var recoverableSignature: secp256k1_ecdsa_recoverable_signature = secp256k1_ecdsa_recoverable_signature() let serializedSignature = Data(signature[0 ..< 64]) @@ -232,7 +140,8 @@ extension SECP256K1 { return recoverableSignature } - internal static func serializeSignature(recoverableSignature: inout secp256k1_ecdsa_recoverable_signature) -> Data? { + private static func serializeSignature(recoverableSignature: inout secp256k1_ecdsa_recoverable_signature) -> Data? { + let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) var serializedSignature = Data(repeating: 0x00, count: 64) var v: Int32 = 0 let result = serializedSignature.withUnsafeMutableBytes { (serSignatureRawBufferPointer: UnsafeMutableRawBufferPointer) -> Int32? in @@ -261,22 +170,51 @@ extension SECP256K1 { return Data(serializedSignature) } - internal static func recoverableSign(hash: Data, privateKey: Data, useExtraEntropy: Bool = false) -> secp256k1_ecdsa_recoverable_signature? { + public static func recoverPublicKey(hash: Data, signature: Data, compressed: Bool = false) -> Data? { + guard hash.count == 32, signature.count == 65 else { return nil } + guard var recoverableSignature = parseSignature(signature: signature) else { return nil } + guard var publicKey = recoverPublicKey(hash: hash, recoverableSignature: &recoverableSignature) else { return nil } + guard let serializedKey = serializePublicKey(publicKey: &publicKey, compressed: compressed) else { return nil } + return serializedKey + } + + private static func randomBytes(length: Int) -> Data? { + for _ in 0 ... 1024 { + var data = Data(repeating: 0, count: length) + let result = data.withUnsafeMutableBytes { mutableRBBytes -> Int32? in + if let mutableRBytes = mutableRBBytes.baseAddress, mutableRBBytes.count > 0 { + let mutableBytes = mutableRBytes.assumingMemoryBound(to: UInt8.self) + return SecRandomCopyBytes(kSecRandomDefault, 32, mutableBytes) + } else { + return nil + } + } + if let res = result, res == errSecSuccess { + return data + } else { + continue + } + } + return nil + } + + private static func recoverableSign(hash: Data, privateKey: Data, useExtraEntropy: Bool = false) -> secp256k1_ecdsa_recoverable_signature? { + let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) if hash.count != 32 || privateKey.count != 32 { return nil } - if !SECP256K1.verifyPrivateKey(privateKey: privateKey) { + if !verifyPrivateKey(privateKey: privateKey) { return nil } var recoverableSignature: secp256k1_ecdsa_recoverable_signature = secp256k1_ecdsa_recoverable_signature() - guard let extraEntropy = SECP256K1.randomBytes(length: 32) else { return nil } - let result = hash.withUnsafeBytes { (hashRBPointer) -> Int32? in + guard let extraEntropy = randomBytes(length: 32) else { return nil } + let result = hash.withUnsafeBytes { hashRBPointer -> Int32? in if let hashRPointer = hashRBPointer.baseAddress, hashRBPointer.count > 0 { let hashPointer = hashRPointer.assumingMemoryBound(to: UInt8.self) - return privateKey.withUnsafeBytes({ (privateKeyRBPointer) -> Int32? in + return privateKey.withUnsafeBytes({ privateKeyRBPointer -> Int32? in if let privateKeyRPointer = privateKeyRBPointer.baseAddress, privateKeyRBPointer.count > 0 { let privateKeyPointer = privateKeyRPointer.assumingMemoryBound(to: UInt8.self) - return extraEntropy.withUnsafeBytes({ (extraEntropyRBPointer) -> Int32? in + return extraEntropy.withUnsafeBytes({ extraEntropyRBPointer -> Int32? in if let extraEntropyRPointer = extraEntropyRBPointer.baseAddress, extraEntropyRBPointer.count > 0 { let extraEntropyPointer = extraEntropyRPointer.assumingMemoryBound(to: UInt8.self) return withUnsafeMutablePointer(to: &recoverableSignature, { (recSignaturePtr: UnsafeMutablePointer) -> Int32 in @@ -302,132 +240,112 @@ extension SECP256K1 { return recoverableSignature } - public static func recoverPublicKey(hash: Data, signature: Data, compressed: Bool = false) -> Data? { - guard hash.count == 32, signature.count == 65 else { return nil } - guard var recoverableSignature = parseSignature(signature: signature) else { return nil } - guard var publicKey = SECP256K1.recoverPublicKey(hash: hash, recoverableSignature: &recoverableSignature) else { return nil } - guard let serializedKey = SECP256K1.serializePublicKey(publicKey: &publicKey, compressed: compressed) else { return nil } - return serializedKey - } - - public static func verifyPrivateKey(privateKey: Data) -> Bool { - if privateKey.count != 32 { return false } - let result = privateKey.withUnsafeBytes { (privateKeyRBPointer) -> Int32? in - if let privateKeyRPointer = privateKeyRBPointer.baseAddress, privateKeyRBPointer.count > 0 { - let privateKeyPointer = privateKeyRPointer.assumingMemoryBound(to: UInt8.self) - let res = secp256k1_ec_seckey_verify(context!, privateKeyPointer) - return res - } else { - return nil - } + public static func signForRecovery(hash: Data, privateKey: Data, useExtraEntropy: Bool = false) -> (serializedSignature: Data?, rawSignature: Data?) { + if hash.count != 32 || privateKey.count != 32 { + return (nil, nil) } - guard let res = result, res == 1 else { - return false + if !verifyPrivateKey(privateKey: privateKey) { + return (nil, nil) } - return true - } - - public static func generatePrivateKey() -> Data? { for _ in 0 ... 1024 { - guard let keyData = SECP256K1.randomBytes(length: 32) else { + guard var recoverableSignature = recoverableSign(hash: hash, privateKey: privateKey, useExtraEntropy: useExtraEntropy) else { continue } - guard SECP256K1.verifyPrivateKey(privateKey: keyData) else { + guard let truePublicKey = privateKeyToPublicKey(privateKey: privateKey) else { continue } + guard let recoveredPublicKey = recoverPublicKey(hash: hash, recoverableSignature: &recoverableSignature) else { continue } + if !constantTimeComparison(Data(toByteArray(truePublicKey.data)), Data(toByteArray(recoveredPublicKey.data))) { continue } - return keyData + guard let serializedSignature = serializeSignature(recoverableSignature: &recoverableSignature) else { continue } + let rawSignature = Data(toByteArray(recoverableSignature)) + return (serializedSignature, rawSignature) } - return nil - } - - public static func unmarshalSignature(signatureData: Data) -> UnmarshaledSignature? { - if signatureData.count != 65 { return nil } - let v = signatureData[64] - let r = Data(signatureData[0 ..< 32]) - let s = Data(signatureData[32 ..< 64]) - return UnmarshaledSignature(v: v, r: r, s: s) - } - - public static func marshalSignature(v: UInt8, r: [UInt8], s: [UInt8]) -> Data? { - guard r.count == 32, s.count == 32 else { return nil } - var completeSignature = Data(r) - completeSignature.append(Data(s)) - completeSignature.append(Data([v])) - return completeSignature + return (nil, nil) } - public static func marshalSignature(v: Data, r: Data, s: Data) -> Data? { - guard r.count == 32, s.count == 32 else { return nil } - var completeSignature = Data(r) - completeSignature.append(s) - completeSignature.append(v) - return completeSignature - } + private static func parsePublicKey(serializedKey: Data) -> secp256k1_pubkey? { + let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) + guard serializedKey.count == 33 || serializedKey.count == 65 else { + return nil + } + let keyLen: Int = Int(serializedKey.count) + var publicKey = secp256k1_pubkey() + let result = serializedKey.withUnsafeBytes { (serializedKeyRawBufferPointer: UnsafeRawBufferPointer) -> Int32? in + if let serializedKeyRawPointer = serializedKeyRawBufferPointer.baseAddress, serializedKeyRawBufferPointer.count > 0 { + let serializedKeyPointer = serializedKeyRawPointer.assumingMemoryBound(to: UInt8.self) - internal static func randomBytes(length: Int) -> Data? { - for _ in 0 ... 1024 { - var data = Data(repeating: 0, count: length) - let result = data.withUnsafeMutableBytes { (mutableRBBytes) -> Int32? in - if let mutableRBytes = mutableRBBytes.baseAddress, mutableRBBytes.count > 0 { - let mutableBytes = mutableRBytes.assumingMemoryBound(to: UInt8.self) - return SecRandomCopyBytes(kSecRandomDefault, 32, mutableBytes) - } else { - return nil + let res = withUnsafeMutablePointer(to: &publicKey) { + secp256k1_ec_pubkey_parse(context!, $0, serializedKeyPointer, keyLen) } - } - if let res = result, res == errSecSuccess { - return data + + return res } else { - continue + return nil } } - return nil - } - - internal static func toByteArray(_ value: T) -> [UInt8] { - var value = value - return withUnsafeBytes(of: &value) { Array($0) } + guard let res = result, res != 0 else { + return nil + } + return publicKey } - internal static func fromByteArray(_ value: [UInt8], _: T.Type) -> T { - return value.withUnsafeBytes { - $0.baseAddress!.load(as: T.self) + public static func serializePublicKey(publicKey: inout secp256k1_pubkey, compressed: Bool = false) -> Data? { + let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) + var keyLength = compressed ? 33 : 65 + var serializedPubkey = Data(repeating: 0x00, count: keyLength) + let result = serializedPubkey.withUnsafeMutableBytes { serializedPubkeyRawBuffPointer -> Int32? in + if let serializedPkRawPointer = serializedPubkeyRawBuffPointer.baseAddress, serializedPubkeyRawBuffPointer.count > 0 { + let serializedPubkeyPointer = serializedPkRawPointer.assumingMemoryBound(to: UInt8.self) + return withUnsafeMutablePointer(to: &keyLength, { (keyPtr: UnsafeMutablePointer) -> Int32 in + withUnsafeMutablePointer(to: &publicKey, { (pubKeyPtr: UnsafeMutablePointer) -> Int32 in + let res = secp256k1_ec_pubkey_serialize(context!, + serializedPubkeyPointer, + keyPtr, + pubKeyPtr, + UInt32(compressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED)) + return res + }) + }) + } else { + return nil + } } + guard let res = result, res != 0 else { + return nil + } + return Data(serializedPubkey) } - internal static func constantTimeComparison(_ lhs: Data, _ rhs: Data) -> Bool { - guard lhs.count == rhs.count else { return false } - var difference = UInt8(0x00) - for i in 0 ..< lhs.count { // compare full length - difference |= lhs[i] ^ rhs[i] // constant time + public static func combineSerializedPublicKeys(keys: [Data], outputCompressed: Bool = false) -> Data? { + let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) + let numToCombine = keys.count + guard numToCombine >= 1 else { return nil } + var storage = ContiguousArray() + let arrayOfPointers = UnsafeMutablePointer?>.allocate(capacity: numToCombine) + defer { + arrayOfPointers.deinitialize(count: numToCombine) + arrayOfPointers.deallocate() } - return difference == UInt8(0x00) + for i in 0 ..< numToCombine { + let key = keys[i] + guard let pubkey = parsePublicKey(serializedKey: key) else { return nil } + storage.append(pubkey) + } + for i in 0 ..< numToCombine { + withUnsafePointer(to: &storage[i]) { ptr in + arrayOfPointers.advanced(by: i).pointee = ptr + } + } + let immutablePointer = UnsafePointer(arrayOfPointers) + var publicKey: secp256k1_pubkey = secp256k1_pubkey() + let result = withUnsafeMutablePointer(to: &publicKey) { (pubKeyPtr: UnsafeMutablePointer) -> Int32 in + let res = secp256k1_ec_pubkey_combine(context!, pubKeyPtr, immutablePointer, numToCombine) + return res + } + if result == 0 { + return nil + } + let serializedKey = serializePublicKey(publicKey: &publicKey, compressed: outputCompressed) + return serializedKey } - - - -// -// // MARK: - ECDH - Elliptic curve diffie-hellman -// -// public static func ecdh(pubKey: secp256k1_pubkey, privateKey: Data) -> secp256k1_pubkey? { -// var localPubkey = pubKey // Pointer takes a variable -// if privateKey.count != 32 { return nil } -// let result = privateKey.withUnsafeBytes { (a: UnsafeRawBufferPointer) -> Int32? in -// if let pkRawPointer = a.baseAddress, let ctx = context, a.count > 0 { -// let privateKeyPointer = pkRawPointer.assumingMemoryBound(to: UInt8.self) -// let res = withUnsafeMutablePointer(to: &localPubkey) { -// secp256k1_ec_pubkey_tweak_mul(ctx, $0, privateKeyPointer) -// } -// return res -// } else { -// return nil -// } -// } -// guard let res = result, res != 0 else { -// return nil -// } -// return localPubkey -// } - - } diff --git a/Sources/TorusUtils/Helpers/Common.swift b/Sources/TorusUtils/Helpers/Common.swift index 638ea421..5e872761 100644 --- a/Sources/TorusUtils/Helpers/Common.swift +++ b/Sources/TorusUtils/Helpers/Common.swift @@ -1,94 +1,14 @@ +import BigInt import Foundation -import CryptoKit - -func normalizeKeysResult(keyArr: [VerifierLookupResponse.Key]) -> VerifierLookupResponse { - var finalResult: VerifierLookupResponse = VerifierLookupResponse(keys: [], is_new_key: false, node_index: "0") - - if (!keyArr.isEmpty) { - finalResult.keys = keyArr.map { key in - return VerifierLookupResponse.Key(pub_key_X: key.pub_key_X, pub_key_Y: key.pub_key_Y, address: key.address) - } - } - return finalResult -} - -func kCombinations(s: Any, k: Int) -> [[Int]] { - var set: [Int] - if let number = s as? Int { - set = Array(0.. set.count || k <= 0 { - return [] - } - - if k == set.count { - return [set] - } - - if k == 1 { - return set.map { [$0] } - } - - var combs: [[Int]] = [] - var tailCombs: [[Int]] = [] - - for i in 0...set.count - k { - tailCombs = kCombinations(s: Array(set[(i + 1)...]), k: k - 1) - for j in 0..(arr: [T], t: Int) -> T? { - var hashMap: [String: Int] = [:] - for element in arr { - let str = "\(element)" - hashMap[str] = (hashMap[str] ?? 0) + 1 - if hashMap[str] == t { - return element - } - } - return nil -} - -func encParamsBufToHex(encParams: Ecies) -> EciesHex { - let ivString = encParams.iv - let ephemPublicKeyString = encParams.ephemPublicKey - let ciphertextString = encParams.ciphertext - let macString = encParams.mac - - return EciesHex(iv: ivString, - ephemPublicKey: ephemPublicKeyString, - ciphertext: ciphertextString, - mac: macString, - mode: "AES256") +func keccak256Data(_ data: Data) -> Data { + return data.sha3(.keccak256) } - -func encParamsHexToBuf(eciesData: EciesHexOmitCiphertext) -> EciesOmitCiphertext { - return EciesOmitCiphertext(iv: eciesData.iv, - ephemPublicKey: eciesData.ephemPublicKey, - mac: eciesData.mac) -} - - - -extension Data { - var hexString: String { - return map { String(format: "%02x", $0) }.joined() - } -} - - -func array32toTuple(_ arr: [UInt8]) -> (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) { - return (arr[0] as UInt8, arr[1] as UInt8, arr[2] as UInt8, arr[3] as UInt8, arr[4] as UInt8, arr[5] as UInt8, arr[6] as UInt8, arr[7] as UInt8, arr[8] as UInt8, arr[9] as UInt8, arr[10] as UInt8, arr[11] as UInt8, arr[12] as UInt8, arr[13] as UInt8, arr[14] as UInt8, arr[15] as UInt8, arr[16] as UInt8, arr[17] as UInt8, arr[18] as UInt8, arr[19] as UInt8, arr[20] as UInt8, arr[21] as UInt8, arr[22] as UInt8, arr[23] as UInt8, arr[24] as UInt8, arr[25] as UInt8, arr[26] as UInt8, arr[27] as UInt8, arr[28] as UInt8, arr[29] as UInt8, arr[30] as UInt8, arr[31] as UInt8, arr[32] as UInt8, arr[33] as UInt8, arr[34] as UInt8, arr[35] as UInt8, arr[36] as UInt8, arr[37] as UInt8, arr[38] as UInt8, arr[39] as UInt8, arr[40] as UInt8, arr[41] as UInt8, arr[42] as UInt8, arr[43] as UInt8, arr[44] as UInt8, arr[45] as UInt8, arr[46] as UInt8, arr[47] as UInt8, arr[48] as UInt8, arr[49] as UInt8, arr[50] as UInt8, arr[51] as UInt8, arr[52] as UInt8, arr[53] as UInt8, arr[54] as UInt8, arr[55] as UInt8, arr[56] as UInt8, arr[57] as UInt8, arr[58] as UInt8, arr[59] as UInt8, arr[60] as UInt8, arr[61] as UInt8, arr[62] as UInt8, arr[63] as UInt8) +func generateAddressFromPubKey(publicKeyX: String, publicKeyY: String) -> String { + let publicKeyHex = publicKeyX.addLeading0sForLength64() + publicKeyY.addLeading0sForLength64() + let publicKeyData = Data(hex: publicKeyHex) + let ethAddrData = publicKeyData.sha3(.keccak256).suffix(20) + let ethAddrlower = ethAddrData.toHexString().addHexPrefix() + return ethAddrlower.toChecksumAddress() } diff --git a/Sources/TorusUtils/Helpers/Error.swift b/Sources/TorusUtils/Helpers/Error.swift index a09022cd..3ffce30c 100644 --- a/Sources/TorusUtils/Helpers/Error.swift +++ b/Sources/TorusUtils/Helpers/Error.swift @@ -1,10 +1,3 @@ -// -// File.swift -// -// -// Created by Shubham on 2/4/20. -// - import Foundation public enum TorusUtilError: Error, Equatable { @@ -124,7 +117,6 @@ extension TorusUtilError: LocalizedError { return "Could not encode data \(msg ?? "")" default: return "default Error msg" - } } } diff --git a/Sources/TorusUtils/Helpers/JSONRPCRequest.swift b/Sources/TorusUtils/Helpers/JSONRPCRequest.swift index 65fac5e3..32478788 100644 --- a/Sources/TorusUtils/Helpers/JSONRPCRequest.swift +++ b/Sources/TorusUtils/Helpers/JSONRPCRequest.swift @@ -1,23 +1,15 @@ -// -// JSONRPCRequest.swift -// -// -// Created by Shubham on 26/3/20. -// - import BigInt import Foundation import AnyCodable -public struct GetPublicAddressOrKeyAssignParams : Encodable { - public var verifier : String - public var verifier_id : String - public var extended_verifier_id :String? - public var one_key_flow : Bool - public var fetch_node_index : Bool +public struct GetPublicAddressOrKeyAssignParams: Encodable { + public var verifier: String + public var verifier_id: String + public var extended_verifier_id: String? + public var one_key_flow: Bool + public var fetch_node_index: Bool } - public struct SignerResponse: Codable { public var torusNonce: String public var torusSignature: String @@ -97,50 +89,49 @@ public struct KeyAssignRequest: Encodable { } } - public indirect enum MixedValue: Codable { case integer(Int) case boolean(Bool) case string(String) - case mixValue([String : MixedValue]) + case mixValue([String: MixedValue]) case array([MixedValue]) public init(from decoder: Decoder) throws { - let container = try decoder.singleValueContainer() - if let value = try? container.decode(Bool.self) { - self = .boolean(value) - }else if let value = try? container.decode(Int.self) { - self = .integer(value) - } else if let value = try? container.decode(String.self) { - self = .string(value) - } else if let value = try? container.decode([String: MixedValue].self) { - self = .mixValue(value) - } else if let value = try? container.decode([MixedValue].self) { - self = .array(value) - } else { - throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid mixed value") - } + let container = try decoder.singleValueContainer() + if let value = try? container.decode(Bool.self) { + self = .boolean(value) + } else if let value = try? container.decode(Int.self) { + self = .integer(value) + } else if let value = try? container.decode(String.self) { + self = .string(value) + } else if let value = try? container.decode([String: MixedValue].self) { + self = .mixValue(value) + } else if let value = try? container.decode([MixedValue].self) { + self = .array(value) + } else { + throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid mixed value") } - + } + public func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() switch self { - case .integer(let value) : + case let .integer(value): try container.encode(value) - case .boolean(let value): + case let .boolean(value): try container.encode(value) - case .string(let value): + case let .string(value): try container.encode(value) - case .mixValue(let value): + case let .mixValue(value): try container.encode(value) - case .array(let value): + case let .array(value): try container.encode(value) } } } /// JSON RPC request structure for serialization and deserialization purposes. -public struct JSONRPCrequest : Encodable { +public struct JSONRPCrequest: Encodable { public var jsonrpc: String = "2.0" public var method: String public var params: T @@ -169,13 +160,6 @@ public struct JSONRPCresponse: Decodable { case errorMessage } -// public func encode(to encoder: Encoder) throws { -// var container = encoder.container(keyedBy: JSONRPCresponseKeys.self) -// try? container.encode(result as? MixedValue, forKey: .result) -//// try? container.encode(result as? [String: String], forKey: .result) -// try container.encode(error, forKey: .error) -// } - public init(id: Int, jsonrpc: String, result: Decodable?, error: ErrorMessage?) { self.id = id self.jsonrpc = jsonrpc @@ -192,19 +176,19 @@ public struct JSONRPCresponse: Decodable { self.init(id: id, jsonrpc: jsonrpc, result: nil, error: errorMessage) return } - + var result: Decodable? - if let rawValue = try? container.decodeIfPresent(VerifierLookupResponse.self, forKey: .result){ + if let rawValue = try? container.decodeIfPresent(VerifierLookupResponse.self, forKey: .result) { result = rawValue - }else if let rawValue = try? container.decodeIfPresent(ShareRequestResult.self, forKey: .result){ + } else if let rawValue = try? container.decodeIfPresent(ShareRequestResult.self, forKey: .result) { result = rawValue - }else if let rawValue = try? container.decodeIfPresent(LegacyShareRequestResult.self, forKey: .result){ + } else if let rawValue = try? container.decodeIfPresent(LegacyShareRequestResult.self, forKey: .result) { result = rawValue - }else if let rawValue = try? container.decodeIfPresent(CommitmentRequestResponse.self, forKey: .result){ + } else if let rawValue = try? container.decodeIfPresent(CommitmentRequestResponse.self, forKey: .result) { result = rawValue - }else if let rawValue = try? container.decodeIfPresent(LegacyLookupResponse.self, forKey: .result){ + } else if let rawValue = try? container.decodeIfPresent(LegacyLookupResponse.self, forKey: .result) { result = rawValue - }else if let rawValue = try? container.decodeIfPresent(String.self, forKey: .result) { + } else if let rawValue = try? container.decodeIfPresent(String.self, forKey: .result) { result = rawValue } else if let rawValue = try? container.decodeIfPresent(Int.self, forKey: .result) { result = rawValue @@ -229,7 +213,7 @@ public struct JSONRPCresponse: Decodable { } else { result = nil } - + self.init(id: id, jsonrpc: jsonrpc, result: result, error: nil) } } diff --git a/Sources/TorusUtils/Helpers/KeyUtils.swift b/Sources/TorusUtils/Helpers/KeyUtils.swift deleted file mode 100644 index ffb7e693..00000000 --- a/Sources/TorusUtils/Helpers/KeyUtils.swift +++ /dev/null @@ -1,144 +0,0 @@ -import Foundation -import CryptoKit -import BigInt - -func keccak256Data(_ data: Data) -> Data { - return data.sha3(.keccak256) -} - -func keccak256Hex(_ data: Data) -> String { - let hash = data.sha3(.keccak256) - return "0x" + hash.map { String(format: "%02x", $0) }.joined() -} - -func stripHexPrefix(_ str: String) -> String { - return str.hasPrefix("0x") ? String(str.dropFirst(2)) : str -} - -struct BasePoint { - let x: Data - let y: Data - - func add(_ other: BasePoint) -> BasePoint? { - let x1 = self.x - let y1 = self.y - let x2 = other.x - let y2 = other.y - - let bigX1 = BigInt(x1) - let bigY1 = BigInt(y1) - let bigX2 = BigInt(x2) - let bigY2 = BigInt(y2) - - let sumX = (bigX1 + bigX2).serialize().toHexString().data(using: .utf8)! - let sumY = (bigY1 + bigY2).serialize().toHexString().data(using: .utf8)! - - return BasePoint(x: sumX, y: sumY) - } -} - - - -func keyFromPublic(x: String, y: String) -> BasePoint? { - let publicKeyHex = "04" + x.padding(toLength: 64, withPad: "0", startingAt: 0) + y.padding(toLength: 64, withPad: "0", startingAt: 0) - - guard let publicKeyData = Data(hexString: publicKeyHex) else { - return nil - } - - do { - let publicKey = try P256.KeyAgreement.PublicKey(x963Representation: publicKeyData) - let publicKeyBytes = publicKey.rawRepresentation.dropFirst() // Remove the first byte (0x04) - - let xData = Data(publicKeyBytes[0..<32]) - let yData = Data(publicKeyBytes[32..<64]) - - return BasePoint(x: xData, y: yData) - } catch { - return nil - } -} - -func generateAddressFromPubKey(publicKeyX: String, publicKeyY: String) -> String { - let publicKeyHex = "04" + publicKeyX.addLeading0sForLength64() + publicKeyY.addLeading0sForLength64() - let publicKeyData = Data(hexString: publicKeyHex)! - - do { - let publicKey = try P256.KeyAgreement.PublicKey(x963Representation: publicKeyData) - let publicKeyBytes = publicKey.rawRepresentation//.dropFirst().dropLast() // Remove the first byte (0x04) - let ethAddressLower = "0x" + keccak256Hex(publicKeyBytes).suffix(40) - return ethAddressLower.toChecksumAddress() - } catch { - // Handle the error if necessary - print("Failed to derive public key: \(error)") - return "" - } -} - -func getPostboxKeyFrom1OutOf1(privKey: String, nonce: String) -> String { - guard let privKeyBigInt = BigInt(privKey, radix: 16), - let nonceBigInt = BigInt(nonce, radix: 16), - let modulus = BigInt(CURVE_N, radix: 16) else { - return "" - } - - let result = (privKeyBigInt - nonceBigInt).modulus(modulus) - return result.serialize().toHexString() -} - - -//import Foundation -//import secp256k1 -//import CryptoKit -// -//func getPublicAddressFromCoordinates(x: String, y: String) -> String? { -// guard let xData = Data(hexString: x), -// let yData = Data(hexString: y) else { -// return nil -// } -// -// // Combine the x and y coordinates into a single data object -// let publicKeyData = xData + yData -// -// // Convert the combined data to a CryptoKit elliptic curve public key -// let publicKey = P256.Signing.PublicKey(rawRepresentation: publicKeyData) -// -// // Compute the public address using the hash of the public key -// let addressData = Data(SHA256.hash(data: publicKey.rawRepresentation)) -// let address = addressData.suffix(20).hexString // Take the last 20 bytes as the address -// -// return address -//} -// -//// Extension to convert Data to hex string representation -//extension Data { -// init?(hexString: String) { -// let string = hexString.trimmingCharacters(in: .whitespaces) -// var data = Data(capacity: string.count / 2) -// -// var index = string.startIndex -// while index < string.endIndex { -// let byteString = string[index ..< string.index(index, offsetBy: 2)] -// guard let byte = UInt8(byteString, radix: 16) else { -// return nil -// } -// data.append(byte) -// index = string.index(index, offsetBy: 2) -// } -// self = data -// } -// -// var hexString: String { -// return map { String(format: "%02hhx", $0) }.joined() -// } -//} -// -//// Usage example -//let xCoordinate = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f" -//let yCoordinate = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e" -// -//if let publicAddress = getPublicAddressFromCoordinates(x: xCoordinate, y: yCoordinate) { -// print("Public Address:", publicAddress) -//} else { -// print("Invalid coordinates") -//} diff --git a/Sources/TorusUtils/Helpers/LangrangeInterpolatePoly.swift b/Sources/TorusUtils/Helpers/LangrangeInterpolatePoly.swift index 8b68444a..f1b8dc2c 100644 --- a/Sources/TorusUtils/Helpers/LangrangeInterpolatePoly.swift +++ b/Sources/TorusUtils/Helpers/LangrangeInterpolatePoly.swift @@ -1,30 +1,33 @@ -import Foundation import BigInt +import Foundation +#if canImport(secp256k1) + import secp256k1 +#endif func modInverse(_ a: BigInt, _ m: BigInt) -> BigInt? { var (t, newT) = (BigInt(0), BigInt(1)) var (r, newR) = (m, a) - + while newR != 0 { let quotient = r / newR (t, newT) = (newT, t - quotient * newT) (r, newR) = (newR, r - quotient * newR) } - + if r > 1 { return nil // Modular inverse does not exist } if t < 0 { t += m } - + return t } -func generatePrivateExcludingIndexes(shareIndexes: [BigInt]) -> BigInt { - let key = BigInt(SECP256K1.generatePrivateKey()!) +func generatePrivateExcludingIndexes(shareIndexes: [BigInt]) throws -> BigInt { + let key = BigInt(try secp256k1.KeyAgreement.PrivateKey().rawRepresentation) if shareIndexes.contains(where: { $0 == key }) { - return generatePrivateExcludingIndexes(shareIndexes: shareIndexes) + return try generatePrivateExcludingIndexes(shareIndexes: shareIndexes) } return key } @@ -36,7 +39,7 @@ func generateEmptyBNArray(length: Int) -> [BigInt] { func denominator(i: Int, innerPoints: [Point]) -> BigInt { var result = BigInt(1) let xi = innerPoints[i].x - for j in (0.. [BigInt] { fatalError("Denominator for interpolationPoly is 0") } coefficients[0] = d.inverse(getOrderOfCurve())! - for k in 0.. [Point] { func lagrange(unsortedPoints: [Point]) -> Polynomial { let sortedPoints = pointSort(innerPoints: unsortedPoints) var polynomial = generateEmptyBNArray(length: sortedPoints.count) - for i in 0.. Polynomial { } func lagrangeInterpolationWithNodeIndex(shares: [BigInt], nodeIndex: [BigInt]) -> BigInt { - let modulus = BigInt(CURVE_N, radix: 16)! if shares.count != nodeIndex.count { - fatalError("shares not equal to nodeIndex length in lagrangeInterpolation") - } - - var secret = BigInt(0) - for i in 0.. Polynomial { var actualS = secret if secret == nil { - actualS = generatePrivateExcludingIndexes(shareIndexes: [BigInt(0)]) + actualS = try generatePrivateExcludingIndexes(shareIndexes: [BigInt(0)]) } - + if deterministicShares == nil { var poly = [actualS!] - for _ in 0.. degree { throw NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Deterministic shares in generateRandomPolynomial should be less or equal than degree to ensure an element of randomness"]) } - + var points = [String: Point]() - for share in deterministicShares { - points[String(share.shareIndex, radix: 16).leftPadding(toLength: 64, withPad: "0")] = - Point(x: share.shareIndex, y: share.share) + for share in deterministicShares { + points[String(share.shareIndex, radix: 16).addLeading0sForLength64()] = + Point(x: share.shareIndex, y: share.share) } - + let remainingDegree = degree - deterministicShares.count - for _ in 0.. [[String: String]] { var dictArr = [[String: String]]() for val in self { diff --git a/Sources/TorusUtils/Interfaces/Ecies.swift b/Sources/TorusUtils/Interfaces/Ecies.swift index b475ca23..cf5fc141 100644 --- a/Sources/TorusUtils/Interfaces/Ecies.swift +++ b/Sources/TorusUtils/Interfaces/Ecies.swift @@ -7,15 +7,14 @@ protocol EciesProtocol { var mac: Data { get } } - -public struct ECIES : Codable { +public struct ECIES: Codable { let iv: String let ephemPublicKey: String let ciphertext: String let mac: String let mode: String? - - init(iv: String, ephemPublicKey: String, ciphertext: String, mac: String, mode: String?=nil) { + + init(iv: String, ephemPublicKey: String, ciphertext: String, mac: String, mode: String? = nil) { self.iv = iv self.ephemPublicKey = ephemPublicKey self.ciphertext = ciphertext @@ -24,13 +23,13 @@ public struct ECIES : Codable { } } -public struct EciesHex : Codable { +public struct EciesHex: Codable { let iv: String let ephemPublicKey: String let ciphertext: String? let mac: String let mode: String? - + init(iv: String, ephemPublicKey: String, ciphertext: String?, mac: String, mode: String?) { self.iv = iv self.ephemPublicKey = ephemPublicKey @@ -38,31 +37,30 @@ public struct EciesHex : Codable { self.mac = mac self.mode = mode } - + func omitCiphertext() -> EciesHexOmitCiphertext { - return EciesHexOmitCiphertext(iv: self.iv, ephemPublicKey: self.ephemPublicKey, mac: self.mac, mode: self.mode) + return EciesHexOmitCiphertext(iv: iv, ephemPublicKey: ephemPublicKey, mac: mac, mode: mode) } - } -public struct EciesHexOmitCiphertext :Decodable { +public struct EciesHexOmitCiphertext: Decodable { var iv: String var ephemPublicKey: String var mac: String var mode: String? - + init(iv: String, ephemPublicKey: String, mac: String, mode: String? = nil) { self.iv = iv self.ephemPublicKey = ephemPublicKey self.mac = mac self.mode = mode } - + init(from: ECIES) { - self.iv = from.iv - self.ephemPublicKey = from.ephemPublicKey - self.mac = from.mac - self.mode = from.mode + iv = from.iv + ephemPublicKey = from.ephemPublicKey + mac = from.mac + mode = from.mode } } @@ -71,7 +69,7 @@ public struct Ecies: Codable { var ephemPublicKey: String var ciphertext: String var mac: String - + init(iv: String, ephemPublicKey: String, ciphertext: String, mac: String) { self.iv = iv self.ephemPublicKey = ephemPublicKey diff --git a/Sources/TorusUtils/Interfaces/ImportedShare.swift b/Sources/TorusUtils/Interfaces/ImportedShare.swift index 24c6e214..22b46c99 100644 --- a/Sources/TorusUtils/Interfaces/ImportedShare.swift +++ b/Sources/TorusUtils/Interfaces/ImportedShare.swift @@ -1,5 +1,5 @@ -import Foundation import BigInt +import Foundation struct ImportedShare { let pubKeyX: String @@ -10,5 +10,4 @@ struct ImportedShare { let keyType: String let nonceData: String let nonceSignature: String - } diff --git a/Sources/TorusUtils/Interfaces/KeyAssignInput.swift b/Sources/TorusUtils/Interfaces/KeyAssignInput.swift index 5c0554a9..597ca036 100644 --- a/Sources/TorusUtils/Interfaces/KeyAssignInput.swift +++ b/Sources/TorusUtils/Interfaces/KeyAssignInput.swift @@ -1,26 +1,22 @@ import Foundation -public struct KeyIndex : Decodable { +public struct KeyIndex: Decodable { let index: String let serviceGroupId: String let tag: String - + enum CodingKeys: CodingKey { case index case service_group_id case tag } - + public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.index = try container.decode(String.self, forKey: .index) - self.serviceGroupId = try container.decode(String.self, forKey: .service_group_id) - self.tag = try container.decode(String.self, forKey: .tag) + index = try container.decode(String.self, forKey: .index) + serviceGroupId = try container.decode(String.self, forKey: .service_group_id) + tag = try container.decode(String.self, forKey: .tag) } - -// public func encode(to encoder: Encoder) throws { -// -// } } enum keyIndexTag: String { @@ -40,9 +36,7 @@ public struct KeyAssignInput { let clientId: String } - - -public struct KeyAssignment : Decodable { +public struct KeyAssignment: Decodable { let index: String let publicKey: PublicKey let threshold: Int @@ -50,8 +44,8 @@ public struct KeyAssignment : Decodable { let share: String let shareMetadata: EciesHex let nonceData: GetOrSetNonceResult? - - struct PublicKey : Hashable, Codable { + + struct PublicKey: Hashable, Codable { let X: String let Y: String } @@ -65,30 +59,29 @@ public struct KeyAssignment : Decodable { case share_metadata case nonce_data } - + public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.index = try container.decode(String.self, forKey: .index) - - self.publicKey = try container.decode(PublicKey.self, forKey: .public_key) - self.threshold = Int(try container.decode(String.self, forKey: .threshold))! - self.nodeIndex = Int(try container.decode(String.self, forKey: .node_index))! - self.share = try container.decode(String.self, forKey: .share) - self.shareMetadata = try container.decode(EciesHex.self, forKey: .share_metadata) - self.nonceData = try container.decodeIfPresent(GetOrSetNonceResult.self, forKey: .nonce_data) + index = try container.decode(String.self, forKey: .index) + + publicKey = try container.decode(PublicKey.self, forKey: .public_key) + threshold = Int(try container.decode(String.self, forKey: .threshold))! + nodeIndex = Int(try container.decode(String.self, forKey: .node_index))! + share = try container.decode(String.self, forKey: .share) + shareMetadata = try container.decode(EciesHex.self, forKey: .share_metadata) + nonceData = try container.decodeIfPresent(GetOrSetNonceResult.self, forKey: .nonce_data) } } -public struct LegacyKeyAssignment : Decodable { - +public struct LegacyKeyAssignment: Decodable { let index: String let publicKey: PublicKey let threshold: String let verifiers: [String: [String]] let share: String let metadata: EciesHex - - struct PublicKey : Hashable, Codable { + + struct PublicKey: Hashable, Codable { let X: String let Y: String } @@ -101,15 +94,14 @@ public struct LegacyKeyAssignment : Decodable { case Share case Metadata } - + public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.index = try container.decode(String.self, forKey: .Index) - self.publicKey = try container.decode(PublicKey.self, forKey: .PublicKey) - self.threshold = try container.decode(String.self, forKey: .Threshold) - self.verifiers = try container.decode([String: [String]].self, forKey: .Verifiers) - self.share = try container.decode(String.self, forKey: .Share) - self.metadata = try container.decode(EciesHex.self, forKey: .Metadata) + index = try container.decode(String.self, forKey: .Index) + publicKey = try container.decode(PublicKey.self, forKey: .PublicKey) + threshold = try container.decode(String.self, forKey: .Threshold) + verifiers = try container.decode([String: [String]].self, forKey: .Verifiers) + share = try container.decode(String.self, forKey: .Share) + metadata = try container.decode(EciesHex.self, forKey: .Metadata) } } - diff --git a/Sources/TorusUtils/Interfaces/KeyLookupResponse.swift b/Sources/TorusUtils/Interfaces/KeyLookupResponse.swift index 4682f2ad..a3bcb1c7 100644 --- a/Sources/TorusUtils/Interfaces/KeyLookupResponse.swift +++ b/Sources/TorusUtils/Interfaces/KeyLookupResponse.swift @@ -1,7 +1,6 @@ import Foundation public struct LegacyKeyLookupResponse: CustomStringConvertible, Hashable { - public let pubKeyX: String public let pubKeyY: String public let keyIndex: String @@ -16,11 +15,9 @@ public struct LegacyKeyLookupResponse: CustomStringConvertible, Hashable { self.keyIndex = keyIndex self.address = address } - } public struct KeyLookupResponse: CustomStringConvertible, Hashable { - public let pubKeyX: String public let pubKeyY: String public let address: String @@ -36,7 +33,6 @@ public struct KeyLookupResponse: CustomStringConvertible, Hashable { self.address = address self.isNewKey = isNewKey } - } public enum KeyLookupError: Error { @@ -56,7 +52,6 @@ public enum KeyLookupError: Error { } extension KeyLookupError: LocalizedError { - public var errorDescription: String? { switch self { case .verifierNotSupported: diff --git a/Sources/TorusUtils/Interfaces/NonceMetadataParams.swift b/Sources/TorusUtils/Interfaces/NonceMetadataParams.swift deleted file mode 100644 index 5be67778..00000000 --- a/Sources/TorusUtils/Interfaces/NonceMetadataParams.swift +++ /dev/null @@ -1,22 +0,0 @@ -//import Foundation -// -//public struct SetNonceData { -// let operation: String -// let data: String -// let timestamp: String -//} -// -//public struct PartialSetNonceData { -// let operation: String? -// let data: String? -// let timestamp: String? -//} -// -//public struct NonceMetadataParams { -// let namespace: String? -// let pubKeyX: String -// let pubKeyY: String -// let setData: PartialSetNonceData -// let signature: String -//} - diff --git a/Sources/TorusUtils/Interfaces/RetrieveSharesResponse.swift b/Sources/TorusUtils/Interfaces/RetrieveSharesResponse.swift index 8649c89f..b9c4dfec 100644 --- a/Sources/TorusUtils/Interfaces/RetrieveSharesResponse.swift +++ b/Sources/TorusUtils/Interfaces/RetrieveSharesResponse.swift @@ -1,5 +1,5 @@ -import Foundation import BigInt +import Foundation public struct RetrieveSharesResponse { public let ethAddress: String @@ -12,7 +12,7 @@ public struct RetrieveSharesResponse { public let postboxPubKeyY: String public let sessionAuthKey: String public let nodeIndexes: [Int] - + public init(ethAddress: String, privKey: String, sessionTokenData: [SessionToken?], X: String, Y: String, metadataNonce: BigInt, postboxPubKeyX: String, postboxPubKeyY: String, sessionAuthKey: String, nodeIndexes: [Int]) { self.ethAddress = ethAddress self.privKey = privKey diff --git a/Sources/TorusUtils/Interfaces/ShareRequestResult.swift b/Sources/TorusUtils/Interfaces/ShareRequestResult.swift index 41e0d79b..89446f92 100644 --- a/Sources/TorusUtils/Interfaces/ShareRequestResult.swift +++ b/Sources/TorusUtils/Interfaces/ShareRequestResult.swift @@ -1,6 +1,6 @@ import Foundation -struct ShareRequestResult : Decodable { +struct ShareRequestResult: Decodable { let keys: [KeyAssignment] let sessionTokens: [String] let sessionTokenMetadata: [EciesHex] @@ -9,7 +9,7 @@ struct ShareRequestResult : Decodable { let nodePubX: String let nodePubY: String let isNewKey: String - + enum CodingKeys: CodingKey { case keys case session_tokens @@ -20,51 +20,43 @@ struct ShareRequestResult : Decodable { case node_puby case is_new_key } - + init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.keys = try container.decode([KeyAssignment].self, forKey: .keys) - self.nodePubX = try container.decode(String.self, forKey: .node_pubx) - self.nodePubY = try container.decode(String.self, forKey: .node_puby) - self.isNewKey = try container.decode(String.self, forKey: .is_new_key) + keys = try container.decode([KeyAssignment].self, forKey: .keys) + nodePubX = try container.decode(String.self, forKey: .node_pubx) + nodePubY = try container.decode(String.self, forKey: .node_puby) + isNewKey = try container.decode(String.self, forKey: .is_new_key) if let sessionTokens = try? container.decodeIfPresent([String].self, forKey: .session_tokens) { self.sessionTokens = sessionTokens } else { - self.sessionTokens = [] + sessionTokens = [] } if let sessionTokenMetadata = try? container.decodeIfPresent([EciesHex].self, forKey: .session_token_metadata) { self.sessionTokenMetadata = sessionTokenMetadata } else { - self.sessionTokenMetadata = [] + sessionTokenMetadata = [] } if let sessionTokenSigs = try? container.decodeIfPresent([String].self, forKey: .session_token_sigs) { self.sessionTokenSigs = sessionTokenSigs } else { - self.sessionTokenSigs = [] + sessionTokenSigs = [] } if let sessionTokenSigMetadata = try? container.decodeIfPresent([EciesHex].self, forKey: .session_token_sig_metadata) { self.sessionTokenSigMetadata = sessionTokenSigMetadata } else { - self.sessionTokenSigMetadata = [] + sessionTokenSigMetadata = [] } - } - -// public func encode(to encoder: Encoder) throws { -// var container = encoder.container(keyedBy: ShareRequestResult.self) -// try? container.encode(sessionTokens , forKey: .session_tokens) -// -// } } typealias ImportShareRequestResult = ShareRequestResult - -struct LegacyShareRequestResult : Decodable { +struct LegacyShareRequestResult: Decodable { let keys: [LegacyKeyAssignment] let sessionTokens: [String] let sessionTokenMetadata: [EciesHex] @@ -72,7 +64,7 @@ struct LegacyShareRequestResult : Decodable { let sessionTokenSigMetadata: [EciesHex] let nodePubX: String let nodePubY: String - + enum CodingKeys: CodingKey { case keys case session_tokens @@ -82,41 +74,35 @@ struct LegacyShareRequestResult : Decodable { case node_pubx case node_puby } - + init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.keys = try container.decode([LegacyKeyAssignment].self, forKey: .keys) - self.nodePubX = try container.decode(String.self, forKey: .node_pubx) - self.nodePubY = try container.decode(String.self, forKey: .node_puby) - + keys = try container.decode([LegacyKeyAssignment].self, forKey: .keys) + nodePubX = try container.decode(String.self, forKey: .node_pubx) + nodePubY = try container.decode(String.self, forKey: .node_puby) + if let sessionTokens = try? container.decodeIfPresent([String].self, forKey: .session_tokens) { self.sessionTokens = sessionTokens } else { - self.sessionTokens = [] + sessionTokens = [] } if let sessionTokenMetadata = try? container.decodeIfPresent([EciesHex].self, forKey: .session_token_metadata) { self.sessionTokenMetadata = sessionTokenMetadata } else { - self.sessionTokenMetadata = [] + sessionTokenMetadata = [] } if let sessionTokenSigs = try? container.decodeIfPresent([String].self, forKey: .session_token_sigs) { self.sessionTokenSigs = sessionTokenSigs } else { - self.sessionTokenSigs = [] + sessionTokenSigs = [] } if let sessionTokenSigMetadata = try? container.decodeIfPresent([EciesHex].self, forKey: .session_token_sig_metadata) { self.sessionTokenSigMetadata = sessionTokenSigMetadata } else { - self.sessionTokenSigMetadata = [] + sessionTokenSigMetadata = [] } } - -// public func encode(to encoder: Encoder) throws { -// var container = encoder.container(keyedBy: ShareRequestResult.self) -// try? container.encode(sessionTokens , forKey: .session_tokens) -// -// } } diff --git a/Sources/TorusUtils/Interfaces/TorusConstants.swift b/Sources/TorusUtils/Interfaces/TorusConstants.swift index cef386f7..6c4b5a8c 100644 --- a/Sources/TorusUtils/Interfaces/TorusConstants.swift +++ b/Sources/TorusUtils/Interfaces/TorusConstants.swift @@ -1,19 +1,20 @@ -import Foundation import BigInt import CommonSources +import Foundation enum TORUS_SAPPHIRE_NETWORK_TYPE { case SAPPHIRE_DEVNET case SAPPHIRE_TESTNET case SAPPHIRE_MAINNET } + struct TORUS_SAPPHIRE_NETWORK { static let SAPPHIRE_DEVNET = "sapphire_devnet" static let SAPPHIRE_TESTNET = "sapphire_testnet" static let SAPPHIRE_MAINNET = "sapphire_mainnet" } -public class INodePub{ +public class INodePub { let X: String let Y: String @@ -23,6 +24,6 @@ public class INodePub{ } } -public func TorusNodePubModelToINodePub (node: TorusNodePubModel) -> INodePub { - return INodePub( X: node.getX(), Y: node.getY() ) +public func TorusNodePubModelToINodePub(node: TorusNodePubModel) -> INodePub { + return INodePub(X: node.getX(), Y: node.getY()) } diff --git a/Sources/TorusUtils/Interfaces/TorusPublicKey.swift b/Sources/TorusUtils/Interfaces/TorusPublicKey.swift index 92669bdb..7ff5d783 100644 --- a/Sources/TorusUtils/Interfaces/TorusPublicKey.swift +++ b/Sources/TorusUtils/Interfaces/TorusPublicKey.swift @@ -1,5 +1,5 @@ -import Foundation import BigInt +import Foundation public enum UserType: String { case v1 @@ -29,8 +29,8 @@ public struct TorusPublicKey { public struct NodesData { public let nodeIndexes: [Int] } - - public init (finalKeyData: FinalKeyData?, oAuthKeyData: OAuthKeyData?, metadata: Metadata?, nodesData: NodesData?) { + + public init(finalKeyData: FinalKeyData?, oAuthKeyData: OAuthKeyData?, metadata: Metadata?, nodesData: NodesData?) { self.finalKeyData = finalKeyData self.oAuthKeyData = oAuthKeyData self.metadata = metadata @@ -40,7 +40,7 @@ public struct TorusPublicKey { public let finalKeyData: FinalKeyData? public let oAuthKeyData: OAuthKeyData? public let metadata: Metadata? - public let nodesData: NodesData? + public let nodesData: NodesData? } public typealias V2NonceResultType = GetOrSetNonceResult diff --git a/Sources/TorusUtils/Interfaces/Toruskey.swift b/Sources/TorusUtils/Interfaces/Toruskey.swift index 512e83dc..b0f2a9fa 100644 --- a/Sources/TorusUtils/Interfaces/Toruskey.swift +++ b/Sources/TorusUtils/Interfaces/Toruskey.swift @@ -1,5 +1,5 @@ -import Foundation import BigInt +import Foundation public struct TorusKey { public struct FinalKeyData { @@ -31,12 +31,12 @@ public struct TorusKey { public struct NodesData { public let nodeIndexes: [Int] } - + public init(finalKeyData: FinalKeyData?, - oAuthKeyData: OAuthKeyData?, - sessionData: SessionData?, - metadata: Metadata?, - nodesData: NodesData?) { + oAuthKeyData: OAuthKeyData?, + sessionData: SessionData?, + metadata: Metadata?, + nodesData: NodesData?) { self.finalKeyData = finalKeyData self.oAuthKeyData = oAuthKeyData self.sessionData = sessionData diff --git a/Sources/TorusUtils/Interfaces/VerifierLookupResponse.swift b/Sources/TorusUtils/Interfaces/VerifierLookupResponse.swift index 4c102db1..47b02705 100644 --- a/Sources/TorusUtils/Interfaces/VerifierLookupResponse.swift +++ b/Sources/TorusUtils/Interfaces/VerifierLookupResponse.swift @@ -1,13 +1,13 @@ import Foundation -struct VerifierLookupResponse : Codable { - struct Key : Codable { +struct VerifierLookupResponse: Codable { + struct Key: Codable { let pub_key_X: String let pub_key_Y: String let address: String let nonce_data: GetOrSetNonceResult? let created_at: Int? - + init(pub_key_X: String, pub_key_Y: String, address: String, nonce_data: GetOrSetNonceResult? = nil, created_at: Int? = nil) { self.pub_key_X = pub_key_X self.pub_key_Y = pub_key_Y @@ -15,7 +15,7 @@ struct VerifierLookupResponse : Codable { self.nonce_data = nonce_data self.created_at = created_at } - + enum JSONRPCresponseKeys: String, CodingKey { case pub_key_X case pub_key_Y @@ -23,11 +23,11 @@ struct VerifierLookupResponse : Codable { case nonce_data case created_at } - + init(pub_key_X: String, pub_key_Y: String, address: String) { self.init(pub_key_X: pub_key_X, pub_key_Y: pub_key_Y, address: address, nonce_data: nil, created_at: nil) } - + public init(from: Decoder) throws { let container = try from.container(keyedBy: CodingKeys.self) pub_key_X = try container.decode(String.self, forKey: .pub_key_X) @@ -37,36 +37,34 @@ struct VerifierLookupResponse : Codable { created_at = try? container.decodeIfPresent(Int.self, forKey: .created_at) } } - + var keys: [Key]? var is_new_key: Bool var node_index: String - + public init(keys: [Key]?, is_new_key: Bool, node_index: String) { self.keys = keys self.is_new_key = is_new_key self.node_index = node_index } - + public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.keys = try container.decodeIfPresent([VerifierLookupResponse.Key].self, forKey: .keys) - self.is_new_key = try container.decode(Bool.self, forKey: .is_new_key) - self.node_index = try container.decode(String.self, forKey: .node_index) + keys = try container.decodeIfPresent([VerifierLookupResponse.Key].self, forKey: .keys) + is_new_key = try container.decode(Bool.self, forKey: .is_new_key) + node_index = try container.decode(String.self, forKey: .node_index) } - } +public struct LegacyLookupResponse: Decodable { + public struct KeyLookup: Decodable { + public var index: String + public var metadata: EciesHexOmitCiphertext + public var publicKey: Point + public var share: String + public var threshold: Int + public var verifier: [String: [String]] -public struct LegacyLookupResponse :Decodable{ - public struct KeyLookup :Decodable { - public var index : String - public var metadata : EciesHexOmitCiphertext - public var publicKey : Point - public var share : String - public var threshold : Int - public var verifier : [String: [String]] - public enum CodingKeys: CodingKey { case Index case Metadata @@ -75,25 +73,17 @@ public struct LegacyLookupResponse :Decodable{ case Threshold case Verifiers } - + public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.index = try container.decode(String.self, forKey: .Index) - self.metadata = try container.decode(EciesHexOmitCiphertext.self, forKey: .Metadata) - self.publicKey = try container.decode(Point.self, forKey: .PublicKey) - self.share = try container.decode(String.self, forKey: .Share) - self.threshold = try container.decode(Int.self, forKey: .Threshold) - self.verifier = try container.decode([String: [String]].self, forKey: .Verifiers) - + index = try container.decode(String.self, forKey: .Index) + metadata = try container.decode(EciesHexOmitCiphertext.self, forKey: .Metadata) + publicKey = try container.decode(Point.self, forKey: .PublicKey) + share = try container.decode(String.self, forKey: .Share) + threshold = try container.decode(Int.self, forKey: .Threshold) + verifier = try container.decode([String: [String]].self, forKey: .Verifiers) } -// public init(from decoder: Decoder) throws { -// let container = try decoder.container(keyedBy: CodingKeys.self) -// self.keys = try container.decode(.self, forKey: .keys) -// } } - - public var keys : [KeyLookup] - - + public var keys: [KeyLookup] } diff --git a/Sources/TorusUtils/Interfaces/VerifierParams.swift b/Sources/TorusUtils/Interfaces/VerifierParams.swift index e1ce3c66..18f2800d 100644 --- a/Sources/TorusUtils/Interfaces/VerifierParams.swift +++ b/Sources/TorusUtils/Interfaces/VerifierParams.swift @@ -4,7 +4,7 @@ public struct VerifierParams { public let verifier_id: String public let extended_verifier_id: String? public let additionalParams: [String: Codable] - + public init(verifier_id: String, extended_verifier_id: String? = nil, additionalParams: [String: Codable] = [:]) { self.verifier_id = verifier_id self.extended_verifier_id = extended_verifier_id diff --git a/Sources/TorusUtils/Models/RetrieveSharesResponseModel.swift b/Sources/TorusUtils/Models/RetrieveSharesResponseModel.swift index 9662dfc6..9ec2d7d2 100644 --- a/Sources/TorusUtils/Models/RetrieveSharesResponseModel.swift +++ b/Sources/TorusUtils/Models/RetrieveSharesResponseModel.swift @@ -1,21 +1,14 @@ -// -// File.swift -// -// -// Created by CW Lee on 30/06/2023. -// - import Foundation public struct RetrieveSharesResponseModel { - public let publicAddress: String - public let privateKey: String + public let publicAddress: String + public let privateKey: String - public init(publicKey: String, privateKey: String) { - self.publicAddress = publicKey - self.privateKey = privateKey - } - } + public init(publicKey: String, privateKey: String) { + publicAddress = publicKey + self.privateKey = privateKey + } +} // legacy public struct RetrieveDecryptAndReconstuctResponseModel { diff --git a/Sources/TorusUtils/Point.swift b/Sources/TorusUtils/Point.swift index ef1b8385..f4414ce3 100644 --- a/Sources/TorusUtils/Point.swift +++ b/Sources/TorusUtils/Point.swift @@ -1,8 +1,8 @@ -import Foundation import BigInt +import Foundation import Security -public class Point : Decodable { +public class Point: Decodable { let x: BigInt let y: BigInt @@ -10,13 +10,12 @@ public class Point : Decodable { self.x = BigInt(x, radix: 16)! self.y = BigInt(y, radix: 16)! } - + init(x: BigInt, y: BigInt) { self.x = x self.y = y } - - + public enum CodingKeys: CodingKey { case X case Y @@ -26,15 +25,15 @@ public class Point : Decodable { let container = try decoder.container(keyedBy: CodingKeys.self) let hexX = try container.decode(String.self, forKey: .X) let hexY = try container.decode(String.self, forKey: .Y) - - self.x = BigInt(hexX, radix: 16)! - self.y = BigInt(hexY, radix: 16)! + + x = BigInt(hexX, radix: 16)! + y = BigInt(hexY, radix: 16)! } - + func encode(enc: String) throws -> Data { switch enc { case "arr": - let prefix = Data(hex: "04") + let prefix = Data(hex: String().add04Prefix()) let xData = Data(hex: x.description) let yData = Data(hex: y.description) return prefix + xData + yData @@ -47,10 +46,10 @@ public class Point : Decodable { } } -public struct PointHex : Decodable, Hashable, Equatable { +public struct PointHex: Decodable, Hashable, Equatable { let x: String let y: String - + init(from: Point) { x = String(from.x, radix: 16) y = String(from.y, radix: 16) diff --git a/Sources/TorusUtils/Polynomial.swift b/Sources/TorusUtils/Polynomial.swift index fe3de39d..4ed66971 100644 --- a/Sources/TorusUtils/Polynomial.swift +++ b/Sources/TorusUtils/Polynomial.swift @@ -1,25 +1,25 @@ -import Foundation -import CryptoKit import BigInt +import CryptoKit +import Foundation typealias ShareMap = [String: Share] public struct Polynomial { let polynomial: [BigInt] - + init(polynomial: [BigInt]) { self.polynomial = polynomial } - + func getThreshold() -> Int { return polynomial.count } - + func polyEval(x: BigInt) -> BigInt { var xi = BigInt(x) var sum = BigInt(0) sum += polynomial[0] - for i in 1.. ShareMap { var shares: ShareMap = [:] - for x in 0.. BigInt { - let orderHex = CURVE_N - let order = BigInt(orderHex, radix: 16)! - return order + let orderHex = CURVE_N + let order = BigInt(orderHex, radix: 16)! + return order } diff --git a/Sources/TorusUtils/Share.swift b/Sources/TorusUtils/Share.swift index e8dbc5b3..11e1498f 100644 --- a/Sources/TorusUtils/Share.swift +++ b/Sources/TorusUtils/Share.swift @@ -1,15 +1,15 @@ import BigInt import Foundation -public class Share : Codable { +public class Share: Codable { var share: BigInt var shareIndex: BigInt - + public init(shareIndex: String, share: String) { self.share = BigInt(share, radix: 16)! self.shareIndex = BigInt(shareIndex, radix: 16)! } - + public init(shareIndex: BigInt, share: BigInt) { self.share = share self.shareIndex = shareIndex diff --git a/Sources/TorusUtils/TorusUtils.swift b/Sources/TorusUtils/TorusUtils.swift index aa29bdae..4c3ea98e 100644 --- a/Sources/TorusUtils/TorusUtils.swift +++ b/Sources/TorusUtils/TorusUtils.swift @@ -1,25 +1,17 @@ import BigInt -import CryptoKit -import FetchNodeDetails import CommonSources -/** - torus utils class - Author: Shubham Rathi - */ +import FetchNodeDetails import Foundation import OSLog -import secp256k1 import AnyCodable +#if canImport(secp256k1) + import secp256k1 +#endif -@available(macOSApplicationExtension 10.15, *) var utilsLogType = OSLogType.default -@available(iOS 13, macOS 10.15, *) open class TorusUtils: AbstractTorusUtils { - - - static let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) private var timeout: Int = 30 var urlSession: URLSession var serverTimeOffset: TimeInterval = 0 @@ -44,7 +36,7 @@ open class TorusUtils: AbstractTorusUtils { self.urlSession = urlSession utilsLogType = loglevel self.enableOneKey = enableOneKey - self.signerHost = signerHost // todo: remove signer host read it from fetch node details same as web sdk. + self.signerHost = signerHost // TODO: remove signer host read it from fetch node details same as web sdk. self.allowHost = allowHost self.network = network self.serverTimeOffset = serverTimeOffset @@ -53,37 +45,34 @@ open class TorusUtils: AbstractTorusUtils { } // MARK: - getPublicAddress - - public func getPublicAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, extendedVerifierId :String? = nil ) async throws -> TorusPublicKey { - if (self.isLegacyNetwork()) { - return try await getLegacyPublicAddress(endpoints: endpoints, torusNodePubs: torusNodePubs , verifier: verifier, verifierId: verifierId, enableOneKey: self.enableOneKey) + + public func getPublicAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, extendedVerifierId: String? = nil) async throws -> TorusPublicKey { + if isLegacyNetwork() { + return try await getLegacyPublicAddress(endpoints: endpoints, torusNodePubs: torusNodePubs, verifier: verifier, verifierId: verifierId, enableOneKey: enableOneKey) } else { - return try await getNewPublicAddress(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId, enableOneKey: self.enableOneKey) + return try await getNewPublicAddress(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId, enableOneKey: enableOneKey) } } - - + public func retrieveShares( endpoints: [String], - torusNodePubs : [TorusNodePubModel], - indexes : [BigUInt], + torusNodePubs: [TorusNodePubModel], + indexes: [BigUInt], verifier: String, verifierParams: VerifierParams, idToken: String, - extraParams: [String:Codable] = [:] + extraParams: [String: Codable] = [:] ) async throws -> TorusKey { - - if (self.isLegacyNetwork()) { + if isLegacyNetwork() { let result = try await legacyRetrieveShares(torusNodePubs: torusNodePubs, indexes: indexes, endpoints: endpoints, verifier: verifier, verifierId: verifierParams.verifier_id, idToken: idToken, extraParams: extraParams) return result } else { - let result = try await retrieveShare( - legacyMetadataHost: self.legacyMetadataHost, - allowHost: self.allowHost, - enableOneKey: self.enableOneKey, - network: self.network, - clientId: self.clientId, + legacyMetadataHost: legacyMetadataHost, + allowHost: allowHost, + enableOneKey: enableOneKey, + network: network, + clientId: clientId, endpoints: endpoints, verifier: verifier, verifierParams: verifierParams, @@ -92,64 +81,54 @@ open class TorusUtils: AbstractTorusUtils { ) return result } - } - - - - - public func getUserTypeAndAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, extendedVerifierId :String? = nil) async throws -> TorusPublicKey { - if (self.isLegacyNetwork()) { + + public func getUserTypeAndAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, extendedVerifierId: String? = nil) async throws -> TorusPublicKey { + if isLegacyNetwork() { return try await getLegacyPublicAddress(endpoints: endpoints, torusNodePubs: torusNodePubs, verifier: verifier, verifierId: verifierId, enableOneKey: true) - } - else { + } else { return try await getNewPublicAddress(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId, enableOneKey: true) } - } - - - private func getNewPublicAddress(endpoints: [String], verifier: String, verifierId: String, extendedVerifierId :String? = nil, enableOneKey: Bool) async throws -> TorusPublicKey { + + private func getNewPublicAddress(endpoints: [String], verifier: String, verifierId: String, extendedVerifierId: String? = nil, enableOneKey: Bool) async throws -> TorusPublicKey { do { - - let result = try await getPubKeyOrKeyAssign(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId ); - let keyResult = result.keyResult; - let nodeIndexes = result.nodeIndexes; - let (X, Y) = ( keyResult.pubKeyX, keyResult.pubKeyY); + let result = try await getPubKeyOrKeyAssign(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId) + let keyResult = result.keyResult + let nodeIndexes = result.nodeIndexes + let (X, Y) = (keyResult.pubKeyX, keyResult.pubKeyY) - let nonceResult = result.nonceResult; + let nonceResult = result.nonceResult - if (nonceResult?.pubNonce?.x == nil && extendedVerifierId == nil && !self.isLegacyNetwork() ) { throw TorusUtilError.runtime("metadata nonce is missing in share response") + if nonceResult?.pubNonce?.x == nil && extendedVerifierId == nil && !isLegacyNetwork() { throw TorusUtilError.runtime("metadata nonce is missing in share response") } - + var modifiedPubKey: String - var oAuthPubKeyString : String - var pubNonce : PubNonce? - - if (extendedVerifierId != nil) { - modifiedPubKey = "04" + X.addLeading0sForLength64() + Y.addLeading0sForLength64() + var oAuthPubKeyString: String + var pubNonce: PubNonce? + + if extendedVerifierId != nil { + modifiedPubKey = (X.addLeading0sForLength64() + Y.addLeading0sForLength64()).add04Prefix() oAuthPubKeyString = modifiedPubKey - } else if(self.isLegacyNetwork()) { + } else if isLegacyNetwork() { return try await formatLegacyPublicData(finalKeyResult: result.keyResult, enableOneKey: enableOneKey, isNewKey: result.keyResult.isNewKey) - } - else { - modifiedPubKey = "04" + X.addLeading0sForLength64() + Y.addLeading0sForLength64() + } else { + modifiedPubKey = (X.addLeading0sForLength64() + Y.addLeading0sForLength64()).add04Prefix() oAuthPubKeyString = modifiedPubKey - + let pubNonceX = (nonceResult?.pubNonce?.x ?? "0") let pubNonceY = (nonceResult?.pubNonce?.y ?? "0") - let noncePub = "04" + pubNonceX.addLeading0sForLength64() + pubNonceY.addLeading0sForLength64(); - modifiedPubKey = combinePublicKeys(keys: [modifiedPubKey, noncePub], compressed: false) + let noncePub = (pubNonceX.addLeading0sForLength64() + pubNonceY.addLeading0sForLength64()).add04Prefix() + modifiedPubKey = try combinePublicKeys(keys: [modifiedPubKey, noncePub], compressed: false) pubNonce = nonceResult?.pubNonce - } let (oAuthX, oAuthY) = try getPublicKeyPointFromPubkeyString(pubKey: oAuthPubKeyString) let (finalX, finalY) = try getPublicKeyPointFromPubkeyString(pubKey: modifiedPubKey) - + let oAuthAddress = generateAddressFromPubKey(publicKeyX: oAuthX, publicKeyY: oAuthY) let finalAddress = generateAddressFromPubKey(publicKeyX: finalX, publicKeyY: finalY) - + return .init( finalKeyData: .init( evmAddress: finalAddress, @@ -169,19 +148,17 @@ open class TorusUtils: AbstractTorusUtils { ), nodesData: .init(nodeIndexes: nodeIndexes) ) - + } catch { throw error } } - - // Legacy private func getLegacyPublicAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, enableOneKey: Bool) async throws -> TorusPublicKey { do { var data: LegacyKeyLookupResponse - var isNewKey = false; + var isNewKey = false do { data = try await legacyKeyLookup(endpoints: endpoints, verifier: verifier, verifierId: verifierId) @@ -205,306 +182,302 @@ open class TorusUtils: AbstractTorusUtils { throw error } } - + private func legacyRetrieveShares(torusNodePubs: [TorusNodePubModel], - indexes : [BigUInt], + indexes: [BigUInt], endpoints: [String], verifier: String, verifierId: String, idToken: String, extraParams: [String: Codable]) async throws -> TorusKey { - return try await withThrowingTaskGroup(of: TorusKey.self, body: { [unowned self] group in - group.addTask { [unowned self] in - try await handleRetrieveShares(torusNodePubs: torusNodePubs, - indexes: indexes, - endpoints: endpoints, verifier: verifier, verifierId: verifierId, idToken: idToken, extraParams: extraParams) - } - group.addTask { [unowned self] in - // 60 second timeout for login - try await _Concurrency.Task.sleep(nanoseconds: UInt64(timeout * 60_000_000_000)) - throw TorusUtilError.timeout - } + return try await withThrowingTaskGroup(of: TorusKey.self, body: { [unowned self] group in + group.addTask { [unowned self] in + try await handleRetrieveShares(torusNodePubs: torusNodePubs, + indexes: indexes, + endpoints: endpoints, verifier: verifier, verifierId: verifierId, idToken: idToken, extraParams: extraParams) + } + group.addTask { [unowned self] in + // 60 second timeout for login + try await _Concurrency.Task.sleep(nanoseconds: UInt64(timeout * 60000000000)) + throw TorusUtilError.timeout + } - do { - for try await val in group { - try Task.checkCancellation() - group.cancelAll() - return val - } - } catch { + do { + for try await val in group { + try Task.checkCancellation() group.cancelAll() - throw error + return val } - throw TorusUtilError.timeout - }) - } - - private func handleRetrieveShares(torusNodePubs: [TorusNodePubModel], - indexes : [BigUInt], - endpoints: [String], verifier: String, verifierId: String, idToken: String, extraParams: [String: Codable]) async throws -> TorusKey { - guard - let privateKey = generatePrivateKeyData(), - let publicKey = SECP256K1.privateToPublic(privateKey: privateKey)?.subdata(in: 1 ..< 65) - else { - throw TorusUtilError.runtime("Unable to generate SECP256K1 keypair.") + } catch { + group.cancelAll() + throw error } + throw TorusUtilError.timeout + }) + } - // Split key in 2 parts, X and Y - // let publicKeyHex = publicKey.toHexString() - let pubKeyX = publicKey.prefix(publicKey.count / 2).toHexString().addLeading0sForLength64() - let pubKeyY = publicKey.suffix(publicKey.count / 2).toHexString().addLeading0sForLength64() + private func handleRetrieveShares(torusNodePubs: [TorusNodePubModel], + indexes: [BigUInt], + endpoints: [String], verifier: String, verifierId: String, idToken: String, extraParams: [String: Codable]) async throws -> TorusKey { + let privateKey = try secp256k1.KeyAgreement.PrivateKey(format: .uncompressed) + let serializedPublicKey = privateKey.publicKey.dataRepresentation.hexString - // Hash the token from OAuth login + // Split key in 2 parts, X and Y + // let publicKeyHex = publicKey.toHexString() + let pubKeyX = String(serializedPublicKey.suffix(128).prefix(64)) + let pubKeyY = String(serializedPublicKey.suffix(64)) - let timestamp = String(Int(getTimestamp())) - let hashedToken = idToken.sha3(.keccak256) + // Hash the token from OAuth login - var lookupPubkeyX: String = "" - var lookupPubkeyY: String = "" - do { - let getPublicAddressData = try await getPublicAddress(endpoints: endpoints, torusNodePubs: torusNodePubs, verifier: verifier, verifierId: verifierId) - let publicAddress = getPublicAddressData.finalKeyData!.evmAddress - let localPubkeyX = getPublicAddressData.finalKeyData!.X.addLeading0sForLength64() - let localPubkeyY = getPublicAddressData.finalKeyData!.Y.addLeading0sForLength64() - lookupPubkeyX = localPubkeyX - lookupPubkeyY = localPubkeyY - let commitmentRequestData = try await commitmentRequest(endpoints: endpoints, verifier: verifier, pubKeyX: pubKeyX, pubKeyY: pubKeyY, timestamp: timestamp, tokenCommitment: hashedToken) - os_log("retrieveShares - data after commitment request: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, commitmentRequestData) - - let (oAuthKeyX, oAuthKeyY, oAuthKey) = try await retrieveDecryptAndReconstruct( - endpoints: endpoints, - indexes: indexes, - extraParams: extraParams, verifier: verifier, tokenCommitment: idToken, nodeSignatures: commitmentRequestData, verifierId: verifierId, lookupPubkeyX: lookupPubkeyX, lookupPubkeyY: lookupPubkeyY, privateKey: privateKey.toHexString()) - - var metadataNonce: BigUInt - var typeOfUser: UserType = .v1 - var pubKeyNonceResult: PubNonce? - var finalPubKey: String = "" - - if enableOneKey { - let nonceResult = try await getOrSetNonce(x: oAuthKeyX, y: oAuthKeyY, privateKey: oAuthKey, getOnly: true) - metadataNonce = BigUInt(nonceResult.nonce ?? "0", radix: 16) ?? 0 - typeOfUser = UserType(rawValue: nonceResult.typeOfUser!)! - if (typeOfUser == .v2) { - finalPubKey = "04" + oAuthKeyX.addLeading0sForLength64() + oAuthKeyY.addLeading0sForLength64() - let newkey = "04" + (nonceResult.pubNonce?.x.addLeading0sForLength64())! + (nonceResult.pubNonce?.y.addLeading0sForLength64())! - finalPubKey = combinePublicKeys(keys: [finalPubKey, newkey], compressed: false) - pubKeyNonceResult = .init(x: nonceResult.pubNonce!.x, y: nonceResult.pubNonce!.y) - } - + let timestamp = String(Int(getTimestamp())) + let hashedToken = idToken.sha3(.keccak256) + var lookupPubkeyX: String = "" + var lookupPubkeyY: String = "" + do { + let getPublicAddressData = try await getPublicAddress(endpoints: endpoints, torusNodePubs: torusNodePubs, verifier: verifier, verifierId: verifierId) + guard (getPublicAddressData.finalKeyData?.evmAddress) != nil + else { + throw TorusUtilError.runtime("Unable to provide evmAddress") + } + let localPubkeyX = getPublicAddressData.finalKeyData!.X.addLeading0sForLength64() + let localPubkeyY = getPublicAddressData.finalKeyData!.Y.addLeading0sForLength64() + lookupPubkeyX = localPubkeyX + lookupPubkeyY = localPubkeyY + let commitmentRequestData = try await commitmentRequest(endpoints: endpoints, verifier: verifier, pubKeyX: pubKeyX, pubKeyY: pubKeyY, timestamp: timestamp, tokenCommitment: hashedToken) + os_log("retrieveShares - data after commitment request: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, commitmentRequestData) + + let (oAuthKeyX, oAuthKeyY, oAuthKey) = try await retrieveDecryptAndReconstruct( + endpoints: endpoints, + indexes: indexes, + extraParams: extraParams, verifier: verifier, tokenCommitment: idToken, nodeSignatures: commitmentRequestData, verifierId: verifierId, lookupPubkeyX: lookupPubkeyX, lookupPubkeyY: lookupPubkeyY, privateKey: privateKey.rawRepresentation.hexString) + + var metadataNonce: BigUInt + var typeOfUser: UserType = .v1 + var pubKeyNonceResult: PubNonce? + var finalPubKey: String = "" + + if enableOneKey { + let nonceResult = try await getOrSetNonce(x: oAuthKeyX, y: oAuthKeyY, privateKey: oAuthKey, getOnly: true) + metadataNonce = BigUInt(nonceResult.nonce ?? "0", radix: 16) ?? 0 + let nonceType = nonceResult.typeOfUser ?? "v1" + typeOfUser = UserType(rawValue: nonceType) ?? UserType.v1 + if typeOfUser == .v2 { + finalPubKey = (oAuthKeyX.addLeading0sForLength64() + oAuthKeyY.addLeading0sForLength64()).add04Prefix() + let newkey = ((nonceResult.pubNonce?.x.addLeading0sForLength64())! + (nonceResult.pubNonce?.y.addLeading0sForLength64())!).add04Prefix() + finalPubKey = try combinePublicKeys(keys: [finalPubKey, newkey], compressed: false) + pubKeyNonceResult = .init(x: nonceResult.pubNonce!.x, y: nonceResult.pubNonce!.y) } else { // for imported keys in legacy networks metadataNonce = try await getMetadata(dictionary: ["pub_key_X": oAuthKeyX, "pub_key_Y": oAuthKeyY]) var privateKeyWithNonce = BigInt(metadataNonce) + BigInt(oAuthKey, radix: 16)! privateKeyWithNonce = privateKeyWithNonce.modulus(modulusValue) - finalPubKey = (SECP256K1.privateToPublic(privateKey: Data(hex: String(privateKeyWithNonce, radix: 16).addLeading0sForLength64()))?.toHexString())! - - } - - let oAuthKeyAddress = generateAddressFromPubKey(publicKeyX: oAuthKeyX, publicKeyY: oAuthKeyY) - let (finalPubX, finalPubY) = try getPublicKeyPointFromPubkeyString(pubKey: finalPubKey) - let finalEvmAddress = generateAddressFromPubKey(publicKeyX: finalPubX, publicKeyY: finalPubY) - - var finalPrivKey = "" - if typeOfUser == .v1 || (typeOfUser == .v2 && metadataNonce > BigInt(0)) { - let tempNewKey = BigInt(metadataNonce) + BigInt(oAuthKey, radix: 16)! - let privateKeyWithNonce = tempNewKey.modulus(modulusValue) - finalPrivKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64() - } - - var isUpgraded : Bool? = false - if typeOfUser == .v1 { - isUpgraded = nil - } else if typeOfUser == .v2 { - isUpgraded = metadataNonce == BigUInt(0) + let serializedKey = Data(hex: privateKeyWithNonce.magnitude.serialize().hexString.addLeading0sForLength64()) + let finalPrivateKey = try secp256k1.KeyAgreement.PrivateKey(dataRepresentation: serializedKey, format: .uncompressed) + finalPubKey = finalPrivateKey.publicKey.dataRepresentation.hexString } - - return TorusKey( - finalKeyData: .init( - evmAddress: finalEvmAddress, - X: finalPubX, - Y: finalPubY, - privKey: finalPrivKey - ), - oAuthKeyData: .init( - evmAddress: oAuthKeyAddress, - X: oAuthKeyX, - Y: oAuthKeyY, - privKey: oAuthKey - ), - sessionData: .init( - sessionTokenData: [], - sessionAuthKey: "" - ), - metadata: .init( - pubNonce: pubKeyNonceResult, - nonce: BigUInt(metadataNonce), - typeOfUser: typeOfUser, - upgraded: isUpgraded - ), - nodesData: .init(nodeIndexes: []) - ) - } catch { - os_log("Error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) - throw error + } else { + // for imported keys in legacy networks + metadataNonce = try await getMetadata(dictionary: ["pub_key_X": oAuthKeyX, "pub_key_Y": oAuthKeyY]) + var privateKeyWithNonce = BigInt(metadataNonce) + BigInt(oAuthKey, radix: 16)! + privateKeyWithNonce = privateKeyWithNonce.modulus(modulusValue) + let finalPrivateKey = try secp256k1.KeyAgreement.PrivateKey(dataRepresentation: Data(hex: privateKeyWithNonce.magnitude.serialize().hexString.addLeading0sForLength64()), format: .uncompressed) + finalPubKey = finalPrivateKey.publicKey.dataRepresentation.hexString } + + let oAuthKeyAddress = generateAddressFromPubKey(publicKeyX: oAuthKeyX, publicKeyY: oAuthKeyY) + let (finalPubX, finalPubY) = try getPublicKeyPointFromPubkeyString(pubKey: finalPubKey) + let finalEvmAddress = generateAddressFromPubKey(publicKeyX: finalPubX, publicKeyY: finalPubY) + + var finalPrivKey = "" + if typeOfUser == .v1 || (typeOfUser == .v2 && metadataNonce > BigInt(0)) { + let tempNewKey = BigInt(metadataNonce) + BigInt(oAuthKey, radix: 16)! + let privateKeyWithNonce = tempNewKey.modulus(modulusValue) + finalPrivKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64() + } + + var isUpgraded: Bool? = false + if typeOfUser == .v1 { + isUpgraded = nil + } else if typeOfUser == .v2 { + isUpgraded = metadataNonce == BigUInt(0) + } + + return TorusKey( + finalKeyData: .init( + evmAddress: finalEvmAddress, + X: finalPubX, + Y: finalPubY, + privKey: finalPrivKey + ), + oAuthKeyData: .init( + evmAddress: oAuthKeyAddress, + X: oAuthKeyX, + Y: oAuthKeyY, + privKey: oAuthKey + ), + sessionData: .init( + sessionTokenData: [], + sessionAuthKey: "" + ), + metadata: .init( + pubNonce: pubKeyNonceResult, + nonce: BigUInt(metadataNonce), + typeOfUser: typeOfUser, + upgraded: isUpgraded + ), + nodesData: .init(nodeIndexes: []) + ) + } catch { + os_log("Error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) + throw error } - - open func generatePrivateKeyData() -> Data? { - return Data.randomOfLength(32) - } - - open func getTimestamp() -> TimeInterval { - return Date().timeIntervalSince1970 - } - + } + + open func getTimestamp() -> TimeInterval { + return Date().timeIntervalSince1970 + } + // MARK: - retreiveDecryptAndReconstuct - private func retrieveDecryptAndReconstruct(endpoints: [String], - indexes: [BigUInt], - extraParams: [String: Codable], verifier: String, tokenCommitment: String, nodeSignatures: [CommitmentRequestResponse], verifierId: String, lookupPubkeyX: String, lookupPubkeyY: String, privateKey: String) async throws -> (String, String, String) { - // Rebuild extraParams - let session = createURLSession() - let threshold = Int(endpoints.count / 2) + 1 - var rpcdata: Data = Data() - - let loadedStrings = extraParams - let valueDict = ["verifieridentifier": verifier, - "verifier_id": verifierId, - "nodesignatures": nodeSignatures.tostringDict(), - "idtoken": tokenCommitment - ] as [String: Codable] - let finalItem = loadedStrings.merging(valueDict) { current, _ in current } - let params = ["encrypted": "yes", - "item": AnyCodable([finalItem]) - ] as [String: AnyCodable] - - let dataForRequest = ["jsonrpc": "2.0", - "id": 10, - "method": AnyCodable(JRPC_METHODS.LEGACY_SHARE_REQUEST), - "params": AnyCodable(params) - ] as [String: AnyCodable] + private func retrieveDecryptAndReconstruct(endpoints: [String], + indexes: [BigUInt], + extraParams: [String: Codable], verifier: String, tokenCommitment: String, nodeSignatures: [CommitmentRequestResponse], verifierId: String, lookupPubkeyX: String, lookupPubkeyY: String, privateKey: String) async throws -> (String, String, String) { + // Rebuild extraParams + let session = createURLSession() + let threshold = Int(endpoints.count / 2) + 1 + var rpcdata: Data = Data() + + let loadedStrings = extraParams + let valueDict = ["verifieridentifier": verifier, + "verifier_id": verifierId, + "nodesignatures": nodeSignatures.tostringDict(), + "idtoken": tokenCommitment, + ] as [String: Codable] + let finalItem = loadedStrings.merging(valueDict) { current, _ in current } + let params = ["encrypted": "yes", + "item": AnyCodable([finalItem]), + ] as [String: AnyCodable] + + let dataForRequest = ["jsonrpc": "2.0", + "id": 10, + "method": AnyCodable(JRPC_METHODS.LEGACY_SHARE_REQUEST), + "params": AnyCodable(params), + ] as [String: AnyCodable] + do { + rpcdata = try JSONEncoder().encode(dataForRequest) + } catch { + os_log("import share - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) + } + + var shareResponses: [PointHex?] = [] + var resultArray = [Int: RetrieveDecryptAndReconstuctResponseModel]() + var errorStack = [Error]() + var requestArr = [URLRequest]() + for (_, el) in endpoints.enumerated() { do { - rpcdata = try JSONEncoder().encode(dataForRequest) + var rq = try makeUrlRequest(url: el) + rq.httpBody = rpcdata + requestArr.append(rq) } catch { - os_log("import share - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) - } - - - var shareResponses : [PointHex] = [] - var resultArray = [Int: RetrieveDecryptAndReconstuctResponseModel]() - var errorStack = [Error]() - var requestArr = [URLRequest]() - for (_, el) in endpoints.enumerated() { - do { - var rq = try makeUrlRequest(url: el) - rq.httpBody = rpcdata - requestArr.append(rq) - } catch { - throw error - } + throw error } - return try await withThrowingTaskGroup(of: Result.self, body: {[unowned self] group in - for (i, rq) in requestArr.enumerated() { - group.addTask { - do { - let val = try await session.data(for: rq) - return .success(.init(data: val.0, urlResponse: val.1, index: i)) - } catch { - return .failure(error) - } + } + return try await withThrowingTaskGroup(of: Result.self, body: { [unowned self] group in + for (i, rq) in requestArr.enumerated() { + group.addTask { + do { + let val = try await session.data(for: rq) + return .success(.init(data: val.0, urlResponse: val.1, index: i)) + } catch { + return .failure(error) } } + } - for try await val in group { - do { - try Task.checkCancellation() - switch val { - case .success(let model): - let _data = model.data -// let i = Int(indexes[model.index]) - let i = Int(indexes[model.index]) - 1 - - - let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: _data) - - if decoded.error != nil { - throw TorusUtilError.decodingFailed(decoded.error?.data) - } - os_log("retrieveDecryptAndReconstuct: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, "\(decoded)") - var X = lookupPubkeyX.addLeading0sForLength64() - var Y = lookupPubkeyY.addLeading0sForLength64() - if let decodedResult = decoded.result as? LegacyLookupResponse { - // case non migration - let keyObj = decodedResult.keys - if let first = keyObj.first { - let pointHex = PointHex(from: first.publicKey) - shareResponses.append(pointHex) - let metadata = first.metadata - let model = RetrieveDecryptAndReconstuctResponseModel(iv: metadata.iv, ephemPublicKey: metadata.ephemPublicKey, share: first.share, pubKeyX: pointHex.x, pubKeyY: pointHex.y) - resultArray[i] = model - } - } else if let decodedResult = decoded.result as? LegacyShareRequestResult { - // case migration - let keyObj = decodedResult.keys - if let first = keyObj.first { - let pointHex = PointHex(from: .init(x: first.publicKey.X, y: first.publicKey.Y)) - shareResponses.append(pointHex) - let metadata = first.metadata - X = pointHex.x - Y = pointHex.y - let model = RetrieveDecryptAndReconstuctResponseModel(iv: metadata.iv, ephemPublicKey: metadata.ephemPublicKey, share: first.share, pubKeyX: pointHex.x, pubKeyY: pointHex.y) - resultArray[i] = model - } - } else { - TorusUtilError.runtime("decode fail") + for try await val in group { + do { + try Task.checkCancellation() + switch val { + case let .success(model): + let _data = model.data + let i = Int(indexes[model.index]) - 1 + + let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: _data) + + if decoded.error != nil { + throw TorusUtilError.decodingFailed(decoded.error?.data) + } + os_log("retrieveDecryptAndReconstuct: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, "\(decoded)") + var X = lookupPubkeyX.addLeading0sForLength64() + var Y = lookupPubkeyY.addLeading0sForLength64() + if let decodedResult = decoded.result as? LegacyLookupResponse { + // case non migration + let keyObj = decodedResult.keys + if let first = keyObj.first { + let pointHex = PointHex(from: first.publicKey) + shareResponses.append(pointHex) + let metadata = first.metadata + let model = RetrieveDecryptAndReconstuctResponseModel(iv: metadata.iv, ephemPublicKey: metadata.ephemPublicKey, share: first.share, pubKeyX: pointHex.x, pubKeyY: pointHex.y) + resultArray[i] = model } - - // Due to multiple keyAssign - - let lookupShares = shareResponses.filter { $0 != nil } // Nonnil elements - - // Comparing dictionaries, so the order of keys doesn't matter - let keyResult = thresholdSame(arr: lookupShares.map { $0 }, threshold: threshold) // Check if threshold is satisfied - var data: [Int: String] = [:] - if keyResult != nil { - os_log("retreiveIndividualNodeShares - result: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, resultArray) - data = try decryptIndividualShares(shares: resultArray, privateKey: privateKey) - } else { - throw TorusUtilError.empty + } else if let decodedResult = decoded.result as? LegacyShareRequestResult { + // case migration + let keyObj = decodedResult.keys + if let first = keyObj.first { + let pointHex = PointHex(from: .init(x: first.publicKey.X, y: first.publicKey.Y)) + shareResponses.append(pointHex) + let metadata = first.metadata + X = pointHex.x + Y = pointHex.y + let model = RetrieveDecryptAndReconstuctResponseModel(iv: metadata.iv, ephemPublicKey: metadata.ephemPublicKey, share: first.share, pubKeyX: pointHex.x, pubKeyY: pointHex.y) + resultArray[i] = model } - os_log("retrieveDecryptAndReconstuct - data after decryptIndividualShares: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, data) - let filteredData = data.filter { $0.value != TorusUtilError.decodingFailed(nil).debugDescription } - - - if filteredData.count < threshold { throw TorusUtilError.thresholdError } - let thresholdLagrangeInterpolationData = try thresholdLagrangeInterpolation(data: filteredData, endpoints: endpoints, lookupPubkeyX: X.addLeading0sForLength64(), lookupPubkeyY: Y.addLeading0sForLength64()) - session.invalidateAndCancel() - return thresholdLagrangeInterpolationData - case .failure(let error): - throw error - } - } catch { - errorStack.append(error) - let nsErr = error as NSError - let userInfo = nsErr.userInfo as [String: Any] - if error as? TorusUtilError == .timeout { - group.cancelAll() - session.invalidateAndCancel() - throw error + } else { + throw TorusUtilError.runtime("decode fail") } - if nsErr.code == -1003 { - // In case node is offline - os_log("retrieveDecryptAndReconstuct: DNS lookup failed, node %@ is probably offline.", log: getTorusLogger(log: TorusUtilsLogger.network, type: .error), type: .error, userInfo["NSErrorFailingURLKey"].debugDescription) - } else if let err = (error as? TorusUtilError) { - if err == TorusUtilError.thresholdError { - os_log("retrieveDecryptAndReconstuct - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) - } + + // Due to multiple keyAssign + + let lookupShares = shareResponses.filter { $0 != nil } // Nonnil elements + + // Comparing dictionaries, so the order of keys doesn't matter + let keyResult = thresholdSame(arr: lookupShares.map { $0 }, threshold: threshold) // Check if threshold is satisfied + var data: [Int: String] = [:] + if keyResult != nil { + os_log("retreiveIndividualNodeShares - result: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, resultArray) + data = try decryptIndividualShares(shares: resultArray, privateKey: privateKey) } else { + throw TorusUtilError.empty + } + os_log("retrieveDecryptAndReconstuct - data after decryptIndividualShares: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, data) + let filteredData = data.filter { $0.value != TorusUtilError.decodingFailed(nil).debugDescription } + + if filteredData.count < threshold { throw TorusUtilError.thresholdError } + let thresholdLagrangeInterpolationData = try thresholdLagrangeInterpolation(data: filteredData, endpoints: endpoints, lookupPubkeyX: X.addLeading0sForLength64(), lookupPubkeyY: Y.addLeading0sForLength64()) + session.invalidateAndCancel() + return thresholdLagrangeInterpolationData + case let .failure(error): + throw error + } + } catch { + errorStack.append(error) + let nsErr = error as NSError + let userInfo = nsErr.userInfo as [String: Any] + if error as? TorusUtilError == .timeout { + group.cancelAll() + session.invalidateAndCancel() + throw error + } + if nsErr.code == -1003 { + // In case node is offline + os_log("retrieveDecryptAndReconstuct: DNS lookup failed, node %@ is probably offline.", log: getTorusLogger(log: TorusUtilsLogger.network, type: .error), type: .error, userInfo["NSErrorFailingURLKey"].debugDescription) + } else if let err = (error as? TorusUtilError) { + if err == TorusUtilError.thresholdError { os_log("retrieveDecryptAndReconstuct - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) } + } else { + os_log("retrieveDecryptAndReconstuct - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription) } } - throw TorusUtilError.runtime("retrieveDecryptAndReconstuct func failed") - }) - - } - + } + throw TorusUtilError.runtime("retrieveDecryptAndReconstuct func failed") + }) + } } diff --git a/Tests/TorusUtilsTests/AquaTest.swift b/Tests/TorusUtilsTests/AquaTest.swift index 3a95249e..8d1d9696 100644 --- a/Tests/TorusUtilsTests/AquaTest.swift +++ b/Tests/TorusUtilsTests/AquaTest.swift @@ -1,16 +1,11 @@ -// -// PolygonTest.swift -// -// -// Created by Dhruv Jaiswal on 01/06/22. -// - import BigInt +import CommonSources import FetchNodeDetails import JWTKit -import secp256k1 +#if canImport(secp256k1) + import secp256k1 +#endif import XCTest -import CommonSources import CoreMedia @testable import TorusUtils @@ -26,7 +21,7 @@ class AquaTest: XCTestCase { override func setUp() { super.setUp() - fnd = NodeDetailManager( network: .legacy(.AQUA)) + fnd = NodeDetailManager(network: .legacy(.AQUA)) } func getFNDAndTUData(verifer: String, veriferID: String, enableOneKey: Bool = false) async throws -> AllNodeDetailsModel { @@ -35,202 +30,148 @@ class AquaTest: XCTestCase { return nodeDetails } - func test_get_public_address() async { - let exp1 = XCTestExpectation(description: "should fetch public address") + func test_should_fetch_public_address() async throws { let verifier: String = "tkey-google-aqua" let verifierID: String = TORUS_TEST_EMAIL - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let val = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertEqual(val.finalKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d") - XCTAssertEqual(val.finalKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d") - XCTAssertEqual(val.finalKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c") - XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d") - XCTAssertEqual(val.oAuthKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d") - XCTAssertEqual(val.oAuthKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c") - XCTAssertNil(val.metadata?.pubNonce) - XCTAssertEqual(val.metadata?.nonce, 0) - XCTAssertEqual(val.metadata?.upgraded, false) - XCTAssertEqual(val.metadata?.typeOfUser, UserType(rawValue: "v1")) - XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let val = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertEqual(val.finalKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d") + XCTAssertEqual(val.finalKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d") + XCTAssertEqual(val.finalKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c") + XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d") + XCTAssertEqual(val.oAuthKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d") + XCTAssertEqual(val.oAuthKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c") + XCTAssertNil(val.metadata?.pubNonce) + XCTAssertEqual(val.metadata?.nonce, 0) + XCTAssertEqual(val.metadata?.upgraded, false) + XCTAssertEqual(val.metadata?.typeOfUser, UserType(rawValue: "v1")) + XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) } - func test_getUserTypeAndAddress_aqua() async { - let exp1 = XCTestExpectation(description: "should fetch user type and public address") - let exp2 = XCTestExpectation(description: "should fetch user type and public address") - let exp3 = XCTestExpectation(description: "should fetch user type and public address") + func test_should_fetch_user_type_and_public_addresses() async throws { var verifier: String = "tkey-google-aqua" var verifierID: String = TORUS_TEST_EMAIL - do { - var nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - var val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d") - XCTAssertEqual(val.oAuthKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d") - XCTAssertEqual(val.oAuthKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c") - XCTAssertEqual(val.finalKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d") - XCTAssertEqual(val.finalKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d") - XCTAssertEqual(val.finalKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c") - XCTAssertNil(val.metadata?.pubNonce) - XCTAssertEqual(val.metadata?.nonce, 0) - XCTAssertEqual(val.metadata?.upgraded, false) - XCTAssertEqual(val.metadata?.typeOfUser, .v1) - XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) - exp1.fulfill() - - // exp2 - verifier = "tkey-google-aqua" - verifierID = "somev2user@gmail.com" - nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x4ea5260fF85678A2a326D08DF9C44d1f559a5828") - XCTAssertEqual(val.oAuthKeyData!.X, "0e6febe33a9d4eeb680cc6b63ff6237ad1971f27adcd7f104a3b1de18eda9337") - XCTAssertEqual(val.oAuthKeyData!.Y, "a5a915561f3543688e71281a850b9ee10b9690f305d9e79028dfc8359192b82d") - XCTAssertEqual(val.finalKeyData!.evmAddress, "0x4ea5260fF85678A2a326D08DF9C44d1f559a5828") - XCTAssertEqual(val.finalKeyData!.X, "0e6febe33a9d4eeb680cc6b63ff6237ad1971f27adcd7f104a3b1de18eda9337") - XCTAssertEqual(val.finalKeyData!.Y, "a5a915561f3543688e71281a850b9ee10b9690f305d9e79028dfc8359192b82d") - XCTAssertEqual(val.metadata?.nonce, 0) - XCTAssertEqual(val.metadata?.upgraded, false) - XCTAssertEqual(val.metadata?.typeOfUser, .v1) - XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) - exp2.fulfill() - - // exp3 - verifierID = "caspertorus@gmail.com" - nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD") - XCTAssertEqual(val.oAuthKeyData!.X, "e76d2f7fa2c0df324b4ab74629c3af47aa4609c35f1d2b6b90b77a47ab9a1281") - XCTAssertEqual(val.oAuthKeyData!.Y, "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f") - XCTAssertEqual(val.finalKeyData!.evmAddress, "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD") - XCTAssertEqual(val.finalKeyData!.X, "e76d2f7fa2c0df324b4ab74629c3af47aa4609c35f1d2b6b90b77a47ab9a1281") - XCTAssertEqual(val.finalKeyData!.Y, "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f") - XCTAssertEqual(val.metadata?.nonce, 0) - XCTAssertEqual(val.metadata?.upgraded, false) - XCTAssertEqual(val.metadata?.typeOfUser, .v1) - XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) - exp2.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - exp2.fulfill() - exp3.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + var val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d") + XCTAssertEqual(val.oAuthKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d") + XCTAssertEqual(val.oAuthKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c") + XCTAssertEqual(val.finalKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d") + XCTAssertEqual(val.finalKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d") + XCTAssertEqual(val.finalKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c") + XCTAssertNil(val.metadata?.pubNonce) + XCTAssertEqual(val.metadata?.nonce, 0) + XCTAssertEqual(val.metadata?.upgraded, false) + XCTAssertEqual(val.metadata?.typeOfUser, .v1) + XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) + + verifier = "tkey-google-aqua" + verifierID = "somev2user@gmail.com" + val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x5735dDC8d5125B23d77C3531aab3895A533584a3") + XCTAssertEqual(val.oAuthKeyData!.X, "e1b419bc52b82e14b148c307f10479cfa464d20c947555fb4758c586eab12873") + XCTAssertEqual(val.oAuthKeyData!.Y, "75f47d7d5a271c0fcf51a790c1683a1cb3394b1d37d20e29c346ac249e3bfca2") + XCTAssertEqual(val.finalKeyData!.evmAddress, "0x5735dDC8d5125B23d77C3531aab3895A533584a3") + XCTAssertEqual(val.finalKeyData!.X, "e1b419bc52b82e14b148c307f10479cfa464d20c947555fb4758c586eab12873") + XCTAssertEqual(val.finalKeyData!.Y, "75f47d7d5a271c0fcf51a790c1683a1cb3394b1d37d20e29c346ac249e3bfca2") + XCTAssertEqual(val.finalKeyData!.evmAddress, "0x5735dDC8d5125B23d77C3531aab3895A533584a3") + XCTAssertEqual(val.metadata?.nonce, 0) + XCTAssertEqual(val.metadata?.upgraded, false) + XCTAssertEqual(val.metadata?.typeOfUser, .v1) + XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) + + verifierID = "caspertorus@gmail.com" + val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD") + XCTAssertEqual(val.oAuthKeyData!.X, "e76d2f7fa2c0df324b4ab74629c3af47aa4609c35f1d2b6b90b77a47ab9a1281") + XCTAssertEqual(val.oAuthKeyData!.Y, "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f") + XCTAssertEqual(val.finalKeyData!.evmAddress, "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD") + XCTAssertEqual(val.finalKeyData!.X, "e76d2f7fa2c0df324b4ab74629c3af47aa4609c35f1d2b6b90b77a47ab9a1281") + XCTAssertEqual(val.finalKeyData!.Y, "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f") + XCTAssertEqual(val.metadata?.nonce, 0) + XCTAssertEqual(val.metadata?.upgraded, false) + XCTAssertEqual(val.metadata?.typeOfUser, .v1) + XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) } - func test_key_assign_aqua() async { - let exp1 = XCTestExpectation(description: "should be able to key assign") + func test_key_assign() async throws { let fakeEmail = generateRandomEmail(of: 6) let verifier: String = "tkey-google-aqua" let verifierID: String = fakeEmail - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertNotNil(data.finalKeyData) - XCTAssertNotEqual(data.finalKeyData?.evmAddress, "") - XCTAssertEqual(data.metadata?.typeOfUser, .v1) - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertNotNil(data.finalKeyData) + XCTAssertNotEqual(data.finalKeyData?.evmAddress, "") + XCTAssertEqual(data.metadata?.typeOfUser, .v1) + XCTAssertEqual(data.metadata?.upgraded, false) } - func test_login_aqua() async { - let exp1 = XCTestExpectation(description: "should be able to login") + func test_login() async throws { let verifier: String = TORUS_TEST_VERIFIER let verifierID: String = TORUS_TEST_EMAIL let verifierParams = VerifierParams(verifier_id: verifierID) let jwt = try! generateIdToken(email: verifierID) let extraParams = ["verifieridentifier": verifier, "verifier_id": verifierID] as [String: Codable] - let buffer: Data = try! NSKeyedArchiver.archivedData(withRootObject: extraParams, requiringSecureCoding: false) - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.retrieveShares( endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(),indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) - XCTAssertEqual(data.finalKeyData?.evmAddress, "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195") - XCTAssertEqual(data.finalKeyData?.X, "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664") - XCTAssertEqual(data.finalKeyData?.Y, "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f") - XCTAssertEqual(data.finalKeyData?.privKey, "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d") - XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195") - XCTAssertEqual(data.oAuthKeyData?.X, "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664") - XCTAssertEqual(data.oAuthKeyData?.Y, "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f") - XCTAssertEqual(data.oAuthKeyData?.privKey, "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d") - XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0) - XCTAssertEqual(data.sessionData?.sessionAuthKey, "") - XCTAssertEqual(data.metadata?.pubNonce, nil) - XCTAssertEqual(data.metadata?.nonce, BigUInt(0)) - XCTAssertEqual(data.metadata?.typeOfUser, .v1) - XCTAssertEqual(data.metadata?.upgraded, nil) - XCTAssertEqual(data.nodesData?.nodeIndexes.count, 0) - - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + XCTAssertEqual(data.finalKeyData?.evmAddress, "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195") + XCTAssertEqual(data.finalKeyData?.X, "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664") + XCTAssertEqual(data.finalKeyData?.Y, "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f") + XCTAssertEqual(data.finalKeyData?.privKey, "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d") + XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195") + XCTAssertEqual(data.oAuthKeyData?.X, "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664") + XCTAssertEqual(data.oAuthKeyData?.Y, "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f") + XCTAssertEqual(data.oAuthKeyData?.privKey, "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d") + XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0) + XCTAssertEqual(data.sessionData?.sessionAuthKey, "") + XCTAssertEqual(data.metadata?.pubNonce, nil) + XCTAssertEqual(data.metadata?.nonce, BigUInt(0)) + XCTAssertEqual(data.metadata?.typeOfUser, .v1) + XCTAssertEqual(data.metadata?.upgraded, nil) + XCTAssertEqual(data.nodesData?.nodeIndexes.count, 0) } - func test_aggregate_login_aqua() async throws { - let exp1 = XCTestExpectation(description: "should be able to aggregate login") + func test_aggregate_login() async throws { let verifier: String = TORUS_TEST_AGGREGATE_VERIFIER let verifierID: String = TORUS_TEST_EMAIL let verifierParams = VerifierParams(verifier_id: verifierID) let jwt = try! generateIdToken(email: TORUS_TEST_EMAIL) let hashedIDToken = jwt.sha3(.keccak256) let extraParams = ["verifier_id": TORUS_TEST_EMAIL, "sub_verifier_ids": [TORUS_TEST_VERIFIER], "verify_params": [["verifier_id": TORUS_TEST_EMAIL, "idtoken": jwt]]] as [String: Codable] - let buffer: Data = try! NSKeyedArchiver.archivedData(withRootObject: extraParams, requiringSecureCoding: false) - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(),indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams) - XCTAssertEqual(data.finalKeyData?.evmAddress, "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D") - XCTAssertEqual(data.finalKeyData?.X, "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d") - XCTAssertEqual(data.finalKeyData?.Y, "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10") - XCTAssertEqual(data.finalKeyData?.privKey, "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355") - XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D") - XCTAssertEqual(data.oAuthKeyData?.X, "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d") - XCTAssertEqual(data.oAuthKeyData?.Y, "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10") - XCTAssertEqual(data.oAuthKeyData?.privKey, "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355") - XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0) - XCTAssertEqual(data.sessionData?.sessionAuthKey, "") - XCTAssertEqual(data.metadata?.pubNonce, nil) - XCTAssertEqual(data.metadata?.nonce, BigUInt(0)) - XCTAssertEqual(data.metadata?.typeOfUser, .v1) - XCTAssertEqual(data.metadata?.upgraded, nil) - XCTAssertEqual(data.nodesData?.nodeIndexes.count, 0) - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams) + XCTAssertEqual(data.finalKeyData?.evmAddress, "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D") + XCTAssertEqual(data.finalKeyData?.X, "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d") + XCTAssertEqual(data.finalKeyData?.Y, "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10") + XCTAssertEqual(data.finalKeyData?.privKey, "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355") + XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D") + XCTAssertEqual(data.oAuthKeyData?.X, "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d") + XCTAssertEqual(data.oAuthKeyData?.Y, "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10") + XCTAssertEqual(data.oAuthKeyData?.privKey, "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355") + XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0) + XCTAssertEqual(data.sessionData?.sessionAuthKey, "") + XCTAssertEqual(data.metadata?.pubNonce, nil) + XCTAssertEqual(data.metadata?.nonce, BigUInt(0)) + XCTAssertEqual(data.metadata?.typeOfUser, .v1) + XCTAssertEqual(data.metadata?.upgraded, nil) + XCTAssertEqual(data.nodesData?.nodeIndexes.count, 0) } } extension AquaTest { - func test_retrieveShares_some_nodes_down() async { - let exp1 = XCTestExpectation(description: "Should be able to getPublicAddress") + func test_retrieveShares_some_nodes_down() async throws { let verifier: String = TORUS_TEST_VERIFIER let verifierID: String = TORUS_TEST_EMAIL let verifierParams = VerifierParams(verifier_id: verifierID) let jwt = try! generateIdToken(email: verifierID) let extraParams = ["verifieridentifier": verifier, "verifier_id": verifierID] as [String: Codable] - let buffer: Data = try! NSKeyedArchiver.archivedData(withRootObject: extraParams, requiringSecureCoding: false) - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - var endpoints = nodeDetails.getTorusNodeEndpoints() - endpoints[0] = "https://ndjnfjbfrj/random" - // should fail if un-commented threshold 4/5 - // endpoints[1] = "https://ndjnfjbfrj/random" - let data = try await tu.retrieveShares(endpoints: endpoints, torusNodePubs: nodeDetails.getTorusNodePub(),indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) - XCTAssertEqual(data.finalKeyData?.privKey, "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d") - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + var endpoints = nodeDetails.getTorusNodeEndpoints() + endpoints[0] = "https://ndjnfjbfrj/random" + // should fail if un-commented threshold 4/5 + // endpoints[1] = "https://ndjnfjbfrj/random" + let data = try await tu.retrieveShares(endpoints: endpoints, torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) + XCTAssertEqual(data.finalKeyData?.privKey, "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d") } } diff --git a/Tests/TorusUtilsTests/CyanTest.swift b/Tests/TorusUtilsTests/CyanTest.swift index 8fdb94ad..959efec2 100644 --- a/Tests/TorusUtilsTests/CyanTest.swift +++ b/Tests/TorusUtilsTests/CyanTest.swift @@ -1,16 +1,11 @@ -// -// PolygonTest.swift -// -// -// Created by Dhruv Jaiswal on 01/06/22. -// - import BigInt +import CommonSources import FetchNodeDetails import JWTKit -import secp256k1 +#if canImport(secp256k1) + import secp256k1 +#endif import XCTest -import CommonSources import CoreMedia @testable import TorusUtils @@ -26,7 +21,6 @@ class CyanTest: XCTestCase { override func setUp() { super.setUp() -// fnd = FetchNodeDetails(proxyAddress: "0x9f072ba19b3370e512aa1b4bfcdaf97283168005", network: .CYAN) fnd = NodeDetailManager(network: .legacy(.CYAN)) } @@ -36,150 +30,135 @@ class CyanTest: XCTestCase { return nodeDetails } - func test_get_public_address() async { - let exp1 = XCTestExpectation(description: "should fetch public address") + func test_should_fetch_public_address() async throws { let verifier: String = "tkey-google-cyan" let verifierID: String = TORUS_TEST_EMAIL - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let val = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertEqual(val.finalKeyData!.evmAddress, "0xA3767911A84bE6907f26C572bc89426dDdDB2825") - XCTAssertEqual(val.finalKeyData!.X, "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a") - XCTAssertEqual(val.finalKeyData!.Y, "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1") - XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xA3767911A84bE6907f26C572bc89426dDdDB2825") - XCTAssertEqual(val.oAuthKeyData!.X, "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a") - XCTAssertEqual(val.oAuthKeyData!.Y, "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1") - XCTAssertNil(val.metadata?.pubNonce) - XCTAssertEqual(val.metadata?.nonce, 0) - XCTAssertEqual(val.metadata?.upgraded, false) - XCTAssertEqual(val.metadata?.typeOfUser, UserType(rawValue: "v1")) - XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let val = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertEqual(val.finalKeyData!.evmAddress, "0xA3767911A84bE6907f26C572bc89426dDdDB2825") + XCTAssertEqual(val.finalKeyData!.X, "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a") + XCTAssertEqual(val.finalKeyData!.Y, "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1") + XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xA3767911A84bE6907f26C572bc89426dDdDB2825") + XCTAssertEqual(val.oAuthKeyData!.X, "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a") + XCTAssertEqual(val.oAuthKeyData!.Y, "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1") + XCTAssertNil(val.metadata?.pubNonce) + XCTAssertEqual(val.metadata?.nonce, 0) + XCTAssertEqual(val.metadata?.upgraded, false) + XCTAssertEqual(val.metadata?.typeOfUser, UserType(rawValue: "v1")) + XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) } - func test_getUserTypeAndAddress_polygon() async { - let exp1 = XCTestExpectation(description: "Should be able to getPublicAddress") - let exp2 = XCTestExpectation(description: "Should be able to getPublicAddress") - let exp3 = XCTestExpectation(description: "Should be able to getPublicAddress") - var verifier: String = "tkey-google-cyan" - var verifierID: String = TORUS_TEST_EMAIL - do { - var nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - var data = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertEqual(data.finalKeyData?.evmAddress, "0xA3767911A84bE6907f26C572bc89426dDdDB2825") - exp1.fulfill() + func test_get_user_type_and_addresses() async throws { + var verifier: String = "tkey-google-cyan" + var verifierID: String = TORUS_TEST_EMAIL + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + var data = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0xA3767911A84bE6907f26C572bc89426dDdDB2825") + XCTAssertEqual(data.oAuthKeyData?.X, "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a") + XCTAssertEqual(data.oAuthKeyData?.Y, "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1") + XCTAssertEqual(data.finalKeyData?.evmAddress, "0xA3767911A84bE6907f26C572bc89426dDdDB2825") + XCTAssertEqual(data.finalKeyData?.X, "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a") + XCTAssertEqual(data.finalKeyData?.Y, "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1") + XCTAssertNil(data.metadata?.pubNonce) + XCTAssertEqual(data.metadata?.nonce, BigUInt.zero) + XCTAssertEqual(data.metadata?.upgraded, false) + XCTAssertEqual(data.metadata?.typeOfUser, .v1) + XCTAssertEqual(data.nodesData?.nodeIndexes, []) - // exp2 - verifier = "tkey-google-cyan" - verifierID = "somev2user@gmail.com" - nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - data = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertEqual(data.finalKeyData?.evmAddress, "0xdE6805586F158aE3C8B25bBB73eef33ED34883D3") - exp2.fulfill() + verifier = "tkey-google-cyan" + verifierID = "somev2user@gmail.com" + data = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x29446f428293a4E6470AEaEDa6EAfA0F842EF54e") + XCTAssertEqual(data.oAuthKeyData?.X, "8b6f2048aba8c7833e3b02c5b6522bb18c484ad0025156e428f17fb8d8c34021") + XCTAssertEqual(data.oAuthKeyData?.Y, "cd9ba153ff89d665f655d1be4c6912f3ff93996e6fe580d89e78bf1476fef2aa") + XCTAssertEqual(data.finalKeyData?.evmAddress, "0x8EA83Ace86EB414747F2b23f03C38A34E0217814") + XCTAssertEqual(data.finalKeyData?.X, "cbe7b0f0332e5583c410fcacb6d4ff685bec053cfd943ac75f5e4aa3278a6fbb") + XCTAssertEqual(data.finalKeyData?.Y, "b525c463f438c7a3c4b018c8c5d16c9ef33b9ac6f319140a22b48b17bdf532dd") + XCTAssertEqual(data.metadata?.pubNonce?.x, "da0039dd481e140090bed9e777ce16c0c4a16f30f47e8b08b73ac77737dd2d4") + XCTAssertEqual(data.metadata?.pubNonce?.y, "7fecffd2910fa47dbdbc989f5c119a668fc922937175974953cbb51c49268265") + XCTAssertEqual(data.metadata?.nonce, BigUInt.zero) + XCTAssertEqual(data.metadata?.upgraded, false) + XCTAssertEqual(data.metadata?.typeOfUser, .v2) + XCTAssertEqual(data.nodesData?.nodeIndexes, []) - // exp3 - verifier = "tkey-google-cyan" - verifierID = "caspertorus@gmail.com" - nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - data = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertEqual(data.finalKeyData?.evmAddress, "0xE6bcd804CBFfb95f750e32300517Ad9EC251dAFD") - exp3.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - exp2.fulfill() - exp3.fulfill() - } - } + verifier = "tkey-google-cyan" + verifierID = "caspertorus@gmail.com" + data = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0xe8a19482cbe5FaC896A5860Ca4156fb999DDc73b") + XCTAssertEqual(data.oAuthKeyData?.X, "c491ba39155594896b27cf71a804ccf493289d918f40e6ba4d590f1c76139e9e") + XCTAssertEqual(data.oAuthKeyData?.Y, "d4649ed9e46461e1af00399a4c65fabb1dc219b3f4af501a7d635c17f57ab553") + XCTAssertEqual(data.finalKeyData?.evmAddress, "0xCC1f953f6972a9e3d685d260399D6B85E2117561") + XCTAssertEqual(data.finalKeyData?.X, "8d784434becaad9b23d9293d1f29c4429447315c4cac824cbf2eb21d3f7d79c8") + XCTAssertEqual(data.finalKeyData?.Y, "fe46a0ef5efe33d16f6cfa678a597be930fbec5432cbb7f3580189c18bd7e157") + XCTAssertEqual(data.metadata?.pubNonce?.x, "50e250cc6ac1d50d32d2b0f85f11c6625a917a115ced4ef24f4eac183e1525c7") + XCTAssertEqual(data.metadata?.pubNonce?.y, "8067a52d02b8214bf82e91b66ce5009f674f4c3998b103059c46c386d0c17f90") + XCTAssertEqual(data.metadata?.nonce, BigUInt.zero) + XCTAssertEqual(data.metadata?.upgraded, false) + XCTAssertEqual(data.metadata?.typeOfUser, .v2) + XCTAssertEqual(data.nodesData?.nodeIndexes, []) + } - func test_key_assign_polygon() async { - let exp1 = XCTestExpectation(description: "should be able to key assign") + func test_key_assign() async throws { let fakeEmail = generateRandomEmail(of: 6) let verifier: String = "tkey-google-cyan" let verifierID: String = fakeEmail - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertNotNil(data) - XCTAssertNotEqual(data.finalKeyData?.evmAddress, "") - XCTAssertEqual(data.metadata?.typeOfUser, .v1) - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertNotEqual(data.finalKeyData?.evmAddress, "") + XCTAssertNotEqual(data.oAuthKeyData?.evmAddress, "") + XCTAssertEqual(data.metadata?.typeOfUser, .v1) + XCTAssertEqual(data.metadata?.upgraded, false) } - func test_login_polygon() async { - let exp1 = XCTestExpectation(description: "Should be able to login") + func test_login() async throws { let verifier: String = TORUS_TEST_VERIFIER let verifierID: String = TORUS_TEST_EMAIL let jwt = try! generateIdToken(email: verifierID) let verifierParams = VerifierParams(verifier_id: verifierID) let extraParams = ["verifieridentifier": verifier, "verifier_id": verifierID] as [String: Codable] - let buffer: Data = try! NSKeyedArchiver.archivedData(withRootObject: extraParams, requiringSecureCoding: false) - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(),indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) - - XCTAssertEqual(data.finalKeyData?.evmAddress, "0x8AA6C8ddCD868873120aA265Fc63E3a2180375BA") - XCTAssertEqual(data.finalKeyData?.X, "35739417e3be1b1e56cdf8c509d8dee5412712514b18df1bc961ac6465a0c949") - XCTAssertEqual(data.finalKeyData?.Y, "887497602e62ced686eb99eaa0020b0c0d705cad96eafeec2dd1bbfb6a9d42c2") - XCTAssertEqual(data.finalKeyData?.privKey, "1e0c955d73e73558f46521da55cc66de7b8fcb56c5b24e851616849b6a1278c8") - XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x8AA6C8ddCD868873120aA265Fc63E3a2180375BA") - XCTAssertEqual(data.oAuthKeyData?.X, "35739417e3be1b1e56cdf8c509d8dee5412712514b18df1bc961ac6465a0c949") - XCTAssertEqual(data.oAuthKeyData?.Y, "887497602e62ced686eb99eaa0020b0c0d705cad96eafeec2dd1bbfb6a9d42c2") - XCTAssertEqual(data.oAuthKeyData?.privKey, "1e0c955d73e73558f46521da55cc66de7b8fcb56c5b24e851616849b6a1278c8") - XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0) - XCTAssertEqual(data.sessionData?.sessionAuthKey, "") - XCTAssertEqual(data.metadata?.pubNonce, nil) - XCTAssertEqual(data.metadata?.nonce, BigUInt(0)) - XCTAssertEqual(data.metadata?.typeOfUser, .v1) - XCTAssertEqual(data.metadata?.upgraded, nil) - XCTAssertEqual(data.nodesData?.nodeIndexes.count, 0) - - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) + + XCTAssertEqual(data.finalKeyData?.evmAddress, "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9") + XCTAssertEqual(data.finalKeyData?.X, "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1") + XCTAssertEqual(data.finalKeyData?.Y, "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359") + XCTAssertEqual(data.finalKeyData?.privKey, "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8") + XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9") + XCTAssertEqual(data.oAuthKeyData?.X, "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1") + XCTAssertEqual(data.oAuthKeyData?.Y, "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359") + XCTAssertEqual(data.oAuthKeyData?.privKey, "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8") + XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0) + XCTAssertEqual(data.sessionData?.sessionAuthKey, "") + XCTAssertEqual(data.metadata?.pubNonce, nil) + XCTAssertEqual(data.metadata?.nonce, BigUInt(0)) + XCTAssertEqual(data.metadata?.typeOfUser, .v1) + XCTAssertEqual(data.metadata?.upgraded, nil) + XCTAssertEqual(data.nodesData?.nodeIndexes.count, 0) } - func test_aggregate_login_polygon() async throws { - let exp1 = XCTestExpectation(description: "should be able to aggregate login") + func test_aggregate_login() async throws { let verifier: String = TORUS_TEST_AGGREGATE_VERIFIER let verifierID: String = TORUS_TEST_EMAIL let jwt = try! generateIdToken(email: TORUS_TEST_EMAIL) let verifierParams = VerifierParams(verifier_id: verifierID) let hashedIDToken = jwt.sha3(.keccak256) let extraParams = ["verifier_id": TORUS_TEST_EMAIL, "sub_verifier_ids": [TORUS_TEST_VERIFIER], "verify_params": [["verifier_id": TORUS_TEST_EMAIL, "idtoken": jwt]]] as [String: Codable] - let buffer: Data = try! NSKeyedArchiver.archivedData(withRootObject: extraParams, requiringSecureCoding: false) - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(),verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams) - XCTAssertEqual(data.finalKeyData?.evmAddress, "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04") - XCTAssertEqual(data.finalKeyData?.X, "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223") - XCTAssertEqual(data.finalKeyData?.Y, "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd") - XCTAssertEqual(data.finalKeyData?.privKey, "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf") - XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04") - XCTAssertEqual(data.oAuthKeyData?.X, "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223") - XCTAssertEqual(data.oAuthKeyData?.Y, "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd") - XCTAssertEqual(data.oAuthKeyData?.privKey, "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf") - XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0) - XCTAssertEqual(data.sessionData?.sessionAuthKey, "") - XCTAssertEqual(data.metadata?.pubNonce, nil) - XCTAssertEqual(data.metadata?.nonce, BigUInt(0)) - XCTAssertEqual(data.metadata?.typeOfUser, .v1) - XCTAssertEqual(data.metadata?.upgraded, nil) - XCTAssertEqual(data.nodesData?.nodeIndexes.count, 0) - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams) + XCTAssertEqual(data.finalKeyData?.evmAddress, "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04") + XCTAssertEqual(data.finalKeyData?.X, "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223") + XCTAssertEqual(data.finalKeyData?.Y, "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd") + XCTAssertEqual(data.finalKeyData?.privKey, "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf") + XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04") + XCTAssertEqual(data.oAuthKeyData?.X, "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223") + XCTAssertEqual(data.oAuthKeyData?.Y, "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd") + XCTAssertEqual(data.oAuthKeyData?.privKey, "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf") + XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0) + XCTAssertEqual(data.sessionData?.sessionAuthKey, "") + XCTAssertEqual(data.metadata?.pubNonce, nil) + XCTAssertEqual(data.metadata?.nonce, BigUInt(0)) + XCTAssertEqual(data.metadata?.typeOfUser, .v1) + XCTAssertEqual(data.metadata?.upgraded, nil) + XCTAssertEqual(data.nodesData?.nodeIndexes.count, 0) } } diff --git a/Tests/TorusUtilsTests/Helpers/EtherAddress.swift b/Tests/TorusUtilsTests/Helpers/EtherAddress.swift new file mode 100644 index 00000000..552a395d --- /dev/null +++ b/Tests/TorusUtilsTests/Helpers/EtherAddress.swift @@ -0,0 +1,14 @@ +import Foundation +@testable import TorusUtils +import XCTest + +class EtherTest: XCTestCase { + func testPublicToEtherAddress() { + let fullAddress = String("04238569d5e12caf57d34fb5b2a0679c7775b5f61fd18cd69db9cc600a651749c3ec13a9367380b7a024a67f5e663f3afd40175c3223da63f6024b05d0bd9f292e") + let X: String = String(fullAddress.suffix(128).prefix(64)) + let Y: String = String(fullAddress.suffix(64)) + let etherAddress = generateAddressFromPubKey(publicKeyX: X, publicKeyY: Y) + let finalAddress = "0x048975d4997D7578A3419851639c10318db430b6" + XCTAssertEqual(etherAddress, finalAddress) + } +} diff --git a/Tests/TorusUtilsTests/Helpers/Lagrange.swift b/Tests/TorusUtilsTests/Helpers/Lagrange.swift index ff43c5c2..1a2366c5 100644 --- a/Tests/TorusUtilsTests/Helpers/Lagrange.swift +++ b/Tests/TorusUtilsTests/Helpers/Lagrange.swift @@ -1,33 +1,32 @@ +import BigInt import Foundation import XCTest -import BigInt @testable import TorusUtils class LagrangeTest: XCTestCase { - var tu: TorusUtils! - + func testLagrangeInterpolatePolynomial() { let points: [Point] = [ Point(x: BigInt(1), y: BigInt(2)), Point(x: BigInt(2), y: BigInt(5)), - Point(x: BigInt(3), y: BigInt(10)) + Point(x: BigInt(3), y: BigInt(10)), ] - + let polynomial = lagrangeInterpolatePolynomial(points: points) - + let xValues: [BigInt] = [BigInt(1), BigInt(2), BigInt(3)] let expectedYValues: [BigInt] = [BigInt(2), BigInt(5), BigInt(10)] - - for i in 0.. TimeInterval { @@ -41,14 +14,6 @@ public class StubMockTorusUtils: TorusUtils { print("[StubMockTorusUtils] getTimeStamp(): ", ret) return ret } - - override open func generatePrivateKeyData() -> Data? { - // empty bytes - let ret = Data(base64Encoded: "FBz7bssmbsV6jBWoOJpkVOu14+6/Xgyt1pxTycODG08=") - - print("[StubMockTorusUtils] generatePrivateKeyData(): ", ret!.bytes.toBase64()) - return ret - } } let endpoints = ["https://teal-15-1.torusnode.com/jrpc", "https://teal-15-3.torusnode.com/jrpc", "https://teal-15-4.torusnode.com/jrpc", "https://teal-15-5.torusnode.com/jrpc", "https://teal-15-2.torusnode.com/jrpc"] diff --git a/Tests/TorusUtilsTests/TestnetTest.swift b/Tests/TorusUtilsTests/TestnetTest.swift index 0dabf520..362e4489 100644 --- a/Tests/TorusUtilsTests/TestnetTest.swift +++ b/Tests/TorusUtilsTests/TestnetTest.swift @@ -1,9 +1,11 @@ import BigInt +import CommonSources import FetchNodeDetails import JWTKit -import secp256k1 +#if canImport(secp256k1) + import secp256k1 +#endif import XCTest -import CommonSources import CoreMedia @testable import TorusUtils @@ -19,7 +21,7 @@ class TestnetTest: XCTestCase { override func setUp() { super.setUp() - fnd = NodeDetailManager( network: .legacy(.TESTNET)) + fnd = NodeDetailManager(network: .legacy(.TESTNET)) } func getFNDAndTUData(verifer: String, veriferID: String, enableOneKey: Bool = false) async throws -> AllNodeDetailsModel { @@ -28,170 +30,120 @@ class TestnetTest: XCTestCase { return nodeDetails } - func test_get_public_address() async { - let exp1 = XCTestExpectation(description: "should fetch public address") + func test_get_public_address() async throws { let verifier: String = "google-lrc" let verifierID: String = TORUS_TEST_EMAIL - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let val = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertEqual(val.finalKeyData!.evmAddress, "0x9bcBAde70546c0796c00323CD1b97fa0a425A506") - XCTAssertEqual(val.finalKeyData!.X, "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5") - XCTAssertEqual(val.finalKeyData!.Y, "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438") - XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x9bcBAde70546c0796c00323CD1b97fa0a425A506") - XCTAssertEqual(val.oAuthKeyData!.X, "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5") - XCTAssertEqual(val.oAuthKeyData!.Y, "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438") - XCTAssertNil(val.metadata?.pubNonce) - XCTAssertEqual(val.metadata?.nonce, 0) - XCTAssertEqual(val.metadata?.upgraded, false) - XCTAssertEqual(val.metadata?.typeOfUser, UserType(rawValue: "v1")) - XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let val = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertEqual(val.finalKeyData!.evmAddress, "0x9bcBAde70546c0796c00323CD1b97fa0a425A506") + XCTAssertEqual(val.finalKeyData!.X, "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5") + XCTAssertEqual(val.finalKeyData!.Y, "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438") + XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x9bcBAde70546c0796c00323CD1b97fa0a425A506") + XCTAssertEqual(val.oAuthKeyData!.X, "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5") + XCTAssertEqual(val.oAuthKeyData!.Y, "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438") + XCTAssertNil(val.metadata?.pubNonce) + XCTAssertEqual(val.metadata?.nonce, 0) + XCTAssertEqual(val.metadata?.upgraded, false) + XCTAssertEqual(val.metadata?.typeOfUser, UserType(rawValue: "v1")) + XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) } - func test_getUserTypeAndAddress_testnet() async { - let exp1 = XCTestExpectation(description: "should fetch user type and public address") - let exp2 = XCTestExpectation(description: "should fetch user type and public address") - let exp3 = XCTestExpectation(description: "should fetch user type and public address") - var verifier: String = "google-lrc" - var verifierID: String = TORUS_TEST_EMAIL - do { - var nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - var val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x9bcBAde70546c0796c00323CD1b97fa0a425A506") - XCTAssertEqual(val.oAuthKeyData!.X, "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5") - XCTAssertEqual(val.oAuthKeyData!.Y, "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438") - XCTAssertEqual(val.finalKeyData!.evmAddress, "0xf5804f608C233b9cdA5952E46EB86C9037fd6842") - XCTAssertEqual(val.finalKeyData!.X, "ed737569a557b50722a8b5c0e4e5ca30cef1ede2f5674a0616b78246bb93dfd0") - XCTAssertEqual(val.finalKeyData!.Y, "d9e8e6c54c12c4da38c2f0d1047fcf6089036127738f4ef72a83431339586ca9") - XCTAssertEqual(val.metadata?.pubNonce?.x, "f3f7caefd6540d923c9993113f34226371bd6714a5be6882dedc95a6a929a8") - XCTAssertEqual(val.metadata?.pubNonce?.y, "f28620603601ce54fa0d70fd691fb72ff52f5bf164bf1a91617922eaad8cc7a5") - XCTAssertEqual(val.metadata?.nonce, 0) - XCTAssertEqual(val.metadata?.upgraded, false) - XCTAssertEqual(val.metadata?.typeOfUser, .v2) - XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) - exp1.fulfill() - - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - - } + func test_getUserTypeAndAddress_testnet() async throws { + let verifier: String = "google-lrc" + let verifierID: String = TORUS_TEST_EMAIL + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x9bcBAde70546c0796c00323CD1b97fa0a425A506") + XCTAssertEqual(val.oAuthKeyData!.X, "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5") + XCTAssertEqual(val.oAuthKeyData!.Y, "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438") + XCTAssertEqual(val.finalKeyData!.evmAddress, "0xf5804f608C233b9cdA5952E46EB86C9037fd6842") + XCTAssertEqual(val.finalKeyData!.X, "ed737569a557b50722a8b5c0e4e5ca30cef1ede2f5674a0616b78246bb93dfd0") + XCTAssertEqual(val.finalKeyData!.Y, "d9e8e6c54c12c4da38c2f0d1047fcf6089036127738f4ef72a83431339586ca9") + XCTAssertEqual(val.metadata?.pubNonce?.x, "f3f7caefd6540d923c9993113f34226371bd6714a5be6882dedc95a6a929a8") + XCTAssertEqual(val.metadata?.pubNonce?.y, "f28620603601ce54fa0d70fd691fb72ff52f5bf164bf1a91617922eaad8cc7a5") + XCTAssertEqual(val.metadata?.nonce, 0) + XCTAssertEqual(val.metadata?.upgraded, false) + XCTAssertEqual(val.metadata?.typeOfUser, .v2) + XCTAssertEqual(val.nodesData?.nodeIndexes.count, 0) } - func test_key_assign_testnet() async { - let exp1 = XCTestExpectation(description: "should be able to key assign") + func test_key_assign_testnet() async throws { let fakeEmail = generateRandomEmail(of: 6) let verifier: String = "google-lrc" let verifierID: String = fakeEmail - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertNotNil(data.finalKeyData) - XCTAssertNotEqual(data.finalKeyData?.evmAddress, "") - XCTAssertEqual(data.metadata?.typeOfUser, .v1) - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertNotNil(data.finalKeyData) + XCTAssertNotEqual(data.finalKeyData?.evmAddress, "") + XCTAssertEqual(data.metadata?.typeOfUser, .v1) } - func test_login_testnet() async { - let exp1 = XCTestExpectation(description: "should be able to login") + func test_login_testnet() async throws { let verifier: String = TORUS_TEST_VERIFIER let verifierID: String = TORUS_TEST_EMAIL let verifierParams = VerifierParams(verifier_id: verifierID) let jwt = try! generateIdToken(email: verifierID) let extraParams = ["verifieridentifier": verifier, "verifier_id": verifierID] as [String: Codable] - let buffer: Data = try! NSKeyedArchiver.archivedData(withRootObject: extraParams, requiringSecureCoding: false) - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.retrieveShares( endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(),verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) - XCTAssertEqual(data.finalKeyData?.evmAddress, "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6") - XCTAssertEqual(data.finalKeyData?.X, "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd") - XCTAssertEqual(data.finalKeyData?.Y, "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9") - XCTAssertEqual(data.finalKeyData?.privKey, "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3") - XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6") - XCTAssertEqual(data.oAuthKeyData?.X, "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd") - XCTAssertEqual(data.oAuthKeyData?.Y, "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9") - XCTAssertEqual(data.oAuthKeyData?.privKey, "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3") - XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0) - XCTAssertEqual(data.sessionData?.sessionAuthKey, "") - XCTAssertEqual(data.metadata?.pubNonce, nil) - XCTAssertEqual(data.metadata?.nonce, BigUInt(0)) - XCTAssertEqual(data.metadata?.typeOfUser, .v1) - XCTAssertEqual(data.metadata?.upgraded, nil) - XCTAssertEqual(data.nodesData?.nodeIndexes.count, 0) - - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + XCTAssertEqual(data.finalKeyData?.evmAddress, "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6") + XCTAssertEqual(data.finalKeyData?.X, "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd") + XCTAssertEqual(data.finalKeyData?.Y, "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9") + XCTAssertEqual(data.finalKeyData?.privKey, "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3") + XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6") + XCTAssertEqual(data.oAuthKeyData?.X, "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd") + XCTAssertEqual(data.oAuthKeyData?.Y, "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9") + XCTAssertEqual(data.oAuthKeyData?.privKey, "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3") + XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0) + XCTAssertEqual(data.sessionData?.sessionAuthKey, "") + XCTAssertEqual(data.metadata?.pubNonce, nil) + XCTAssertEqual(data.metadata?.nonce, BigUInt(0)) + XCTAssertEqual(data.metadata?.typeOfUser, .v1) + XCTAssertEqual(data.metadata?.upgraded, nil) + XCTAssertEqual(data.nodesData?.nodeIndexes.count, 0) } func test_aggregate_login_testnet() async throws { - let exp1 = XCTestExpectation(description: "should be able to aggregate login") let verifier: String = TORUS_TEST_AGGREGATE_VERIFIER let verifierID: String = TORUS_TEST_EMAIL let verifierParams = VerifierParams(verifier_id: verifierID) let jwt = try! generateIdToken(email: TORUS_TEST_EMAIL) let hashedIDToken = jwt.sha3(.keccak256) let extraParams = ["verifier_id": TORUS_TEST_EMAIL, "sub_verifier_ids": [TORUS_TEST_VERIFIER], "verify_params": [["verifier_id": TORUS_TEST_EMAIL, "idtoken": jwt]]] as [String: Codable] - let buffer: Data = try! NSKeyedArchiver.archivedData(withRootObject: extraParams, requiringSecureCoding: false) - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(),indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams) - XCTAssertEqual(data.finalKeyData?.evmAddress, "0x938a40E155d118BD31E439A9d92D67bd55317965") - XCTAssertEqual(data.finalKeyData?.X, "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95") - XCTAssertEqual(data.finalKeyData?.Y, "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6") - XCTAssertEqual(data.finalKeyData?.privKey, "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1") - XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x938a40E155d118BD31E439A9d92D67bd55317965") - XCTAssertEqual(data.oAuthKeyData?.X, "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95") - XCTAssertEqual(data.oAuthKeyData?.Y, "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6") - XCTAssertEqual(data.oAuthKeyData?.privKey, "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1") - XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0) - XCTAssertEqual(data.sessionData?.sessionAuthKey, "") - XCTAssertEqual(data.metadata?.pubNonce, nil) - XCTAssertEqual(data.metadata?.nonce, BigUInt(0)) - XCTAssertEqual(data.metadata?.typeOfUser, .v1) - XCTAssertEqual(data.metadata?.upgraded, nil) - XCTAssertEqual(data.nodesData?.nodeIndexes.count, 0) - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams) + XCTAssertEqual(data.finalKeyData?.evmAddress, "0x938a40E155d118BD31E439A9d92D67bd55317965") + XCTAssertEqual(data.finalKeyData?.X, "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95") + XCTAssertEqual(data.finalKeyData?.Y, "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6") + XCTAssertEqual(data.finalKeyData?.privKey, "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1") + XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x938a40E155d118BD31E439A9d92D67bd55317965") + XCTAssertEqual(data.oAuthKeyData?.X, "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95") + XCTAssertEqual(data.oAuthKeyData?.Y, "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6") + XCTAssertEqual(data.oAuthKeyData?.privKey, "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1") + XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0) + XCTAssertEqual(data.sessionData?.sessionAuthKey, "") + XCTAssertEqual(data.metadata?.pubNonce, nil) + XCTAssertEqual(data.metadata?.nonce, BigUInt(0)) + XCTAssertEqual(data.metadata?.typeOfUser, .v1) + XCTAssertEqual(data.metadata?.upgraded, nil) + XCTAssertEqual(data.nodesData?.nodeIndexes.count, 0) } } extension TestnetTest { - func test_retrieveShares_some_nodes_down() async { - let exp1 = XCTestExpectation(description: "Should be able to getPublicAddress") + func test_retrieveShares_some_nodes_down() async throws { let verifier: String = TORUS_TEST_VERIFIER let verifierID: String = TORUS_TEST_EMAIL let verifierParams = VerifierParams(verifier_id: verifierID) let jwt = try! generateIdToken(email: verifierID) let extraParams = ["verifieridentifier": verifier, "verifier_id": verifierID] as [String: Codable] - let buffer: Data = try! NSKeyedArchiver.archivedData(withRootObject: extraParams, requiringSecureCoding: false) - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - var endpoints = nodeDetails.getTorusNodeEndpoints() - endpoints[0] = "https://ndjnfjbfrj/random" - // should fail if un-commented threshold 4/5 - // endpoints[1] = "https://ndjnfjbfrj/random" - let data = try await tu.retrieveShares(endpoints: endpoints, torusNodePubs: nodeDetails.getTorusNodePub(),indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) - XCTAssertEqual(data.finalKeyData?.privKey, "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3") - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + var endpoints = nodeDetails.getTorusNodeEndpoints() + endpoints[0] = "https://ndjnfjbfrj/random" + // should fail if un-commented threshold 4/5 + // endpoints[1] = "https://ndjnfjbfrj/random" + let data = try await tu.retrieveShares(endpoints: endpoints, torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) + XCTAssertEqual(data.finalKeyData?.privKey, "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3") } } diff --git a/Tests/TorusUtilsTests/Utils/JWTUtils.swift b/Tests/TorusUtilsTests/Utils/JWTUtils.swift index 56946e2e..8a9e2a67 100644 --- a/Tests/TorusUtilsTests/Utils/JWTUtils.swift +++ b/Tests/TorusUtilsTests/Utils/JWTUtils.swift @@ -1,10 +1,3 @@ -// -// File.swift -// -// -// Created by Shubham on 3/8/21. -// - import Foundation import JWTKit diff --git a/Tests/TorusUtilsTests/Utils/MockTorusUtils.swift b/Tests/TorusUtilsTests/Utils/MockTorusUtils.swift index 63f65293..23a1fe28 100644 --- a/Tests/TorusUtilsTests/Utils/MockTorusUtils.swift +++ b/Tests/TorusUtilsTests/Utils/MockTorusUtils.swift @@ -1,28 +1,18 @@ -// -// File.swift -// -// -// Created by Shubham on 2/8/21. -// - +import BigInt +import CommonSources import FetchNodeDetails import Foundation import TorusUtils -import BigInt -import CommonSources - class MockTorusUtils: AbstractTorusUtils { - - func retrieveShares(endpoints: [String], torusNodePubs: [TorusNodePubModel], indexes: [BigUInt], verifier: String, verifierParams: VerifierParams, idToken: String, extraParams: [String:Codable]) async throws -> TorusKey { + func retrieveShares(endpoints: [String], torusNodePubs: [TorusNodePubModel], indexes: [BigUInt], verifier: String, verifierParams: VerifierParams, idToken: String, extraParams: [String: Codable]) async throws -> TorusKey { return TorusKey(finalKeyData: nil, oAuthKeyData: nil, sessionData: nil, metadata: nil, nodesData: nil) } - + func getPublicAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, extendedVerifierId: String?) async throws -> TorusPublicKey { // GetPublicAddressResult(address: "") return TorusPublicKey(finalKeyData: nil, oAuthKeyData: nil, metadata: nil, nodesData: nil) } - var nodePubKeys: [TorusNodePubModel] @@ -47,6 +37,6 @@ class MockTorusUtils: AbstractTorusUtils { } func getOrSetNonce(x: String, y: String, privateKey: String?, getOnly: Bool) async throws -> GetOrSetNonceResult { - return GetOrSetNonceResult.init(typeOfUser: "v1") + return GetOrSetNonceResult(typeOfUser: "v1") } } diff --git a/Tests/TorusUtilsTests/Utils/StubURLProtocol.swift b/Tests/TorusUtilsTests/Utils/StubURLProtocol.swift index 9a0e0505..13204c0a 100644 --- a/Tests/TorusUtilsTests/Utils/StubURLProtocol.swift +++ b/Tests/TorusUtilsTests/Utils/StubURLProtocol.swift @@ -65,7 +65,7 @@ private let injectedURLs: Set = [ URL(string: "https://teal-15-3.torusnode.com/jrpc"), URL(string: "https://teal-15-5.torusnode.com/jrpc"), URL(string: "https://metadata.tor.us/get"), - URL(string: "https://signer.tor.us/api/allow") + URL(string: "https://signer.tor.us/api/allow"), ] private let httpBodyKey = "StubURLProtocolHTTPBody" @@ -514,5 +514,5 @@ private let injectedStubs: [Stub] = [ responseBody: Data(#"{"message":""}"#.utf8), statusCode: 200, responseHeaders: mustDecodeJSON(#"{"Content-Type":"application/json; charset=utf-8","Etag":"W/\"e-JWOqSwGs6lhRJiUZe/mVb6Mua74\"","x-xss-protection":"0","x-content-type-options":"nosniff","Vary":"Origin, Accept-Encoding","x-frame-options":"SAMEORIGIN","referrer-policy":"no-referrer","content-security-policy":"default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests","Date":"Sun, 17 Oct 2021 10:57:33 GMT","x-dns-prefetch-control":"off","x-permitted-cross-domain-policies":"none","Strict-Transport-Security":"max-age=15552000; includeSubDomains","x-download-options":"noopen","Content-Length":"14","expect-ct":"max-age=0"}"#) as! [String: String] - ) + ), ] diff --git a/Tests/TorusUtilsTests/XCTestManifests.swift b/Tests/TorusUtilsTests/XCTestManifests.swift index 790be24e..e5188700 100644 --- a/Tests/TorusUtilsTests/XCTestManifests.swift +++ b/Tests/TorusUtilsTests/XCTestManifests.swift @@ -3,7 +3,7 @@ import XCTest #if !canImport(ObjectiveC) public func allTests() -> [XCTestCaseEntry] { return [ - testCase(torus_utils_swiftTests.allTests) + testCase(torus_utils_swiftTests.allTests), ] } #endif diff --git a/Tests/TorusUtilsTests/oneKeyTest.swift b/Tests/TorusUtilsTests/oneKeyTest.swift index 72246b73..75ea8b04 100644 --- a/Tests/TorusUtilsTests/oneKeyTest.swift +++ b/Tests/TorusUtilsTests/oneKeyTest.swift @@ -1,16 +1,11 @@ -// -// oneKey.swift -// -// -// Created by Dhruv Jaiswal on 02/06/22. -// - import BigInt +import CommonSources import FetchNodeDetails import JWTKit -import secp256k1 +#if canImport(secp256k1) + import secp256k1 +#endif import XCTest -import CommonSources import CoreMedia @testable import TorusUtils @@ -24,7 +19,6 @@ class OneKeyTest: XCTestCase { override func setUp() { super.setUp() -// fnd = FetchNodeDetails(proxyAddress: FetchNodeDetails.proxyAddressTestnet, network: .TESTNET) fnd = NodeDetailManager(network: .legacy(.TESTNET)) } @@ -38,95 +32,59 @@ class OneKeyTest: XCTestCase { } } - func test_fetch_public_address() async { - let exp1 = XCTestExpectation(description: "should still fetch v1 public address correctly") + func test_fetch_public_address() async throws { let verifier = "google-lrc" let verifierID = "himanshu@tor.us" - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertEqual(data.finalKeyData?.evmAddress, "0xf1e76fcDD28b5AA06De01de508fF21589aB9017E") - // XCTAssertEqual(val["typeOfUser"], TypeOfUser.v1.rawValue) - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertEqual(data.finalKeyData?.evmAddress, "0xf1e76fcDD28b5AA06De01de508fF21589aB9017E") } - func test_login() async { - let exp1 = XCTestExpectation(description: "should still login v1 account correctly") + func test_login() async throws { let verifier: String = TORUS_TEST_VERIFIER let email = TORUS_TEST_EMAIL let verifierID: String = email let jwt = try! generateIdToken(email: email) let verifierParams = VerifierParams(verifier_id: verifierID) let extraParams = ["verifier_id": email] as [String: Codable] - let buffer: Data = try! NSKeyedArchiver.archivedData(withRootObject: extraParams, requiringSecureCoding: false) - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) - XCTAssertEqual(data.finalKeyData?.privKey, "296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4") - exp1.fulfill() - } catch let err{ - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) + XCTAssertEqual(data.finalKeyData?.privKey, "296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4") } - func test_login_v2() async { - let exp1 = XCTestExpectation(description: "should still login v2 account correctly") + func test_login_v2() async throws { let verifier: String = TORUS_TEST_VERIFIER let verifierID: String = TORUS_TEST_EMAIL let jwt = try! generateIdToken(email: verifierID) let verifierParams = VerifierParams(verifier_id: verifierID) let extraParams = ["verifier_id": verifierID] as [String: Codable] - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) - XCTAssertEqual(data.finalKeyData?.privKey, "296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4") - XCTAssertEqual(data.finalKeyData?.evmAddress, "0x53010055542cCc0f2b6715a5c53838eC4aC96EF7") - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams) + XCTAssertEqual(data.oAuthKeyData?.privKey, "068ee4f97468ef1ae95d18554458d372e31968190ae38e377be59d8b3c9f7a25") + XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0xEfd7eDAebD0D99D1B7C8424b54835457dD005Dc4") + XCTAssertEqual(data.finalKeyData?.privKey, "296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4") + XCTAssertEqual(data.finalKeyData?.evmAddress, "0x53010055542cCc0f2b6715a5c53838eC4aC96EF7") } - func test_aggregate_login() async { - let exp1 = XCTestExpectation(description: "Should be able to aggregate login") + func test_aggregate_login() async throws { let verifier: String = TORUS_TEST_AGGREGATE_VERIFIER let verifierID: String = TORUS_TEST_EMAIL let jwt = try! generateIdToken(email: TORUS_TEST_EMAIL) let verifierParams = VerifierParams(verifier_id: verifierID) let hashedIDToken = jwt.sha3(.keccak256) let extraParams = ["verifier_id": TORUS_TEST_EMAIL, "sub_verifier_ids": [TORUS_TEST_VERIFIER], "verify_params": [["verifier_id": TORUS_TEST_EMAIL, "idtoken": jwt]]] as [String: Codable] - let buffer: Data = try! NSKeyedArchiver.archivedData(withRootObject: extraParams, requiringSecureCoding: false) - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams) - XCTAssertEqual(data.finalKeyData?.evmAddress, "0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B") - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams) + XCTAssertEqual(data.finalKeyData?.evmAddress, "0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B") } - func test_key_assign() async { + func test_key_assign() async throws { let fakeEmail = generateRandomEmail(of: 6) - let exp1 = XCTestExpectation(description: "Should be able to assign key") let verifier: String = "google-lrc" let verifierID: String = fakeEmail - do { - let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) - let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) - XCTAssertNotNil(data) - XCTAssertNotEqual(data.finalKeyData?.evmAddress, "") - exp1.fulfill() - } catch let err { - XCTFail(err.localizedDescription) - exp1.fulfill() - } + let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID) + let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID) + XCTAssertNotNil(data) + XCTAssertNotEqual(data.finalKeyData?.evmAddress, "") } }