org.bouncycastle.math.ec.custom.sec.SecP256K1Curve Java Examples

The following examples show how to use org.bouncycastle.math.ec.custom.sec.SecP256K1Curve. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Signature.java    From etherjar with Apache License 2.0 6 votes vote down vote up
/**
 * Decompress a compressed public key (x coordinate and low-bit of y-coordinate).
 *
 * @param xBN X-coordinate
 * @param yBit Sign of Y-coordinate
 * @return Uncompressed public key
 */
private static ECPoint decompressKey(BigInteger xBN, boolean yBit) {
    SecP256K1Curve curve = (SecP256K1Curve)ecParams.getCurve();
    ECFieldElement x = curve.fromBigInteger(xBN);
    ECFieldElement alpha = x.multiply(x.square().add(curve.getA())).add(curve.getB());
    ECFieldElement beta = alpha.sqrt();
    if (beta == null)
        throw new IllegalArgumentException("Invalid point compression");
    ECPoint ecPoint;
    BigInteger nBeta = beta.toBigInteger();
    if (nBeta.testBit(0) == yBit) {
        ecPoint = curve.createPoint(x.toBigInteger(), nBeta);
    } else {
        ECFieldElement y = curve.fromBigInteger(curve.getQ().subtract(nBeta));
        ecPoint = curve.createPoint(x.toBigInteger(), y.toBigInteger());
    }
    return ecPoint;
}
 
Example #2
Source File: ECCEncrypt.java    From web3sdk with Apache License 2.0 5 votes vote down vote up
/**
 * create BCECPublicKey from publicKey and privateKey
 *
 * @param publicKey
 * @return
 */
private BCECPublicKey createBCECPublicKey(BigInteger publicKey) {
    // Handle public key.
    String publicKeyValue =
            Numeric.toHexStringNoPrefixZeroPadded(publicKey, Keys.PUBLIC_KEY_LENGTH_IN_HEX);
    String prePublicKeyStr = publicKeyValue.substring(0, 64);
    String postPublicKeyStr = publicKeyValue.substring(64);
    SecP256K1Curve secP256K1Curve = new SecP256K1Curve();
    SecP256K1Point secP256K1Point =
            (SecP256K1Point)
                    secP256K1Curve.createPoint(
                            new BigInteger(prePublicKeyStr, 16),
                            new BigInteger(postPublicKeyStr, 16));
    SecP256K1Point secP256K1PointG =
            (SecP256K1Point)
                    secP256K1Curve.createPoint(ECCParams.POINTG_PRE, ECCParams.POINTG_POST);

    ECDomainParameters domainParameters =
            new ECDomainParameters(secP256K1Curve, secP256K1PointG, ECCParams.FACTOR_N);
    ECPublicKeyParameters publicKeyParameters =
            new ECPublicKeyParameters(secP256K1Point, domainParameters);

    BCECPublicKey bcecPublicKey =
            new BCECPublicKey(
                    "ECDSA",
                    publicKeyParameters,
                    ECCParams.ecNamedCurveSpec,
                    BouncyCastleProvider.CONFIGURATION);

    return bcecPublicKey;
}
 
Example #3
Source File: Signature.java    From etherjar with Apache License 2.0 4 votes vote down vote up
/**
 *
 * @return public key derived from current v,R,S and message
 */
// implementation is based on BitcoinJ ECKey code
// see https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/core/ECKey.java
public byte[] ecrecover() {
    int recId = getRecId();
    SecP256K1Curve curve = (SecP256K1Curve)ecParams.getCurve();
    BigInteger n = ecParams.getN();

    // Let x = r + jn
    BigInteger i = BigInteger.valueOf((long)recId / 2);
    BigInteger x = r.add(i.multiply(n));

    if (x.compareTo(curve.getQ()) >= 0) {
        // Cannot have point co-ordinates larger than this as everything takes place modulo Q.
        return null;
    }

    // Compressed keys require you to know an extra bit of data about the y-coord as there are two possibilities.
    // So it's encoded in the recId.
    ECPoint R = decompressKey(x, (recId & 1) == 1);
    if (!R.multiply(n).isInfinity()) {
        // If nR != point at infinity, then recId (i.e. v) is invalid
        return null;
    }

    //
    // Compute a candidate public key as:
    // Q = mi(r) * (sR - eG)
    //
    // Where mi(x) is the modular multiplicative inverse. We transform this into the following:
    // Q = (mi(r) * s ** R) + (mi(r) * -e ** G)
    // Where -e is the modular additive inverse of e, that is z such that z + e = 0 (mod n).
    // In the above equation, ** is point multiplication and + is point addition (the EC group operator).
    //
    // We can find the additive inverse by subtracting e from zero then taking the mod. For example the additive
    // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod 11 = 8.
    //
    BigInteger e = new BigInteger(1, message);
    BigInteger eInv = BigInteger.ZERO.subtract(e).mod(n);
    BigInteger rInv = r.modInverse(n);
    BigInteger srInv = rInv.multiply(s).mod(n);
    BigInteger eInvrInv = rInv.multiply(eInv).mod(n);

    ECPoint q = ECAlgorithms.sumOfTwoMultiplies(ecParams.getG(), eInvrInv, R, srInv);

    // For Ethereum we don't use first byte of the key
    byte[] full = q.getEncoded(false);
    byte[] ethereum = new byte[full.length - 1];
    System.arraycopy(full, 1, ethereum, 0, ethereum.length);
    return ethereum;
}