Example usage for org.bouncycastle.math.ec.custom.sec SecP256K1Curve getQ

List of usage examples for org.bouncycastle.math.ec.custom.sec SecP256K1Curve getQ

Introduction

In this page you can find the example usage for org.bouncycastle.math.ec.custom.sec SecP256K1Curve getQ.

Prototype

public BigInteger getQ() 

Source Link

Usage

From source file:org.ScripterRon.BitcoinCore.ECKey.java

License:Apache License

/**
 * <p>Given the components of a signature and a selector value, recover and return the public key
 * that generated the signature according to the algorithm in SEC1v2 section 4.1.6.</p>
 *
 * <p>The recID is an index from 0 to 3 which indicates which of the 4 possible keys is the correct one.
 * Because the key recovery operation yields multiple potential keys, the correct key must either be
 * stored alongside the signature, or you must be willing to try each recId in turn until you find one
 * that outputs the key you are expecting.</p>
 *
 * <p>If this method returns null, it means recovery was not possible and recID should be iterated.</p>
 *
 * <p>Given the above two points, a correct usage of this method is inside a for loop from 0 to 3, and if the
 * output is null OR a key that is not the one you expect, you try again with the next recID.</p>
 *
 * @param       recID               Which possible key to recover.
 * @param       sig                 R and S components of the signature
 * @param       e                   The double SHA-256 hash of the original message
 * @param       compressed          Whether or not the original public key was compressed
 * @return      An ECKey containing only the public part, or null if recovery wasn't possible
 *//*from w w  w . j a va  2 s. c  om*/
private static ECKey recoverFromSignature(int recID, ECDSASignature sig, BigInteger e, boolean compressed) {
    BigInteger n = ecParams.getN();
    BigInteger i = BigInteger.valueOf((long) recID / 2);
    BigInteger x = sig.getR().add(i.multiply(n));
    //
    //   Convert the integer x to an octet string X of length mlen using the conversion routine
    //        specified in Section 2.3.7, where mlen = (log2 p)/8 or mlen = m/8.
    //   Convert the octet string (16 set binary digits)||X to an elliptic curve point R using the
    //        conversion routine specified in Section 2.3.4. If this conversion routine outputs 'invalid', then
    //        do another iteration.
    //
    // More concisely, what these points mean is to use X as a compressed public key.
    //
    SecP256K1Curve curve = (SecP256K1Curve) ecParams.getCurve();
    BigInteger prime = curve.getQ();
    if (x.compareTo(prime) >= 0) {
        return null;
    }
    //
    // Compressed keys require you to know an extra bit of data about the y-coordinate as
    // there are two possibilities.  So it's encoded in the recID.
    //
    ECPoint R = decompressKey(x, (recID & 1) == 1);
    if (!R.multiply(n).isInfinity())
        return null;
    //
    //   For k from 1 to 2 do the following.   (loop is outside this function via iterating recId)
    //     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 eInv = BigInteger.ZERO.subtract(e).mod(n);
    BigInteger rInv = sig.getR().modInverse(n);
    BigInteger srInv = rInv.multiply(sig.getS()).mod(n);
    BigInteger eInvrInv = rInv.multiply(eInv).mod(n);
    ECPoint q = ECAlgorithms.sumOfTwoMultiplies(ecParams.getG(), eInvrInv, R, srInv);
    return new ECKey(q.getEncoded(compressed));
}

From source file:org.ScripterRon.BitcoinCore.ECKey.java

License:Apache License

/**
 * 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
 *//*from   w  w w  . java  2 s .  co  m*/
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;
}

From source file:org.toporin.bitcoincore.ECKey.java

License:Apache License

/**
 * <p>Given the components of a signature and a selector value, recover and return the public key
 * that generated the signature according to the algorithm in SEC1v2 section 4.1.6.</p>
 *
 * <p>The recID is an index from 0 to 3 which indicates which of the 4 possible keys is the correct one.
 * Because the key recovery operation yields multiple potential keys, the correct key must either be
 * stored alongside the signature, or you must be willing to try each recId in turn until you find one
 * that outputs the key you are expecting.</p>
 *
 * <p>If this method returns null, it means recovery was not possible and recID should be iterated.</p>
 *
 * <p>Given the above two points, a correct usage of this method is inside a for loop from 0 to 3, and if the
 * output is null OR a key that is not the one you expect, you try again with the next recID.</p>
 *
 * @param       recID               Which possible key to recover.
 * @param       sig                 R and S components of the signature
 * @param       e                   The double SHA-256 hash of the original message
 * @param       compressed          Whether or not the original public key was compressed
 * @return      An ECKey containing only the public part, or null if recovery wasn't possible
 *//*ww w  .  ja va 2s  .c om*/
protected static ECKey recoverFromSignature(int recID, ECDSASignature sig, BigInteger e, boolean compressed) {
    BigInteger n = ecParams.getN();
    BigInteger i = BigInteger.valueOf((long) recID / 2);
    BigInteger x = sig.getR().add(i.multiply(n));
    //
    //   Convert the integer x to an octet string X of length mlen using the conversion routine
    //        specified in Section 2.3.7, where mlen = (log2 p)/8 or mlen = m/8.
    //   Convert the octet string (16 set binary digits)||X to an elliptic curve point R using the
    //        conversion routine specified in Section 2.3.4. If this conversion routine outputs 'invalid', then
    //        do another iteration.
    //
    // More concisely, what these points mean is to use X as a compressed public key.
    //
    SecP256K1Curve curve = (SecP256K1Curve) ecParams.getCurve();
    BigInteger prime = curve.getQ();
    if (x.compareTo(prime) >= 0) {
        return null;
    }
    //
    // Compressed keys require you to know an extra bit of data about the y-coordinate as
    // there are two possibilities.  So it's encoded in the recID.
    //
    ECPoint R = decompressKey(x, (recID & 1) == 1);
    if (!R.multiply(n).isInfinity())
        return null;
    //
    //   For k from 1 to 2 do the following.   (loop is outside this function via iterating recId)
    //     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 eInv = BigInteger.ZERO.subtract(e).mod(n);
    BigInteger rInv = sig.getR().modInverse(n);
    BigInteger srInv = rInv.multiply(sig.getS()).mod(n);
    BigInteger eInvrInv = rInv.multiply(eInv).mod(n);
    ECPoint q = ECAlgorithms.sumOfTwoMultiplies(ecParams.getG(), eInvrInv, R, srInv);
    return new ECKey(q.getEncoded(compressed));
}