From a57d6c53b057118fbd039780f9a5c4fa77d7e616 Mon Sep 17 00:00:00 2001 From: Ronald Mannak Date: Thu, 7 Jul 2022 20:58:03 -0700 Subject: [PATCH 01/12] Add EIP1024 conform encryption --- Package.swift | 5 +++-- .../eip1024/EthEncryptedData+EIP1024.swift | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 5e23061..52e011c 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.4 +// swift-tools-version:5.5 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription @@ -22,7 +22,8 @@ let package = Package( .package(url: "https://github.com/Quick/Nimble.git", .upToNextMajor(from: "9.0.0")), .package(url: "https://github.com/MyEtherWallet/bls-eth-swift.git", .exact("1.0.1")), .package(url: "https://github.com/attaswift/BigInt.git", from: "5.2.1"), - .package(name: "MEWwalletTweetNacl", url: "https://github.com/MyEtherWallet/mew-wallet-ios-tweetnacl.git", .upToNextMajor(from: "1.0.0")) + //.package(name: "MEWwalletTweetNacl", url: "https://github.com/MyEtherWallet/mew-wallet-ios-tweetnacl.git", .upToNextMajor(from: "1.0.0")), + .package(name: "MEWwalletTweetNacl", url: "https://github.com/moonfishapp/mew-wallet-ios-tweetnacl.git", branch: "main"), ], targets: [ .target( diff --git a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift index d6d165c..f32091e 100644 --- a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift +++ b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift @@ -14,16 +14,38 @@ public struct EthEncryptedData: Codable { public let nonce: String public let ephemPublicKey: String public let ciphertext: String + public private (set) var version = "x25519-xsalsa20-poly1305" public init(nonce: String, ephemPublicKey: String, ciphertext: String) { self.nonce = nonce self.ephemPublicKey = ephemPublicKey self.ciphertext = ciphertext } + + /// - Parameters: + /// - plaintext: plain text to be necrypted + /// - publicKey: public key of recipient + /// - Returns: EthEncryptedData + public static func encrypt(plaintext: String, publicKey: String) throws -> EthEncryptedData { + var nonce = [UInt8](repeating: 0, count: Constants.SecretBox.nonceLength) + let status = SecRandomCopyBytes(kSecRandomDefault, Constants.SecretBox.nonceLength, &nonce) + guard status == errSecSuccess else { + throw TweetNaclError.tweetNacl("Secure random bytes error") + } + let ephemKeys = try TweetNacl.keyPair() + let publicKeyData = Data(hex: publicKey) + + let ciphertextData = try TweetNacl.box(message: plaintext, nonce: Data(nonce), theirPublicKey: publicKeyData, mySecretKey: ephemKeys.secretKey) + guard let ciphertext = String(data: ciphertextData, encoding: .utf8), let nonceString = String(data: Data(nonce), encoding: .utf8), let ephemPublicKeyString = String(data: ephemKeys.publicKey, encoding: .utf8) else { + throw EthCryptoError.encryptionFailed + } + return EthEncryptedData(nonce: nonceString, ephemPublicKey: ephemPublicKeyString, ciphertext: ciphertext) + } } public enum EthCryptoError: Error { case decryptionFailed + case encryptionFailed } extension EthEncryptedData { From e024db24bdb2a44739ddd031703eb6de7884e011 Mon Sep 17 00:00:00 2001 From: Ronald Mannak Date: Sun, 10 Jul 2022 21:50:18 -0700 Subject: [PATCH 02/12] Temp commented out encrypt --- .../eip1024/EthEncryptedData+EIP1024.swift | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift index f32091e..679779f 100644 --- a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift +++ b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift @@ -26,21 +26,16 @@ public struct EthEncryptedData: Codable { /// - plaintext: plain text to be necrypted /// - publicKey: public key of recipient /// - Returns: EthEncryptedData - public static func encrypt(plaintext: String, publicKey: String) throws -> EthEncryptedData { - var nonce = [UInt8](repeating: 0, count: Constants.SecretBox.nonceLength) - let status = SecRandomCopyBytes(kSecRandomDefault, Constants.SecretBox.nonceLength, &nonce) - guard status == errSecSuccess else { - throw TweetNaclError.tweetNacl("Secure random bytes error") - } - let ephemKeys = try TweetNacl.keyPair() - let publicKeyData = Data(hex: publicKey) - - let ciphertextData = try TweetNacl.box(message: plaintext, nonce: Data(nonce), theirPublicKey: publicKeyData, mySecretKey: ephemKeys.secretKey) - guard let ciphertext = String(data: ciphertextData, encoding: .utf8), let nonceString = String(data: Data(nonce), encoding: .utf8), let ephemPublicKeyString = String(data: ephemKeys.publicKey, encoding: .utf8) else { - throw EthCryptoError.encryptionFailed - } - return EthEncryptedData(nonce: nonceString, ephemPublicKey: ephemPublicKeyString, ciphertext: ciphertext) - } +// public static func encrypt(plaintext: String, publicKey: String) throws -> EthEncryptedData { +// let ephemKeys = try TweetNacl.keyPair() +// let publicKeyData = Data(hex: publicKey) +// +// let ciphertextData = try TweetNacl.box(message: plaintext, theirPublicKey: publicKeyData, mySecretKey: ephemKeys.secretKey) +// guard let ciphertext = String(data: ciphertextData, encoding: .utf8), let nonceString = String(data: Data(nonce), encoding: .utf8), let ephemPublicKeyString = String(data: ephemKeys.publicKey, encoding: .utf8) else { +// throw EthCryptoError.encryptionFailed +// } +// return EthEncryptedData(nonce: nonceString, ephemPublicKey: ephemPublicKeyString, ciphertext: ciphertext) +// } } public enum EthCryptoError: Error { From 6af69bd7a836c0b6d01ed5a1b1ff9ecf9c2be9b6 Mon Sep 17 00:00:00 2001 From: Ronald Mannak Date: Tue, 2 Aug 2022 17:14:31 -0700 Subject: [PATCH 03/12] Encrypt messages using recipient public key --- .../Sources/eips/eip1024/EIP1024Tests.swift | 56 +++++++++++++++- .../eip1024/EthEncryptedData+EIP1024.swift | 66 ++++++++++++++----- 2 files changed, 103 insertions(+), 19 deletions(-) diff --git a/MEWwalletKitTests/Sources/eips/eip1024/EIP1024Tests.swift b/MEWwalletKitTests/Sources/eips/eip1024/EIP1024Tests.swift index 94d1c67..a12ab33 100644 --- a/MEWwalletKitTests/Sources/eips/eip1024/EIP1024Tests.swift +++ b/MEWwalletKitTests/Sources/eips/eip1024/EIP1024Tests.swift @@ -9,6 +9,7 @@ import Foundation import Quick import Nimble +import MEWwalletTweetNacl @testable import MEWwalletKit class EIP1024Tests: QuickSpec { @@ -17,15 +18,68 @@ class EIP1024Tests: QuickSpec { ephemPublicKey: "FBH1/pAEHOOW14Lu3FWkgV3qOEcuL78Zy+qW1RwzMXQ=", ciphertext: "f8kBcl/NCyf3sybfbwAKk/np2Bzt9lRVkZejr6uh5FgnNlH/ic62DZzy" ) + let recipientPrivateKeyString = "7e5374ec2ef0d91761a6e72fdf8f6ac665519bfdf6da0a2329cf0d804514b816" + private let senderPrivateKey = try! PrivateKeyEth1(seed: Data(hex: "0xc55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04"), network: .ethereum) + override func spec() { describe("salsa decryption") { it("should decrypt the encrypted data") { let message = try? self.encryptedData.decrypt( - privateKey: "7e5374ec2ef0d91761a6e72fdf8f6ac665519bfdf6da0a2329cf0d804514b816" + privateKey: self.recipientPrivateKeyString //"7e5374ec2ef0d91761a6e72fdf8f6ac665519bfdf6da0a2329cf0d804514b816" ) expect(message ?? "").to(equal("My name is Satoshi Buterin")) } } + + describe("test PrivateKeyEth1 extension") { + it("should convert Ethereum keys to curve25519") { + do { + let privateKey = Data([0x7e, 0x53, 0x74, 0xec, 0x2e, 0xf0, 0xd9, 0x17, 0x61, 0xa6, 0xe7, 0x2f, 0xdf, 0x8f, 0x6a, 0xc6, 0x65, 0x51, 0x9b, 0xfd, 0xf6, 0xda, 0x0a, 0x23, 0x29, 0xcf, 0x0d, 0x80, 0x45, 0x14, 0xb8, 0x16]) + let ethPrivateKey = try PrivateKeyEth1(seed: privateKey, network: .ethereum) + let keypair = try TweetNacl.keyPair(fromSecretKey: ethPrivateKey.data()) + + expect(keypair.secretKey.count) == 32 + expect(keypair.publicKey.count) == 32 + expect(String(data: keypair.publicKey.base64EncodedData(), encoding: .utf8)) == "uh9pcAr8Mg+nLj/8x4BPtMM9k925R8aXPAmjHjAV8x8=" + } catch { + fail(error.localizedDescription) + } + } + } + + describe("roundtrip") { + it("should encrypt and then decrypt the data") { + + let recipientEthKey = PrivateKeyEth1(privateKey: Data(hex: self.recipientPrivateKeyString), network: .ethereum) + expect(recipientEthKey.string()!) == "7e5374ec2ef0d91761a6e72fdf8f6ac665519bfdf6da0a2329cf0d804514b816" + + do { + let recipientKeyPair = try TweetNacl.keyPair(fromSecretKey: recipientEthKey.data()) + guard let recipientPublicKeyString = String(data: recipientKeyPair.publicKey.base64EncodedData(), encoding: .utf8) else { + fail("returned nil") + return + } + + let encryptedData = try EthEncryptedData.encrypt(plaintext: "My name is Satoshi Buterin", senderPrivateKey: self.senderPrivateKey, recipientPublicKey: recipientPublicKeyString) + expect(Data(base64Encoded: encryptedData.ephemPublicKey)!.count) == 32 + + + // Decrypt using recipient's private key string + let decryptedByRecipient = try encryptedData.decrypt(privateKey: recipientEthKey) + expect(decryptedByRecipient) == "My name is Satoshi Buterin" + + // Decrypt using recipient's private key + let decryptedByRecipientString = try encryptedData.decrypt(privateKey: self.recipientPrivateKeyString) + expect(decryptedByRecipientString) == "My name is Satoshi Buterin" + + // Decrypt using sender's private key +// let decryptedBySender = try encryptedData.decrypt(privateKey: self.senderPrivateKey) +// expect(decryptedBySender) == "My name is Satoshi Buterin" + } catch { + fail(error.localizedDescription) + } + } + } } } diff --git a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift index 679779f..416eb96 100644 --- a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift +++ b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift @@ -21,29 +21,40 @@ public struct EthEncryptedData: Codable { self.ephemPublicKey = ephemPublicKey self.ciphertext = ciphertext } - - /// - Parameters: - /// - plaintext: plain text to be necrypted - /// - publicKey: public key of recipient - /// - Returns: EthEncryptedData -// public static func encrypt(plaintext: String, publicKey: String) throws -> EthEncryptedData { -// let ephemKeys = try TweetNacl.keyPair() -// let publicKeyData = Data(hex: publicKey) -// -// let ciphertextData = try TweetNacl.box(message: plaintext, theirPublicKey: publicKeyData, mySecretKey: ephemKeys.secretKey) -// guard let ciphertext = String(data: ciphertextData, encoding: .utf8), let nonceString = String(data: Data(nonce), encoding: .utf8), let ephemPublicKeyString = String(data: ephemKeys.publicKey, encoding: .utf8) else { -// throw EthCryptoError.encryptionFailed -// } -// return EthEncryptedData(nonce: nonceString, ephemPublicKey: ephemPublicKeyString, ciphertext: ciphertext) -// } } public enum EthCryptoError: Error { case decryptionFailed case encryptionFailed + case keyError } extension EthEncryptedData { + + // MARK: - Encrypt + /// - Parameters: + /// - plaintext: plain text to be encrypted + /// - senderKey: private ethereum key of sender + /// - publicKey: public key of recipient curve25519 in hex format + /// - Returns: EthEncryptedData + public static func encrypt(plaintext: String, senderPrivateKey: PrivateKeyEth1, recipientPublicKey: String) throws -> EthEncryptedData { + guard let plaintextData = plaintext.data(using: .utf8), + let recipientPublicKey = Data(base64Encoded: recipientPublicKey) else { + throw EthCryptoError.encryptionFailed + } + let secretBox = try TweetNacl.box(message: plaintextData, recipientPublicKey: recipientPublicKey, senderSecretKey: senderPrivateKey.curve25519PrivateKeyData()) + return try EthEncryptedData(nonce: secretBox.nonce.base64EncodedString(), ephemPublicKey: senderPrivateKey.curve25519PublicKey(), ciphertext: secretBox.box.base64EncodedString()) + } + + // MARK: - Decrypt + public func decrypt(privateKey: PrivateKeyEth1) throws -> String { + guard let privateKey = privateKey.string() else { throw EthCryptoError.keyError } + return try decrypt(privateKey: privateKey) + } + + /// Decrypts EthEncryptedData + /// - Parameter privateKey: Private Ethereum key + /// - Returns: cleartext message public func decrypt(privateKey: String) throws -> String { let data = Data(hex: privateKey) @@ -71,9 +82,28 @@ extension EthEncryptedData { } extension PrivateKeyEth1 { - public func eth_publicKey() throws -> String { - let publicKey = try TweetNacl.keyPair(fromSecretKey: data()).publicKey - return publicKey.toHexString() + /// Create curve25519 public key from Ethereum private key + /// - Returns: base64 encoded string + public func curve25519PublicKey() throws -> String { + return try curve25519PublicKeyData().base64EncodedString() + } + + /// Create curve25519 public key from Ethereum private key + /// - Returns: public key + func curve25519PublicKeyData() throws -> Data { + return try TweetNacl.keyPair(fromSecretKey: data()).publicKey + } + + /// Create curve25519 private key from Ethereum private key + /// - Returns: base64 encoded string + public func curve25519PrivateKey() throws -> String { + return try curve25519PrivateKeyData().base64EncodedString() + } + + /// Create curve25519 private key from Ethereum private key + /// - Returns: private key + func curve25519PrivateKeyData() throws -> Data { + return try TweetNacl.keyPair(fromSecretKey: data()).secretKey } } From 9399458a07cce60eaa528ffd970f340676ef9bff Mon Sep 17 00:00:00 2001 From: Ronald Mannak Date: Tue, 2 Aug 2022 19:02:52 -0700 Subject: [PATCH 04/12] =?UTF-8?q?Add=20decrypt=20with=20sender=E2=80=99s?= =?UTF-8?q?=20private=20key?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/eips/eip1024/EIP1024Tests.swift | 4 +- .../eip1024/EthEncryptedData+EIP1024.swift | 48 ++++++++++++++++++- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/MEWwalletKitTests/Sources/eips/eip1024/EIP1024Tests.swift b/MEWwalletKitTests/Sources/eips/eip1024/EIP1024Tests.swift index a12ab33..6faf10e 100644 --- a/MEWwalletKitTests/Sources/eips/eip1024/EIP1024Tests.swift +++ b/MEWwalletKitTests/Sources/eips/eip1024/EIP1024Tests.swift @@ -74,8 +74,8 @@ class EIP1024Tests: QuickSpec { expect(decryptedByRecipientString) == "My name is Satoshi Buterin" // Decrypt using sender's private key -// let decryptedBySender = try encryptedData.decrypt(privateKey: self.senderPrivateKey) -// expect(decryptedBySender) == "My name is Satoshi Buterin" + let decryptedBySender = try encryptedData.decrypt(senderPrivateKey: self.senderPrivateKey, recipientPublicKey: recipientPublicKeyString) + expect(decryptedBySender) == "My name is Satoshi Buterin" } catch { fail(error.localizedDescription) } diff --git a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift index 416eb96..180161c 100644 --- a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift +++ b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift @@ -46,14 +46,17 @@ extension EthEncryptedData { return try EthEncryptedData(nonce: secretBox.nonce.base64EncodedString(), ephemPublicKey: senderPrivateKey.curve25519PublicKey(), ciphertext: secretBox.box.base64EncodedString()) } - // MARK: - Decrypt + // MARK: - Decrypt + /// Decrypts EthEncryptedData + /// - Parameter privateKey: Private Ethereum key + /// - Returns: cleartext message public func decrypt(privateKey: PrivateKeyEth1) throws -> String { guard let privateKey = privateKey.string() else { throw EthCryptoError.keyError } return try decrypt(privateKey: privateKey) } /// Decrypts EthEncryptedData - /// - Parameter privateKey: Private Ethereum key + /// - Parameter privateKey: String of private Ethereum key /// - Returns: cleartext message public func decrypt(privateKey: String) throws -> String { let data = Data(hex: privateKey) @@ -79,6 +82,47 @@ extension EthEncryptedData { return message } + + + /// Decrypt the message using the sender's private key + /// - Parameters: + /// - senderPrivateKey: sender private key as PrivateKeyEth1 + /// - recipientPublicKey: string of recipient's public key + /// - Returns: cleartext message + public func decrypt(senderPrivateKey: PrivateKeyEth1, recipientPublicKey: String) throws -> String { + guard let privateKey = senderPrivateKey.string() else { throw EthCryptoError.keyError } + return try decrypt(senderPrivateKey: privateKey, recipientPublicKey: recipientPublicKey) + } + + /// Decrypt the message using the sender's private key + /// - Parameters: + /// - senderPrivateKey: sender private key as string + /// - recipientPublicKey: string of recipient's public key + /// - Returns: cleartext message + public func decrypt(senderPrivateKey: String, recipientPublicKey: String) throws -> String { + let data = Data(hex: senderPrivateKey) + + let secretKey = try TweetNacl.keyPair(fromSecretKey: data).secretKey + + guard let nonce = Data(base64Encoded: self.nonce), + let cipherText = Data(base64Encoded: self.ciphertext), + let recipientPublicKeyData = Data(base64Encoded: recipientPublicKey) else { + throw EthCryptoError.decryptionFailed + } + + let decrypted = try TweetNacl.open( + message: cipherText, + nonce: nonce, + publicKey: recipientPublicKeyData, + secretKey: secretKey + ) + + guard let message = String(data: decrypted, encoding: .utf8) else { + throw EthCryptoError.decryptionFailed + } + + return message + } } extension PrivateKeyEth1 { From 44f6ccd5038c781c1b98356d96c7fd1fb6822b2a Mon Sep 17 00:00:00 2001 From: Ronald Mannak Date: Thu, 4 Aug 2022 13:40:28 -0700 Subject: [PATCH 05/12] make curve25519 key data methods accessible --- Sources/eips/eip1024/EthEncryptedData+EIP1024.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift index 180161c..610bbcd 100644 --- a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift +++ b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift @@ -135,7 +135,7 @@ extension PrivateKeyEth1 { /// Create curve25519 public key from Ethereum private key /// - Returns: public key - func curve25519PublicKeyData() throws -> Data { + public func curve25519PublicKeyData() throws -> Data { return try TweetNacl.keyPair(fromSecretKey: data()).publicKey } @@ -147,7 +147,7 @@ extension PrivateKeyEth1 { /// Create curve25519 private key from Ethereum private key /// - Returns: private key - func curve25519PrivateKeyData() throws -> Data { + public func curve25519PrivateKeyData() throws -> Data { return try TweetNacl.keyPair(fromSecretKey: data()).secretKey } } From 804286e748bafd6179560351fe880d7173817a58 Mon Sep 17 00:00:00 2001 From: Ronald Mannak Date: Wed, 17 Aug 2022 23:41:57 -0700 Subject: [PATCH 06/12] added self to emphesize data is a property --- Sources/eips/eip1024/EthEncryptedData+EIP1024.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift index 610bbcd..4ff3c67 100644 --- a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift +++ b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift @@ -136,7 +136,7 @@ extension PrivateKeyEth1 { /// Create curve25519 public key from Ethereum private key /// - Returns: public key public func curve25519PublicKeyData() throws -> Data { - return try TweetNacl.keyPair(fromSecretKey: data()).publicKey + return try TweetNacl.keyPair(fromSecretKey: self.data()).publicKey } /// Create curve25519 private key from Ethereum private key @@ -148,6 +148,6 @@ extension PrivateKeyEth1 { /// Create curve25519 private key from Ethereum private key /// - Returns: private key public func curve25519PrivateKeyData() throws -> Data { - return try TweetNacl.keyPair(fromSecretKey: data()).secretKey + return try TweetNacl.keyPair(fromSecretKey: self.data()).secretKey } } From daf78a63b87426e7997c41567b8f450cee783394 Mon Sep 17 00:00:00 2001 From: Ronald Mannak Date: Tue, 23 Aug 2022 18:17:02 -0700 Subject: [PATCH 07/12] Add error descriptions --- Sources/eips/eip1024/EthEncryptedData+EIP1024.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift index 4ff3c67..5e2908e 100644 --- a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift +++ b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift @@ -29,6 +29,19 @@ public enum EthCryptoError: Error { case keyError } +extension EthCryptoError: LocalizedError { + public var errorDescription: String? { + switch self { + case .decryptionFailed: + return "Decryption failed" + case .encryptionFailed: + return "Encryption failed" + case .keyError: + return "Invalid private key" + } + } +} + extension EthEncryptedData { // MARK: - Encrypt From e63239c0a8695044a02856c5c799907d1c3ba0dc Mon Sep 17 00:00:00 2001 From: Ronald Mannak Date: Tue, 6 Sep 2022 15:49:04 -0700 Subject: [PATCH 08/12] Add public init Legacy Transaction --- Sources/eips/eip155/LegacyTransaction.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/eips/eip155/LegacyTransaction.swift b/Sources/eips/eip155/LegacyTransaction.swift index d082af9..ce1cf0c 100644 --- a/Sources/eips/eip155/LegacyTransaction.swift +++ b/Sources/eips/eip155/LegacyTransaction.swift @@ -14,7 +14,7 @@ public class LegacyTransaction: Transaction { return self._gasPrice.data } - init( + public init( nonce: BigInt = BigInt(0x00), gasPrice: BigInt = BigInt(0x00), gasLimit: BigInt = BigInt(0x00), From 441396dea276ec70fd5fd0b7b6a8103c7a8b156f Mon Sep 17 00:00:00 2001 From: Ronald Mannak Date: Mon, 12 Sep 2022 20:24:14 -0700 Subject: [PATCH 09/12] Revert package, fix indentation --- Package.swift | 3 +- .../eip1024/EthEncryptedData+EIP1024.swift | 178 +++++++++--------- 2 files changed, 89 insertions(+), 92 deletions(-) diff --git a/Package.swift b/Package.swift index 52e011c..cbcef0e 100644 --- a/Package.swift +++ b/Package.swift @@ -22,8 +22,7 @@ let package = Package( .package(url: "https://github.com/Quick/Nimble.git", .upToNextMajor(from: "9.0.0")), .package(url: "https://github.com/MyEtherWallet/bls-eth-swift.git", .exact("1.0.1")), .package(url: "https://github.com/attaswift/BigInt.git", from: "5.2.1"), - //.package(name: "MEWwalletTweetNacl", url: "https://github.com/MyEtherWallet/mew-wallet-ios-tweetnacl.git", .upToNextMajor(from: "1.0.0")), - .package(name: "MEWwalletTweetNacl", url: "https://github.com/moonfishapp/mew-wallet-ios-tweetnacl.git", branch: "main"), + .package(name: "MEWwalletTweetNacl", url: "https://github.com/MyEtherWallet/mew-wallet-ios-tweetnacl.git", .upToNextMajor(from: "1.0.0")), ], targets: [ .target( diff --git a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift index 5e2908e..09f005b 100644 --- a/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift +++ b/Sources/eips/eip1024/EthEncryptedData+EIP1024.swift @@ -24,118 +24,116 @@ public struct EthEncryptedData: Codable { } public enum EthCryptoError: Error { - case decryptionFailed - case encryptionFailed - case keyError + case decryptionFailed + case encryptionFailed + case keyError } extension EthCryptoError: LocalizedError { - public var errorDescription: String? { - switch self { - case .decryptionFailed: - return "Decryption failed" - case .encryptionFailed: - return "Encryption failed" - case .keyError: - return "Invalid private key" - } + public var errorDescription: String? { + switch self { + case .decryptionFailed: + return "Decryption failed" + case .encryptionFailed: + return "Encryption failed" + case .keyError: + return "Invalid private key" } + } } extension EthEncryptedData { - // MARK: - Encrypt - /// - Parameters: - /// - plaintext: plain text to be encrypted - /// - senderKey: private ethereum key of sender - /// - publicKey: public key of recipient curve25519 in hex format - /// - Returns: EthEncryptedData - public static func encrypt(plaintext: String, senderPrivateKey: PrivateKeyEth1, recipientPublicKey: String) throws -> EthEncryptedData { - guard let plaintextData = plaintext.data(using: .utf8), - let recipientPublicKey = Data(base64Encoded: recipientPublicKey) else { - throw EthCryptoError.encryptionFailed - } - let secretBox = try TweetNacl.box(message: plaintextData, recipientPublicKey: recipientPublicKey, senderSecretKey: senderPrivateKey.curve25519PrivateKeyData()) - return try EthEncryptedData(nonce: secretBox.nonce.base64EncodedString(), ephemPublicKey: senderPrivateKey.curve25519PublicKey(), ciphertext: secretBox.box.base64EncodedString()) + // MARK: - Encrypt + /// - Parameters: + /// - plaintext: plain text to be encrypted + /// - senderKey: private ethereum key of sender + /// - publicKey: public key of recipient curve25519 in hex format + /// - Returns: EthEncryptedData + public static func encrypt(plaintext: String, senderPrivateKey: PrivateKeyEth1, recipientPublicKey: String) throws -> EthEncryptedData { + guard let plaintextData = plaintext.data(using: .utf8), + let recipientPublicKey = Data(base64Encoded: recipientPublicKey) else { + throw EthCryptoError.encryptionFailed } + let secretBox = try TweetNacl.box(message: plaintextData, recipientPublicKey: recipientPublicKey, senderSecretKey: senderPrivateKey.curve25519PrivateKeyData()) + return try EthEncryptedData(nonce: secretBox.nonce.base64EncodedString(), ephemPublicKey: senderPrivateKey.curve25519PublicKey(), ciphertext: secretBox.box.base64EncodedString()) + } - // MARK: - Decrypt - /// Decrypts EthEncryptedData - /// - Parameter privateKey: Private Ethereum key - /// - Returns: cleartext message - public func decrypt(privateKey: PrivateKeyEth1) throws -> String { - guard let privateKey = privateKey.string() else { throw EthCryptoError.keyError } - return try decrypt(privateKey: privateKey) - } + // MARK: - Decrypt + /// Decrypts EthEncryptedData + /// - Parameter privateKey: Private Ethereum key + /// - Returns: cleartext message + public func decrypt(privateKey: PrivateKeyEth1) throws -> String { + guard let privateKey = privateKey.string() else { throw EthCryptoError.keyError } + return try decrypt(privateKey: privateKey) + } - /// Decrypts EthEncryptedData - /// - Parameter privateKey: String of private Ethereum key - /// - Returns: cleartext message - public func decrypt(privateKey: String) throws -> String { - let data = Data(hex: privateKey) + /// Decrypts EthEncryptedData + /// - Parameter privateKey: String of private Ethereum key + /// - Returns: cleartext message + public func decrypt(privateKey: String) throws -> String { + let data = Data(hex: privateKey) - let secretKey = try TweetNacl.keyPair(fromSecretKey: data).secretKey + let secretKey = try TweetNacl.keyPair(fromSecretKey: data).secretKey - guard let nonce = Data(base64Encoded: self.nonce), - let cipherText = Data(base64Encoded: self.ciphertext), - let ephemPublicKey = Data(base64Encoded: self.ephemPublicKey) else { - throw EthCryptoError.decryptionFailed - } - - let decrypted = try TweetNacl.open( - message: cipherText, - nonce: nonce, - publicKey: ephemPublicKey, - secretKey: secretKey - ) + guard let nonce = Data(base64Encoded: self.nonce), + let cipherText = Data(base64Encoded: self.ciphertext), + let ephemPublicKey = Data(base64Encoded: self.ephemPublicKey) else { + throw EthCryptoError.decryptionFailed + } - guard let message = String(data: decrypted, encoding: .utf8) else { - throw EthCryptoError.decryptionFailed - } + let decrypted = try TweetNacl.open( + message: cipherText, + nonce: nonce, + publicKey: ephemPublicKey, + secretKey: secretKey + ) - return message + guard let message = String(data: decrypted, encoding: .utf8) else { + throw EthCryptoError.decryptionFailed } + + return message + } + /// Decrypt the message using the sender's private key + /// - Parameters: + /// - senderPrivateKey: sender private key as PrivateKeyEth1 + /// - recipientPublicKey: string of recipient's public key + /// - Returns: cleartext message + public func decrypt(senderPrivateKey: PrivateKeyEth1, recipientPublicKey: String) throws -> String { + guard let privateKey = senderPrivateKey.string() else { throw EthCryptoError.keyError } + return try decrypt(senderPrivateKey: privateKey, recipientPublicKey: recipientPublicKey) + } - /// Decrypt the message using the sender's private key - /// - Parameters: - /// - senderPrivateKey: sender private key as PrivateKeyEth1 - /// - recipientPublicKey: string of recipient's public key - /// - Returns: cleartext message - public func decrypt(senderPrivateKey: PrivateKeyEth1, recipientPublicKey: String) throws -> String { - guard let privateKey = senderPrivateKey.string() else { throw EthCryptoError.keyError } - return try decrypt(senderPrivateKey: privateKey, recipientPublicKey: recipientPublicKey) - } - - /// Decrypt the message using the sender's private key - /// - Parameters: - /// - senderPrivateKey: sender private key as string - /// - recipientPublicKey: string of recipient's public key - /// - Returns: cleartext message - public func decrypt(senderPrivateKey: String, recipientPublicKey: String) throws -> String { - let data = Data(hex: senderPrivateKey) - - let secretKey = try TweetNacl.keyPair(fromSecretKey: data).secretKey + /// Decrypt the message using the sender's private key + /// - Parameters: + /// - senderPrivateKey: sender private key as string + /// - recipientPublicKey: string of recipient's public key + /// - Returns: cleartext message + public func decrypt(senderPrivateKey: String, recipientPublicKey: String) throws -> String { + let data = Data(hex: senderPrivateKey) + let secretKey = try TweetNacl.keyPair(fromSecretKey: data).secretKey - guard let nonce = Data(base64Encoded: self.nonce), - let cipherText = Data(base64Encoded: self.ciphertext), - let recipientPublicKeyData = Data(base64Encoded: recipientPublicKey) else { - throw EthCryptoError.decryptionFailed - } - - let decrypted = try TweetNacl.open( - message: cipherText, - nonce: nonce, - publicKey: recipientPublicKeyData, - secretKey: secretKey - ) + guard let nonce = Data(base64Encoded: self.nonce), + let cipherText = Data(base64Encoded: self.ciphertext), + let recipientPublicKeyData = Data(base64Encoded: recipientPublicKey) else { + throw EthCryptoError.decryptionFailed + } - guard let message = String(data: decrypted, encoding: .utf8) else { - throw EthCryptoError.decryptionFailed - } + let decrypted = try TweetNacl.open( + message: cipherText, + nonce: nonce, + publicKey: recipientPublicKeyData, + secretKey: secretKey + ) - return message + guard let message = String(data: decrypted, encoding: .utf8) else { + throw EthCryptoError.decryptionFailed } + + return message + } } extension PrivateKeyEth1 { From fe3cdafa6b476e453a93c52c3af309e84459f703 Mon Sep 17 00:00:00 2001 From: Ronald Mannak Date: Thu, 20 Oct 2022 17:56:08 -0700 Subject: [PATCH 10/12] Update branch --- Package.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index cbcef0e..6d9baa1 100644 --- a/Package.swift +++ b/Package.swift @@ -22,7 +22,9 @@ let package = Package( .package(url: "https://github.com/Quick/Nimble.git", .upToNextMajor(from: "9.0.0")), .package(url: "https://github.com/MyEtherWallet/bls-eth-swift.git", .exact("1.0.1")), .package(url: "https://github.com/attaswift/BigInt.git", from: "5.2.1"), - .package(name: "MEWwalletTweetNacl", url: "https://github.com/MyEtherWallet/mew-wallet-ios-tweetnacl.git", .upToNextMajor(from: "1.0.0")), +// .package(name: "MEWwalletTweetNacl", url: "https://github.com/MyEtherWallet/mew-wallet-ios-tweetnacl.git", .upToNextMajor(from: "1.0.0")), + .package(name: "MEWwalletTweetNacl", url: "https://github.com/MoonfishApp/mew-wallet-ios-tweetnacl.git", .branch("main")), +// .package(name: "MEWwalletTweetNacl", path: "../mew-wallet-ios-tweetnacl"), ], targets: [ .target( From 4ef281ca895adfd6aeef4b5574fb7ef8e1ed6887 Mon Sep 17 00:00:00 2001 From: Ronald Mannak Date: Thu, 20 Oct 2022 18:58:30 -0700 Subject: [PATCH 11/12] Disable BLS for Linux --- Sources/Classes/Ethereum2/SecretKeyEth2.swift | 3 +++ Sources/Extensions/BLS/Data+BLS.swift | 4 ++++ Sources/Extensions/BLS/blsPublicKey+Data.swift | 3 +++ Sources/Extensions/BLS/blsSecretKey+PublicKey.swift | 4 ++++ 4 files changed, 14 insertions(+) diff --git a/Sources/Classes/Ethereum2/SecretKeyEth2.swift b/Sources/Classes/Ethereum2/SecretKeyEth2.swift index 68225fe..13dd198 100644 --- a/Sources/Classes/Ethereum2/SecretKeyEth2.swift +++ b/Sources/Classes/Ethereum2/SecretKeyEth2.swift @@ -6,6 +6,8 @@ // Copyright © 2020 MyEtherWallet Inc. All rights reserved. // +#if !os(Linux) + import Foundation import bls_framework @@ -98,3 +100,4 @@ extension SecretKeyEth2: BIP32 { return derivedSK } } +#endif diff --git a/Sources/Extensions/BLS/Data+BLS.swift b/Sources/Extensions/BLS/Data+BLS.swift index 91bcd56..8d9aa9b 100644 --- a/Sources/Extensions/BLS/Data+BLS.swift +++ b/Sources/Extensions/BLS/Data+BLS.swift @@ -6,6 +6,8 @@ // Copyright © 2020 MyEtherWallet Inc. All rights reserved. // +#if !os(Linux) + import Foundation import bls_framework import CryptoSwift @@ -55,3 +57,5 @@ extension Data { return result } } + +#endif diff --git a/Sources/Extensions/BLS/blsPublicKey+Data.swift b/Sources/Extensions/BLS/blsPublicKey+Data.swift index cda5fb5..1524d03 100644 --- a/Sources/Extensions/BLS/blsPublicKey+Data.swift +++ b/Sources/Extensions/BLS/blsPublicKey+Data.swift @@ -6,6 +6,8 @@ // Copyright © 2020 MyEtherWallet Inc. All rights reserved. // +#if !os(Linux) + import Foundation import bls_framework @@ -19,3 +21,4 @@ extension blsPublicKey { return Data(bytes) } } +#endif diff --git a/Sources/Extensions/BLS/blsSecretKey+PublicKey.swift b/Sources/Extensions/BLS/blsSecretKey+PublicKey.swift index b4c2354..7585856 100644 --- a/Sources/Extensions/BLS/blsSecretKey+PublicKey.swift +++ b/Sources/Extensions/BLS/blsSecretKey+PublicKey.swift @@ -6,6 +6,8 @@ // Copyright © 2020 MyEtherWallet Inc. All rights reserved. // +#if !os(Linux) + import Foundation import bls_framework @@ -18,3 +20,5 @@ extension blsSecretKey { return publicKey } } + +#endif From 991be74cb34bef7ce52f4a8cadbcd24351fb86dc Mon Sep 17 00:00:00 2001 From: Ronald Mannak Date: Thu, 20 Oct 2022 21:37:30 -0700 Subject: [PATCH 12/12] Remove Linux code --- Sources/Classes/Ethereum2/SecretKeyEth2.swift | 3 --- Sources/Extensions/BLS/Data+BLS.swift | 4 ---- Sources/Extensions/BLS/blsPublicKey+Data.swift | 2 -- Sources/Extensions/BLS/blsSecretKey+PublicKey.swift | 4 ---- 4 files changed, 13 deletions(-) diff --git a/Sources/Classes/Ethereum2/SecretKeyEth2.swift b/Sources/Classes/Ethereum2/SecretKeyEth2.swift index 13dd198..68225fe 100644 --- a/Sources/Classes/Ethereum2/SecretKeyEth2.swift +++ b/Sources/Classes/Ethereum2/SecretKeyEth2.swift @@ -6,8 +6,6 @@ // Copyright © 2020 MyEtherWallet Inc. All rights reserved. // -#if !os(Linux) - import Foundation import bls_framework @@ -100,4 +98,3 @@ extension SecretKeyEth2: BIP32 { return derivedSK } } -#endif diff --git a/Sources/Extensions/BLS/Data+BLS.swift b/Sources/Extensions/BLS/Data+BLS.swift index 8d9aa9b..91bcd56 100644 --- a/Sources/Extensions/BLS/Data+BLS.swift +++ b/Sources/Extensions/BLS/Data+BLS.swift @@ -6,8 +6,6 @@ // Copyright © 2020 MyEtherWallet Inc. All rights reserved. // -#if !os(Linux) - import Foundation import bls_framework import CryptoSwift @@ -57,5 +55,3 @@ extension Data { return result } } - -#endif diff --git a/Sources/Extensions/BLS/blsPublicKey+Data.swift b/Sources/Extensions/BLS/blsPublicKey+Data.swift index 1524d03..9fcca82 100644 --- a/Sources/Extensions/BLS/blsPublicKey+Data.swift +++ b/Sources/Extensions/BLS/blsPublicKey+Data.swift @@ -6,7 +6,6 @@ // Copyright © 2020 MyEtherWallet Inc. All rights reserved. // -#if !os(Linux) import Foundation import bls_framework @@ -21,4 +20,3 @@ extension blsPublicKey { return Data(bytes) } } -#endif diff --git a/Sources/Extensions/BLS/blsSecretKey+PublicKey.swift b/Sources/Extensions/BLS/blsSecretKey+PublicKey.swift index 7585856..b4c2354 100644 --- a/Sources/Extensions/BLS/blsSecretKey+PublicKey.swift +++ b/Sources/Extensions/BLS/blsSecretKey+PublicKey.swift @@ -6,8 +6,6 @@ // Copyright © 2020 MyEtherWallet Inc. All rights reserved. // -#if !os(Linux) - import Foundation import bls_framework @@ -20,5 +18,3 @@ extension blsSecretKey { return publicKey } } - -#endif