-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add EIP1024 conform encryption #7
base: develop
Are you sure you want to change the base?
Changes from 7 commits
a57d6c5
e024db2
6af69bd
9399458
44f6ccd
804286e
daf78a6
e63239c
441396d
fe3cdaf
4ef281c
991be74
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ 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 | ||
|
@@ -24,9 +25,52 @@ public struct EthEncryptedData: Codable { | |
|
||
public enum EthCryptoError: Error { | ||
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" | ||
} | ||
} | ||
} | ||
|
||
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 | ||
/// 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) | ||
|
||
|
@@ -51,12 +95,72 @@ extension EthEncryptedData { | |
|
||
return message | ||
} | ||
|
||
|
||
/// Decrypt the message using the sender's private key | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ronaldmannak this looks good to me, but indentations needs to be fixed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done and done |
||
/// - 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 { | ||
public func eth_publicKey() throws -> String { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ronaldmannak can you please keep this method to not break back compatibility, but mark it as 'deprecated'? |
||
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 | ||
public func curve25519PublicKeyData() throws -> Data { | ||
return try TweetNacl.keyPair(fromSecretKey: self.data()).publicKey | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ronaldmannak in that case I think it's better to have |
||
} | ||
|
||
/// 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 | ||
public func curve25519PrivateKeyData() throws -> Data { | ||
return try TweetNacl.keyPair(fromSecretKey: self.data()).secretKey | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ronaldmannak can be reverted