Skip to content
Browse files

made tests pass again

  • Loading branch information...
1 parent 7cadf5f commit 69d1e10f8b645085fc4cde5e4c3cfe4ba443be59 @dbasch committed Jan 17, 2014
View
6 README.md
@@ -4,9 +4,7 @@ A Java implementation of the BIP-0038 Draft: [Passphrase-protected private key](
## Usage
-`BIP38.encryptEC(password, lot, sequence)` generates an encrypted key starting with 6P.
-If you don't care about lot/sequence (if you don't know what they are, you don't care),
- just use -1 for the lot. That will cause those parameters to be ignored.
+`BIP38.generateEncryptedKey(password)` generates an encrypted key starting with "6P".
`BIP38.encryptNoEC(password, encodedKey, isCompressed)` encrypts a known key.
@@ -16,7 +14,7 @@ If you don't care about lot/sequence (if you don't know what they are, you don't
Key generation:
- `encrypt("hello", -1, -1)`
+ `generateEncryptedKey("hello")`
might produce
View
36 src/main/java/com/fruitcat/bitcoin/BIP38.java
@@ -34,10 +34,7 @@
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.security.GeneralSecurityException;
-import java.security.Key;
-import java.security.SecureRandom;
-import java.security.Security;
+import java.security.*;
import java.util.Arrays;
public class BIP38 {
@@ -51,16 +48,27 @@
/**
* Generates an encrypted key with EC multiplication.
* Only uncompressed format for now.
- * if lot is less than 0, lot and sequence are ignored.
+ *
* @param password
* @return
* @throws UnsupportedEncodingException
* @throws GeneralSecurityException
* @throws AddressFormatException
*/
- public static String encryptEC(String password, int lot, int sequence) throws UnsupportedEncodingException, GeneralSecurityException, AddressFormatException {
+ public static String generateEncryptedKey(String password) throws UnsupportedEncodingException, GeneralSecurityException, AddressFormatException {
+
+ byte[] intermediate = Arrays.copyOfRange(Base58.decode(intermediatePassphrase(password, -1, -1)), 0, 53);
+ return encryptedKeyFromIntermediate(intermediate, -1);
+ }
- byte[] intermediate = Base58.decode(intermediatePassphrase(password, lot, sequence));
+ /**
+ * if lot is less than 0, lot and sequence are ignored.
+ * @param intermediate
+ * @param lot
+ * @return
+ * @throws GeneralSecurityException
+ */
+ public static String encryptedKeyFromIntermediate(byte[] intermediate, int lot) throws GeneralSecurityException {
byte flagByte = (lot > 0) ? (byte) 4 : (byte) 0; //uncompressed
byte[] ownerEntropy = new byte[8];
@@ -89,7 +97,7 @@ public static String encryptEC(String password, int lot, int sequence) throws Un
byte[] m2 = new byte[16];
for (int i = 0; i < 16; i++) {
m1[i] = (byte) (seedB[i] ^ derivedHalf1[i]);
- m2[i] = (byte) (m2[i] ^ derivedHalf1[16 + i]);
+
}
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding", "BC");
@@ -98,6 +106,9 @@ public static String encryptEC(String password, int lot, int sequence) throws Un
byte[] encryptedPart1 = cipher.doFinal(m1);
System.arraycopy(encryptedPart1, 8, m2, 0, 8);
System.arraycopy(seedB, 16, m2, 8, 8);
+ for (int i = 0 ; i < 16; i ++) {
+ m2[i] = (byte) (m2[i] ^ derivedHalf1[16 + i]);
+ }
byte[] encryptedPart2 = cipher.doFinal(m2);
byte[] encryptedPrivateKey = new byte[39];
@@ -236,14 +247,14 @@ public static String decryptEC(String password, byte[] encryptedKey) throws Unsu
byte[] m2 = cipher.doFinal(encryptedPart2);
byte[] encryptedPart1 = new byte[16];
+ System.arraycopy(encryptedKey, 15, encryptedPart1, 0, 8);
+
byte[] seedB = new byte[24];
for (int i = 0; i < 16; i++) {
m2[i] = (byte) (m2[i] ^ derivedHalf1[16 + i]);
}
-
System.arraycopy(m2, 0, encryptedPart1, 8, 8);
- System.arraycopy(encryptedKey, 15, encryptedPart1, 0, 8);
byte[] m1 = cipher.doFinal(encryptedPart1);
@@ -276,7 +287,6 @@ public static String encryptNoEC(String encodedPrivateKey, String password, bool
DumpedPrivateKey dk = new DumpedPrivateKey(MainNetParams.get(), encodedPrivateKey);
ECKey key = dk.getKey();
- System.out.println(key.getPrivateKeyEncoded(MainNetParams.get()));
byte[] keyBytes = key.getPrivKeyBytes();
String address = key.toAddress(MainNetParams.get()).toString();
byte[] tmp = address.getBytes("ASCII");
@@ -345,8 +355,8 @@ public static String decryptNoEC(String password, byte[] encryptedKey) throws Un
// generate a key, decrypt it, print the decrypted key and the address.
public static void main(String args[]) throws Exception {
- String encryptedKey = encryptEC("hello", 1, 1);
- System.out.println(encryptedKey);
+ String encryptedKey = generateEncryptedKey("hello");
+ System.out.println("key is:" + encryptedKey);
String key = decrypt("hello", encryptedKey);
DumpedPrivateKey dk = new DumpedPrivateKey(MainNetParams.get(), key);
ECKey k = dk.getKey();
View
3 src/main/java/com/fruitcat/bitcoin/Utils.java
@@ -61,7 +61,8 @@ public static ECPoint compressPoint(ECPoint uncompressed) {
}
//for debugging
- protected static void pb(byte [] x) {
+ protected static void pb(String name, byte [] x) {
+ System.out.print(name + ": ");
for (byte b : x) {
int l = b >= 0 ? b : 256 + b;
System.out.print(l + " ");
View
14 src/test/java/com/fruitcat/bitcoin/BIP38Test.java
@@ -1,7 +1,10 @@
package com.fruitcat.bitcoin;
+import com.google.bitcoin.core.Base58;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
+
+import java.util.Arrays;
import java.util.Random;
/**
@@ -14,7 +17,7 @@
//EC multiply, no compression, no lot/sequence numbers
@Test
- public void decryptECNoCompressionNoLotTest() throws Exception {
+ public void decryptECNoCompressionNoLot() throws Exception {
String encryptedKey = "6PfQu77ygVyJLZjfvMLyhLMQbYnu5uguoJJ4kMCLqWwPEdfpwANVS76gTX";
String key = "5K4caxezwjGCGfnoPTZ8tMcJBLB7Jvyjv4xxeacadhq8nLisLR2";
String decryptedKey = BIP38.decrypt(testPass, encryptedKey);
@@ -36,9 +39,16 @@ public void randomRoundTripNoEC() throws Exception {
byte[] r = new byte[16];
(new Random()).nextBytes(r);
String randomPass = new String(r, "ASCII");
- System.out.println(randomPass);
String key = "5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR";
String encryptedKey = BIP38.encryptNoEC(key, randomPass, false);
assertEquals(key, (BIP38.decrypt(randomPass, encryptedKey)));
}
+
+ //generate an encrypted key and make sure it looks ok.
+ @Test
+ public void generateEncryptedKey() throws Exception {
+ String k = BIP38.generateEncryptedKey(testPass);
+ String dk = BIP38.decrypt(testPass, k);
+ assertEquals(dk.charAt(0), '5');
+ }
}

0 comments on commit 69d1e10

Please sign in to comment.
Something went wrong with that request. Please try again.