|
12 | 12 | import org.junit.Test; |
13 | 13 |
|
14 | 14 | import java.io.File; |
15 | | -import java.util.Arrays; |
| 15 | +import java.nio.charset.StandardCharsets; |
16 | 16 | import java.util.Collection; |
17 | 17 | import java.util.Collections; |
18 | 18 | import java.util.List; |
19 | 19 | import java.util.concurrent.TimeUnit; |
20 | 20 |
|
21 | 21 | import com.breadwallet.corecrypto.HelpersAIT.RecordingSystemListener; |
22 | 22 | import com.breadwallet.crypto.AddressScheme; |
| 23 | +import com.breadwallet.crypto.Coder; |
| 24 | +import com.breadwallet.crypto.Cipher; |
23 | 25 | import com.breadwallet.crypto.Currency; |
| 26 | +import com.breadwallet.crypto.Key; |
24 | 27 | import com.breadwallet.crypto.Network; |
25 | 28 | import com.breadwallet.crypto.System; |
26 | 29 | import com.breadwallet.crypto.Unit; |
|
40 | 43 | import com.google.common.primitives.UnsignedLong; |
41 | 44 | import com.google.common.util.concurrent.Uninterruptibles; |
42 | 45 |
|
| 46 | +import static org.junit.Assert.assertArrayEquals; |
43 | 47 | import static org.junit.Assert.assertEquals; |
44 | 48 | import static org.junit.Assert.assertFalse; |
45 | 49 | import static org.junit.Assert.assertNotEquals; |
@@ -105,6 +109,154 @@ public void testSystemAppCurrencies() { |
105 | 109 | assertEquals("fooi", fooBase.get().getSymbol()); |
106 | 110 | } |
107 | 111 |
|
| 112 | + @Test |
| 113 | + public void testSystemMigrateBRCoreKeyCiphertext() { |
| 114 | + // Setup the expected data |
| 115 | + |
| 116 | + Coder coder = Coder.createForAlgorithm(Coder.Algorithm.HEX); |
| 117 | + |
| 118 | + byte[] authenticateData = new byte[0]; |
| 119 | + |
| 120 | + Optional<byte[]> maybeNonce12 = coder.decode( |
| 121 | + "00000000ed41e4e70e000000"); |
| 122 | + assertTrue(maybeNonce12.isPresent()); |
| 123 | + byte[] nonce12 = maybeNonce12.get(); |
| 124 | + |
| 125 | + Optional<byte[]> maybeCiphertext = coder.decode( |
| 126 | + "1e611714327192ec8454f1e05b1437fa4e56c77ab132d31925c1834f7ed67b7b14d93bdde51b43d38" + |
| 127 | + "11b2f22a23ca86287ce130740633f0680207137dabae3faa778c4b45ab692eea527902237ee1cfb9" + |
| 128 | + "97217e9df27e8d9131609d2e96745f1dac6c54b180621bacbb00845fe4183c1192d8f45cc267de7e" + |
| 129 | + "4ab943dfd73080ae5a3f1dd7c2ea2cc3a009a405154544938c22972744aa62e631c32e9ea7eaa687" + |
| 130 | + "ccbc244c6b97d9d69644d4b74805837c5ca3caedd63"); |
| 131 | + assertTrue(maybeCiphertext.isPresent()); |
| 132 | + byte[] ciphertext = maybeCiphertext.get(); |
| 133 | + |
| 134 | + Optional<byte[]> maybeExpectedPlaintext = coder.decode( |
| 135 | + "425a6839314159265359a70ea17800004e5f80400010077ff02c2001003f679c0a200072229ea7a86" + |
| 136 | + "41a6d47a81a00f5340d53d348f54f4c2479266a7a9e9a9ea3432d1f1618e7e529ecd56e5203e90c3" + |
| 137 | + "48494fd7b98217b4b525b1c41335aee41453c8c121998a4cc2ef5856afa62e6b82358d48acd52866" + |
| 138 | + "cc671180b0f2f83aa5c891bb8c043bd254cfd2054b5930bd1910328ea5235866bf4ff8bb9229c284" + |
| 139 | + "8538750bc00"); |
| 140 | + assertTrue(maybeExpectedPlaintext.isPresent()); |
| 141 | + byte[] expectedPlaintext = maybeExpectedPlaintext.get(); |
| 142 | + |
| 143 | + // Test with paper key |
| 144 | + |
| 145 | + { |
| 146 | + byte[] pk = "truly flame one position follow sponsor frost oval tuna swallow situate talk".getBytes(StandardCharsets.UTF_8); |
| 147 | + Optional<? extends Key> maybeCryptoEncodedKey = Key.createForBIP32ApiAuth(pk, HelpersAIT.BIP39_WORDS_EN); |
| 148 | + assertTrue(maybeCryptoEncodedKey.isPresent()); |
| 149 | + Key key = maybeCryptoEncodedKey.get(); |
| 150 | + |
| 151 | + // Migrate using the crypto address params key |
| 152 | + |
| 153 | + Optional<byte[]> maybeMigratedCiphertext = System.migrateBRCoreKeyCiphertext(key, nonce12, authenticateData, ciphertext); |
| 154 | + assertTrue(maybeMigratedCiphertext.isPresent()); |
| 155 | + byte[] migratedCiphertext = maybeMigratedCiphertext.get(); |
| 156 | + |
| 157 | + // Decrypt using the crypto address params key |
| 158 | + |
| 159 | + Cipher cipher = Cipher.createForChaCha20Poly1305(key, nonce12, authenticateData); |
| 160 | + Optional<byte[]> maybeDecryptedPlaintext = cipher.decrypt(migratedCiphertext); |
| 161 | + assertTrue(maybeDecryptedPlaintext.isPresent()); |
| 162 | + byte[] decryptedPlaintext = maybeDecryptedPlaintext.get(); |
| 163 | + |
| 164 | + // Verify correct decryption |
| 165 | + |
| 166 | + assertArrayEquals(expectedPlaintext, decryptedPlaintext); |
| 167 | + } |
| 168 | + |
| 169 | + // Test with a private key string encoded using CRYPTO_ADDRESS_PARAMS |
| 170 | + |
| 171 | + byte[] cryptoAddressParamsMigratedCiphertext; |
| 172 | + { |
| 173 | + // Load the correct key encoded with the crypto address params |
| 174 | + |
| 175 | + byte[] ks = "T7GNuCG4XzHaPGhmUTVGvTnHZodVTrV7KKj1K1vVwTcNcSADqnb5".getBytes(StandardCharsets.UTF_8); |
| 176 | + Optional<? extends Key> maybeCryptoEncodedKey = Key.createFromPrivateKeyString(ks); |
| 177 | + assertTrue(maybeCryptoEncodedKey.isPresent()); |
| 178 | + Key key = maybeCryptoEncodedKey.get(); |
| 179 | + |
| 180 | + // Migrate using the crypto address params key |
| 181 | + |
| 182 | + Optional<byte[]> maybeMigratedCiphertext = System.migrateBRCoreKeyCiphertext(key, nonce12, authenticateData, ciphertext); |
| 183 | + assertTrue(maybeMigratedCiphertext.isPresent()); |
| 184 | + cryptoAddressParamsMigratedCiphertext = maybeMigratedCiphertext.get(); |
| 185 | + |
| 186 | + // Decrypt using the crypto address params key |
| 187 | + |
| 188 | + Cipher cipher = Cipher.createForChaCha20Poly1305(key, nonce12, authenticateData); |
| 189 | + Optional<byte[]> maybeDecryptedPlaintext = cipher.decrypt(cryptoAddressParamsMigratedCiphertext); |
| 190 | + assertTrue(maybeDecryptedPlaintext.isPresent()); |
| 191 | + byte[] decryptedPlaintext = maybeDecryptedPlaintext.get(); |
| 192 | + |
| 193 | + // Verify correct decryption |
| 194 | + |
| 195 | + assertArrayEquals(expectedPlaintext, decryptedPlaintext); |
| 196 | + } |
| 197 | + |
| 198 | + // Test with a private key string encoded using BITCOIN_ADDRESS_PARAMS |
| 199 | + |
| 200 | + byte[] mainnetAddressParamsMigratedCiphertext; |
| 201 | + { |
| 202 | + // Load the correct key encoded with the bitcoin address params |
| 203 | + |
| 204 | + byte[] ks = "cRo6vMxjZg1EmsYAKEMY5RjyFBHb4DZua9yDZdkTsc6DMHhv8Unr".getBytes(StandardCharsets.UTF_8); |
| 205 | + Optional<? extends Key> maybeCryptoEncodedKey = Key.createFromPrivateKeyString(ks); |
| 206 | + assertTrue(maybeCryptoEncodedKey.isPresent()); |
| 207 | + Key key = maybeCryptoEncodedKey.get(); |
| 208 | + |
| 209 | + // Migrate using the crypto address params key |
| 210 | + |
| 211 | + Optional<byte[]> maybeMigratedCiphertext = System.migrateBRCoreKeyCiphertext(key, nonce12, authenticateData, ciphertext); |
| 212 | + assertTrue(maybeMigratedCiphertext.isPresent()); |
| 213 | + mainnetAddressParamsMigratedCiphertext = maybeMigratedCiphertext.get(); |
| 214 | + |
| 215 | + // Decrypt using the crypto address params key |
| 216 | + |
| 217 | + Cipher cipher = Cipher.createForChaCha20Poly1305(key, nonce12, authenticateData); |
| 218 | + Optional<byte[]> maybeDecryptedPlaintext = cipher.decrypt(mainnetAddressParamsMigratedCiphertext); |
| 219 | + assertTrue(maybeDecryptedPlaintext.isPresent()); |
| 220 | + byte[] decryptedPlaintext = maybeDecryptedPlaintext.get(); |
| 221 | + |
| 222 | + // Verify correct decryption |
| 223 | + |
| 224 | + assertArrayEquals(expectedPlaintext, decryptedPlaintext); |
| 225 | + } |
| 226 | + |
| 227 | + // Confirm that migrated ciphertext is the same, regardless of private key encoding |
| 228 | + |
| 229 | + assertArrayEquals(cryptoAddressParamsMigratedCiphertext, mainnetAddressParamsMigratedCiphertext); |
| 230 | + |
| 231 | + { |
| 232 | + // Load the incorrect uncompressed key |
| 233 | + |
| 234 | + byte[] ks = "5Kb8kLf9zgWQnogidDA76MzPL6TsZZY36hWXMssSzNydYXYB9KF".getBytes(StandardCharsets.UTF_8); |
| 235 | + Optional<? extends Key> maybeCryptoEncodedKey = Key.createFromPrivateKeyString(ks); |
| 236 | + assertTrue(maybeCryptoEncodedKey.isPresent()); |
| 237 | + Key key = maybeCryptoEncodedKey.get(); |
| 238 | + |
| 239 | + // Migrate and fail |
| 240 | + |
| 241 | + Optional<byte[]> maybeMigratedCiphertext = System.migrateBRCoreKeyCiphertext(key, nonce12, authenticateData, ciphertext); |
| 242 | + assertFalse(maybeMigratedCiphertext.isPresent()); |
| 243 | + } |
| 244 | + |
| 245 | + { |
| 246 | + // Load the incorrect uncompressed key |
| 247 | + |
| 248 | + byte[] ks = "KyvGbxRUoofdw3TNydWn2Z78dBHSy2odn1d3wXWN2o3SAtccFNJL".getBytes(StandardCharsets.UTF_8); |
| 249 | + Optional<? extends Key> maybeCryptoEncodedKey = Key.createFromPrivateKeyString(ks); |
| 250 | + assertTrue(maybeCryptoEncodedKey.isPresent()); |
| 251 | + Key key = maybeCryptoEncodedKey.get(); |
| 252 | + |
| 253 | + // Migrate and fail |
| 254 | + |
| 255 | + Optional<byte[]> maybeMigratedCiphertext = System.migrateBRCoreKeyCiphertext(key, nonce12, authenticateData, ciphertext); |
| 256 | + assertFalse(maybeMigratedCiphertext.isPresent()); |
| 257 | + } |
| 258 | + } |
| 259 | + |
108 | 260 | @Test |
109 | 261 | public void testSystemBtc() { |
110 | 262 | testSystemForCurrency("btc", WalletManagerMode.API_ONLY, AddressScheme.BTC_LEGACY); |
|
0 commit comments