mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 18:25:51 +00:00
ECKey: preserve compression state when deserializing from ASN.1.
Resolves issue 528.
This commit is contained in:
parent
f27558bcd2
commit
e397928ec3
@ -143,7 +143,7 @@ public class ECKey implements Serializable {
|
||||
* reference implementation in its wallet. Note that this is slow because it requires an EC point multiply.
|
||||
*/
|
||||
public static ECKey fromASN1(byte[] asn1privkey) {
|
||||
return new ECKey(extractPrivateKeyFromASN1(asn1privkey));
|
||||
return extractKeyFromASN1(asn1privkey);
|
||||
}
|
||||
|
||||
/** Creates an ECKey given the private key only. The public key is calculated from it (this is slow) */
|
||||
@ -559,7 +559,7 @@ public class ECKey implements Serializable {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static BigInteger extractPrivateKeyFromASN1(byte[] asn1privkey) {
|
||||
private static ECKey extractKeyFromASN1(byte[] asn1privkey) {
|
||||
// To understand this code, see the definition of the ASN.1 format for EC private keys in the OpenSSL source
|
||||
// code in ec_asn1.c:
|
||||
//
|
||||
@ -577,9 +577,18 @@ public class ECKey implements Serializable {
|
||||
checkArgument(((DERInteger) seq.getObjectAt(0)).getValue().equals(BigInteger.ONE),
|
||||
"Input is of wrong version");
|
||||
Object obj = seq.getObjectAt(1);
|
||||
byte[] bits = ((ASN1OctetString) obj).getOctets();
|
||||
byte[] privbits = ((ASN1OctetString) obj).getOctets();
|
||||
decoder.close();
|
||||
return new BigInteger(1, bits);
|
||||
BigInteger privkey = new BigInteger(1, privbits);
|
||||
byte[] pubbits = ((DERBitString)((ASN1TaggedObject)seq.getObjectAt(3)).getObject()).getBytes();
|
||||
// Now sanity check to ensure the pubkey bytes match the privkey.
|
||||
byte[] compressed = publicKeyFromPrivate(privkey, true);
|
||||
if (Arrays.equals(pubbits, compressed))
|
||||
return new ECKey(privkey, compressed);
|
||||
byte[] uncompressed = publicKeyFromPrivate(privkey, false);
|
||||
if (Arrays.equals(pubbits, uncompressed))
|
||||
return new ECKey(privkey, uncompressed);
|
||||
throw new IllegalArgumentException("Public key in ASN.1 structure does not match private key.");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e); // Cannot happen, reading from memory stream.
|
||||
}
|
||||
|
@ -39,15 +39,14 @@ import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.crypto.params.KeyParameter;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.SignatureException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static com.google.bitcoin.core.Utils.reverseBytes;
|
||||
@ -171,6 +170,11 @@ public class ECKeyTest {
|
||||
"11da3761e86431e4a54c176789e41f1651b324d240d599a7067bee23d328ec2a"));
|
||||
assertTrue(roundtripKey.verify(message, decodedKey.sign(new Sha256Hash(message)).encodeToDER()));
|
||||
assertTrue(decodedKey.verify(message, roundtripKey.sign(new Sha256Hash(message)).encodeToDER()));
|
||||
|
||||
// Verify bytewise equivalence of public keys (i.e. compression state is preserved)
|
||||
ECKey key = new ECKey();
|
||||
ECKey key2 = ECKey.fromASN1(key.toASN1());
|
||||
assertArrayEquals(key.getPubKey(), key2.getPubKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -367,7 +371,7 @@ public class ECKeyTest {
|
||||
public void keyRecoveryWithEncryptedKey() throws Exception {
|
||||
ECKey unencryptedKey = new ECKey();
|
||||
KeyParameter aesKey = keyCrypter.deriveKey(PASSWORD1);
|
||||
ECKey encryptedKey = unencryptedKey.encrypt(keyCrypter,aesKey);
|
||||
ECKey encryptedKey = unencryptedKey.encrypt(keyCrypter, aesKey);
|
||||
|
||||
String message = "Goodbye Jupiter!";
|
||||
Sha256Hash hash = Sha256Hash.create(message.getBytes());
|
||||
|
Loading…
x
Reference in New Issue
Block a user