3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-13 10:45:51 +00:00

Use FixedPointCombMultiplier for mul by G

This commit is contained in:
Peter Dettman 2015-06-12 16:17:15 +07:00 committed by Mike Hearn
parent 62f22d83a0
commit e3bba1c3cb
3 changed files with 24 additions and 9 deletions

View File

@ -39,6 +39,7 @@ import org.spongycastle.crypto.signers.ECDSASigner;
import org.spongycastle.crypto.signers.HMacDSAKCalculator;
import org.spongycastle.math.ec.ECAlgorithms;
import org.spongycastle.math.ec.ECPoint;
import org.spongycastle.math.ec.FixedPointCombMultiplier;
import org.spongycastle.math.ec.FixedPointUtil;
import org.spongycastle.math.ec.custom.sec.SecP256K1Curve;
import org.spongycastle.util.encoders.Base64;
@ -243,7 +244,7 @@ public class ECKey implements EncryptableItem, Serializable {
* compressed or not.
*/
public static ECKey fromPrivate(BigInteger privKey, boolean compressed) {
ECPoint point = CURVE.getG().multiply(privKey);
ECPoint point = publicPointFromPrivate(privKey);
return new ECKey(privKey, compressed ? compressPoint(point) : decompressPoint(point));
}
@ -361,7 +362,7 @@ public class ECKey implements EncryptableItem, Serializable {
this.priv = privKey;
if (pubKey == null) {
// Derive public from private.
ECPoint point = CURVE.getG().multiply(privKey);
ECPoint point = publicPointFromPrivate(privKey);
if (compressed)
point = compressPoint(point);
this.pub = new LazyECPoint(point);
@ -439,10 +440,25 @@ public class ECKey implements EncryptableItem, Serializable {
* new BigInteger(1, bytes);</tt>
*/
public static byte[] publicKeyFromPrivate(BigInteger privKey, boolean compressed) {
ECPoint point = CURVE.getG().multiply(privKey);
ECPoint point = publicPointFromPrivate(privKey);
return point.getEncoded(compressed);
}
/**
* Returns public key point from the given private key. To convert a byte array into a BigInteger, use <tt>
* new BigInteger(1, bytes);</tt>
*/
public static ECPoint publicPointFromPrivate(BigInteger privKey) {
/*
* TODO: FixedPointCombMultiplier currently doesn't support scalars longer than the group order,
* but that could change in future versions.
*/
if (privKey.bitLength() > CURVE.getN().bitLength()) {
privKey = privKey.mod(CURVE.getN());
}
return new FixedPointCombMultiplier().multiply(CURVE.getG(), privKey);
}
/** Gets the hash160 form of the public key (as seen in addresses). */
public byte[] getPubKeyHash() {
if (pubKeyHash == null)

View File

@ -88,7 +88,7 @@ public class DeterministicKey extends ECKey {
byte[] chainCode,
BigInteger priv,
@Nullable DeterministicKey parent) {
super(priv, compressPoint(ECKey.CURVE.getG().multiply(priv)));
super(priv, compressPoint(ECKey.publicPointFromPrivate(priv)));
checkArgument(chainCode.length == 32);
this.parent = parent;
this.childNumberPath = checkNotNull(childNumberPath);
@ -156,7 +156,7 @@ public class DeterministicKey extends ECKey {
@Nullable DeterministicKey parent,
int depth,
int parentFingerprint) {
super(priv, compressPoint(ECKey.CURVE.getG().multiply(priv)));
super(priv, compressPoint(ECKey.publicPointFromPrivate(priv)));
checkArgument(chainCode.length == 32);
this.parent = parent;
this.childNumberPath = checkNotNull(childNumberPath);

View File

@ -194,21 +194,20 @@ public final class HDKeyDerivation {
BigInteger ilInt = new BigInteger(1, il);
assertLessThanN(ilInt, "Illegal derived key: I_L >= n");
final ECPoint G = ECKey.CURVE.getG();
final BigInteger N = ECKey.CURVE.getN();
ECPoint Ki;
switch (mode) {
case NORMAL:
Ki = G.multiply(ilInt).add(parent.getPubKeyPoint());
Ki = ECKey.publicPointFromPrivate(ilInt).add(parent.getPubKeyPoint());
break;
case WITH_INVERSION:
// This trick comes from Gregory Maxwell. Check the homomorphic properties of our curve hold. The
// below calculations should be redundant and give the same result as NORMAL but if the precalculated
// tables have taken a bit flip will yield a different answer. This mode is used when vending a key
// to perform a last-ditch sanity check trying to catch bad RAM.
Ki = G.multiply(ilInt.add(RAND_INT));
Ki = ECKey.publicPointFromPrivate(ilInt.add(RAND_INT).mod(N));
BigInteger additiveInverse = RAND_INT.negate().mod(N);
Ki = Ki.add(G.multiply(additiveInverse));
Ki = Ki.add(ECKey.publicPointFromPrivate(additiveInverse));
Ki = Ki.add(parent.getPubKeyPoint());
break;
default: throw new AssertionError();