@@ -23,13 +23,13 @@ public class EthereumKeystoreV3: AbstractKeystore {
2323 }
2424
2525 public func UNSAFE_getPrivateKeyData( password: String , account: EthereumAddress ) throws -> Data {
26- if self . addresses ? . count == 1 && account == self . addresses? . last {
27- guard let privateKey = try ? self . getKeyData ( password) else {
26+ if account == addresses? . last {
27+ guard let privateKey = try ? getKeyData ( password) else {
2828 throw AbstractKeystoreError . invalidPasswordError
2929 }
3030 return privateKey
3131 }
32- throw AbstractKeystoreError . invalidAccountError
32+ throw AbstractKeystoreError . invalidAccountError ( " EthereumKeystoreV3. Cannot get private key: keystore doesn't contain information about given address \( account . address ) . " )
3333 }
3434
3535 // Class
@@ -77,7 +77,7 @@ public class EthereumKeystoreV3: AbstractKeystore {
7777 defer {
7878 Data . zero ( & newPrivateKey)
7979 }
80- try encryptDataToStorage ( password, keyData : newPrivateKey, aesMode: aesMode)
80+ try encryptDataToStorage ( password, privateKey : newPrivateKey, aesMode: aesMode)
8181 }
8282
8383 public init ? ( privateKey: Data , password: String , aesMode: String = " aes-128-cbc " ) throws {
@@ -87,68 +87,60 @@ public class EthereumKeystoreV3: AbstractKeystore {
8787 guard SECP256K1 . verifyPrivateKey ( privateKey: privateKey) else {
8888 return nil
8989 }
90- try encryptDataToStorage ( password, keyData : privateKey, aesMode: aesMode)
90+ try encryptDataToStorage ( password, privateKey : privateKey, aesMode: aesMode)
9191 }
9292
93- fileprivate func encryptDataToStorage( _ password: String , keyData : Data ? , dkLen: Int = 32 , N: Int = 4096 , R: Int = 6 , P: Int = 1 , aesMode: String = " aes-128-cbc " ) throws {
94- if keyData == nil {
95- throw AbstractKeystoreError . encryptionError ( " Encryption without key data " )
93+ fileprivate func encryptDataToStorage( _ password: String , privateKey : Data , dkLen: Int = 32 , N: Int = 4096 , R: Int = 6 , P: Int = 1 , aesMode: String = " aes-128-cbc " ) throws {
94+ if privateKey . count != 32 {
95+ throw AbstractKeystoreError . encryptionError ( " EthereumKeystoreV3. Attempted encryption with private key of length != 32. Given private key length is \( privateKey . count ) . " )
9696 }
9797 let saltLen = 32
9898 guard let saltData = Data . randomBytes ( length: saltLen) else {
99- throw AbstractKeystoreError . noEntropyError
99+ throw AbstractKeystoreError . noEntropyError ( " EthereumKeystoreV3. Failed to generate random bytes: `Data.randomBytes(length: \( saltLen ) )`. " )
100100 }
101101 guard let derivedKey = scrypt ( password: password, salt: saltData, length: dkLen, N: N, R: R, P: P) else {
102- throw AbstractKeystoreError . keyDerivationError
102+ throw AbstractKeystoreError . keyDerivationError ( " EthereumKeystoreV3. Scrypt function failed. " )
103103 }
104104 let last16bytes = Data ( derivedKey [ ( derivedKey. count - 16 ) ... ( derivedKey. count - 1 ) ] )
105105 let encryptionKey = Data ( derivedKey [ 0 ... 15 ] )
106106 guard let IV = Data . randomBytes ( length: 16 ) else {
107- throw AbstractKeystoreError . noEntropyError
107+ throw AbstractKeystoreError . noEntropyError ( " EthereumKeystoreV3. Failed to generate random bytes: `Data.randomBytes(length: 16)`. " )
108108 }
109- var aesCipher : AES ?
110- switch aesMode {
109+ var aesCipher : AES
110+ switch aesMode. lowercased ( ) {
111111 case " aes-128-cbc " :
112- aesCipher = try ? AES ( key: encryptionKey. bytes, blockMode: CBC ( iv: IV . bytes) , padding: . noPadding)
112+ aesCipher = try AES ( key: encryptionKey. bytes, blockMode: CBC ( iv: IV . bytes) , padding: . noPadding)
113113 case " aes-128-ctr " :
114- aesCipher = try ? AES ( key: encryptionKey. bytes, blockMode: CTR ( iv: IV . bytes) , padding: . noPadding)
114+ aesCipher = try AES ( key: encryptionKey. bytes, blockMode: CTR ( iv: IV . bytes) , padding: . noPadding)
115115 default :
116- aesCipher = nil
116+ throw AbstractKeystoreError . aesError ( " EthereumKeystoreV3. AES error: given AES mode can be one of 'aes-128-cbc' or 'aes-128-ctr'. Instead ' \( aesMode ) ' was given. " )
117117 }
118- if aesCipher == nil {
119- throw AbstractKeystoreError . aesError
120- }
121- guard let encryptedKey = try aesCipher? . encrypt ( keyData!. bytes) else {
122- throw AbstractKeystoreError . aesError
123- }
124- let encryptedKeyData = Data ( encryptedKey)
125- var dataForMAC = Data ( )
126- dataForMAC. append ( last16bytes)
127- dataForMAC. append ( encryptedKeyData)
118+
119+ let encryptedKeyData = Data ( try aesCipher. encrypt ( privateKey. bytes) )
120+ let dataForMAC = last16bytes + encryptedKeyData
128121 let mac = dataForMAC. sha3 ( . keccak256)
129122 let kdfparams = KdfParamsV3 ( salt: saltData. toHexString ( ) , dklen: dkLen, n: N, p: P, r: R, c: nil , prf: nil )
130123 let cipherparams = CipherParamsV3 ( iv: IV . toHexString ( ) )
131124 let crypto = CryptoParamsV3 ( ciphertext: encryptedKeyData. toHexString ( ) , cipher: aesMode, cipherparams: cipherparams, kdf: " scrypt " , kdfparams: kdfparams, mac: mac. toHexString ( ) , version: nil )
132- guard let pubKey = Utilities . privateToPublic ( keyData! ) else {
133- throw AbstractKeystoreError . keyDerivationError
125+ guard let publicKey = Utilities . privateToPublic ( privateKey ) else {
126+ throw AbstractKeystoreError . keyDerivationError ( " EthereumKeystoreV3. Failed to derive public key from given private key. `Utilities.privateToPublic(privateKey)` returned `nil`. " )
134127 }
135- guard let addr = Utilities . publicToAddress ( pubKey ) else {
136- throw AbstractKeystoreError . keyDerivationError
128+ guard let addr = Utilities . publicToAddress ( publicKey ) else {
129+ throw AbstractKeystoreError . keyDerivationError ( " EthereumKeystoreV3. Failed to derive address from derived public key. `Utilities.publicToAddress(publicKey)` returned `nil`. " )
137130 }
138131 self . address = addr
139132 let keystoreparams = KeystoreParamsV3 ( address: addr. address. lowercased ( ) , crypto: crypto, id: UUID ( ) . uuidString. lowercased ( ) , version: 3 )
140133 self . keystoreParams = keystoreparams
141134 }
142135
143136 public func regenerate( oldPassword: String , newPassword: String , dkLen: Int = 32 , N: Int = 4096 , R: Int = 6 , P: Int = 1 ) throws {
144- var keyData = try self . getKeyData ( oldPassword)
145- if keyData == nil {
146- throw AbstractKeystoreError . encryptionError ( " Failed to decrypt a keystore " )
137+ guard var privateKey = try getKeyData ( oldPassword) else {
138+ throw AbstractKeystoreError . encryptionError ( " EthereumKeystoreV3. Failed to decrypt a keystore " )
147139 }
148140 defer {
149- Data . zero ( & keyData! )
141+ Data . zero ( & privateKey )
150142 }
151- try self . encryptDataToStorage ( newPassword, keyData : keyData! , aesMode: self . keystoreParams!. crypto. cipher)
143+ try self . encryptDataToStorage ( newPassword, privateKey : privateKey , aesMode: self . keystoreParams!. crypto. cipher)
152144 }
153145
154146 fileprivate func getKeyData( _ password: String ) throws -> Data ? {
0 commit comments