@@ -65,19 +65,19 @@ public class EthereumKeystoreV3: AbstractKeystore {
65
65
}
66
66
}
67
67
68
- public init ? ( password: String = " BANKEXFOUNDATION " ) throws {
68
+ public init ? ( password: String = " BANKEXFOUNDATION " , aesMode : String = " aes-128-cbc " ) throws {
69
69
guard var newPrivateKey = SECP256K1 . generatePrivateKey ( ) else { return nil }
70
70
defer { Data . zero ( & newPrivateKey) }
71
- try encryptDataToStorage ( password, keyData: newPrivateKey)
71
+ try encryptDataToStorage ( password, keyData: newPrivateKey, aesMode : aesMode )
72
72
}
73
73
74
- public init ? ( privateKey: Data , password: String = " BANKEXFOUNDATION " ) throws {
74
+ public init ? ( privateKey: Data , password: String = " BANKEXFOUNDATION " , aesMode : String = " aes-128-cbc " ) throws {
75
75
guard privateKey. count == 32 else { return nil }
76
76
guard SECP256K1 . verifyPrivateKey ( privateKey: privateKey) else { return nil }
77
- try encryptDataToStorage ( password, keyData: privateKey)
77
+ try encryptDataToStorage ( password, keyData: privateKey, aesMode : aesMode )
78
78
}
79
79
80
- fileprivate func encryptDataToStorage( _ password: String , keyData: Data ? , dkLen: Int = 32 , N: Int = 4096 , R: Int = 6 , P: Int = 1 ) throws {
80
+ 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 {
81
81
if ( keyData == nil ) {
82
82
throw AbstractKeystoreError . encryptionError ( " Encryption without key data " )
83
83
}
@@ -87,16 +87,27 @@ public class EthereumKeystoreV3: AbstractKeystore {
87
87
let last16bytes = derivedKey [ ( derivedKey. count - 16 ) ... ( derivedKey. count- 1 ) ]
88
88
let encryptionKey = derivedKey [ 0 ... 15 ]
89
89
guard let IV = Data . randomBytes ( length: 16 ) else { throw AbstractKeystoreError . noEntropyError}
90
- let aecCipher = try ? AES ( key: encryptionKey. bytes, blockMode: CBC ( iv: IV . bytes) , padding: . noPadding)
91
- guard let encryptedKey = try aecCipher? . encrypt ( keyData!. bytes) else { throw AbstractKeystoreError . aesError}
90
+ var aesCipher : AES ?
91
+ switch aesMode {
92
+ case " aes-128-cbc " :
93
+ aesCipher = try ? AES ( key: encryptionKey. bytes, blockMode: CBC ( iv: IV . bytes) , padding: . noPadding)
94
+ case " aes-128-ctr " :
95
+ aesCipher = try ? AES ( key: encryptionKey. bytes, blockMode: CTR ( iv: IV . bytes) , padding: . noPadding)
96
+ default :
97
+ aesCipher = nil
98
+ }
99
+ if aesCipher == nil {
100
+ throw AbstractKeystoreError . aesError
101
+ }
102
+ guard let encryptedKey = try aesCipher? . encrypt ( keyData!. bytes) else { throw AbstractKeystoreError . aesError}
92
103
let encryptedKeyData = Data ( bytes: encryptedKey)
93
104
var dataForMAC = Data ( )
94
105
dataForMAC. append ( last16bytes)
95
106
dataForMAC. append ( encryptedKeyData)
96
107
let mac = dataForMAC. sha3 ( . keccak256)
97
108
let kdfparams = KdfParamsV3 ( salt: saltData. toHexString ( ) , dklen: dkLen, n: N, p: P, r: R, c: nil , prf: nil )
98
109
let cipherparams = CipherParamsV3 ( iv: IV . toHexString ( ) )
99
- let crypto = CryptoParamsV3 ( ciphertext: encryptedKeyData. toHexString ( ) , cipher: " aes-128-cbc " , cipherparams: cipherparams, kdf: " scrypt " , kdfparams: kdfparams, mac: mac. toHexString ( ) , version: nil )
110
+ let crypto = CryptoParamsV3 ( ciphertext: encryptedKeyData. toHexString ( ) , cipher: aesMode , cipherparams: cipherparams, kdf: " scrypt " , kdfparams: kdfparams, mac: mac. toHexString ( ) , version: nil )
100
111
guard let pubKey = Web3 . Utils. privateToPublic ( keyData!) else { throw AbstractKeystoreError . keyDerivationError}
101
112
guard let addr = Web3 . Utils. publicToAddress ( pubKey) else { throw AbstractKeystoreError . keyDerivationError}
102
113
self . address = addr
@@ -110,7 +121,7 @@ public class EthereumKeystoreV3: AbstractKeystore {
110
121
throw AbstractKeystoreError . encryptionError ( " Failed to decrypt a keystore " )
111
122
}
112
123
defer { Data . zero ( & keyData!) }
113
- try self . encryptDataToStorage ( newPassword, keyData: keyData!)
124
+ try self . encryptDataToStorage ( newPassword, keyData: keyData!, aesMode : self . keystoreParams! . crypto . cipher )
114
125
}
115
126
116
127
fileprivate func getKeyData( _ password: String ) throws -> Data ? {
@@ -128,14 +139,14 @@ public class EthereumKeystoreV3: AbstractKeystore {
128
139
guard let algo = keystoreParams. crypto. kdfparams. prf else { return nil }
129
140
var hashVariant : HMAC . Variant ? ;
130
141
switch algo {
131
- case " hmac-sha256 " :
132
- hashVariant = HMAC . Variant. sha256
133
- case " hmac-sha384 " :
134
- hashVariant = HMAC . Variant. sha384
135
- case " hmac-sha512 " :
136
- hashVariant = HMAC . Variant. sha512
137
- default :
138
- hashVariant = nil
142
+ case " hmac-sha256 " :
143
+ hashVariant = HMAC . Variant. sha256
144
+ case " hmac-sha384 " :
145
+ hashVariant = HMAC . Variant. sha384
146
+ case " hmac-sha512 " :
147
+ hashVariant = HMAC . Variant. sha512
148
+ default :
149
+ hashVariant = nil
139
150
}
140
151
guard ( hashVariant != nil ) else { return nil }
141
152
guard let c = keystoreParams. crypto. kdfparams. c else { return nil }
0 commit comments