Search in sources :

Example 11 with ECPoint

use of org.spongycastle.math.ec.ECPoint in project AppCoins-ethereumj by AppStoreFoundation.

the class ECKey method recoverPubBytesFromSignature.

/**
 * <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 the R and S components of the signature, wrapped.
 * @param messageHash Hash of the data that was signed.
 * @return 65-byte encoded public key
 */
@Nullable
public static byte[] recoverPubBytesFromSignature(int recId, ECDSASignature sig, byte[] messageHash) {
    check(recId >= 0, "recId must be positive");
    check(sig.r.signum() >= 0, "r must be positive");
    check(sig.s.signum() >= 0, "s must be positive");
    check(messageHash != null, "messageHash must not be null");
    // 1.0 For j from 0 to h   (h == recId here and the loop is outside this function)
    // 1.1 Let x = r + jn
    // Curve order.
    BigInteger n = CURVE.getN();
    BigInteger i = BigInteger.valueOf((long) recId / 2);
    BigInteger x = sig.r.add(i.multiply(n));
    // 1.2. 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⌉.
    // 1.3. 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 of Step 1.
    // 
    // More concisely, what these points mean is to use X as a compressed public key.
    ECCurve.Fp curve = (ECCurve.Fp) CURVE.getCurve();
    BigInteger prime = // Bouncy Castle is not consistent about the letter it uses for the prime.
    curve.getQ();
    if (x.compareTo(prime) >= 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);
    // 1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility).
    if (!R.multiply(n).isInfinity()) {
        return null;
    }
    // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification.
    BigInteger e = new BigInteger(1, messageHash);
    // 1.6. For k from 1 to 2 do the following.   (loop is outside this function via iterating recId)
    // 1.6.1. 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.r.modInverse(n);
    BigInteger srInv = rInv.multiply(sig.s).mod(n);
    BigInteger eInvrInv = rInv.multiply(eInv).mod(n);
    Fp q = (Fp) ECAlgorithms.sumOfTwoMultiplies(CURVE.getG(), eInvrInv, R, srInv);
    return q.getEncoded(/* compressed */
    false);
}
Also used : ECCurve(org.spongycastle.math.ec.ECCurve) BigInteger(java.math.BigInteger) Fp(org.spongycastle.math.ec.ECPoint.Fp) ECPoint(org.spongycastle.math.ec.ECPoint) Nullable(android.support.annotation.Nullable)

Example 12 with ECPoint

use of org.spongycastle.math.ec.ECPoint in project toshi-android-client by toshiapp.

the class ECKey method recoverPubBytesFromSignature.

/**
 * <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 the R and S components of the signature, wrapped.
 * @param messageHash Hash of the data that was signed.
 * @return 65-byte encoded public key
 */
@Nullable
public static byte[] recoverPubBytesFromSignature(int recId, ECDSASignature sig, byte[] messageHash) {
    check(recId >= 0, "recId must be positive");
    check(sig.r.signum() >= 0, "r must be positive");
    check(sig.s.signum() >= 0, "s must be positive");
    check(messageHash != null, "messageHash must not be null");
    // 1.0 For j from 0 to h   (h == recId here and the loop is outside this function)
    // 1.1 Let x = r + jn
    // Curve order.
    BigInteger n = CURVE.getN();
    BigInteger i = BigInteger.valueOf((long) recId / 2);
    BigInteger x = sig.r.add(i.multiply(n));
    // 1.2. 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⌉.
    // 1.3. 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 of Step 1.
    // 
    // More concisely, what these points mean is to use X as a compressed public key.
    ECCurve.Fp curve = (ECCurve.Fp) CURVE.getCurve();
    // Bouncy Castle is not consistent about the letter it uses for the prime.
    BigInteger prime = curve.getQ();
    if (x.compareTo(prime) >= 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);
    // 1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility).
    if (!R.multiply(n).isInfinity())
        return null;
    // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification.
    BigInteger e = new BigInteger(1, messageHash);
    // 1.6. For k from 1 to 2 do the following.   (loop is outside this function via iterating recId)
    // 1.6.1. 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.r.modInverse(n);
    BigInteger srInv = rInv.multiply(sig.s).mod(n);
    BigInteger eInvrInv = rInv.multiply(eInv).mod(n);
    ECPoint.Fp q = (ECPoint.Fp) ECAlgorithms.sumOfTwoMultiplies(CURVE.getG(), eInvrInv, R, srInv);
    return q.getEncoded(/* compressed */
    false);
}
Also used : ECCurve(org.spongycastle.math.ec.ECCurve) BigInteger(java.math.BigInteger) ECPoint(org.spongycastle.math.ec.ECPoint) Nullable(android.support.annotation.Nullable)

Example 13 with ECPoint

use of org.spongycastle.math.ec.ECPoint in project aion by aionnetwork.

the class ECKeySecp256k1 method recoverPubBytesFromSignature.

/**
 * <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
 *            the R and S components of the signature, wrapped.
 * @param messageHash
 *            Hash of the data that was signed.
 * @return 65-byte encoded public key
 */
public byte[] recoverPubBytesFromSignature(int recId, ECDSASignature sig, byte[] messageHash) {
    check(recId >= 0, "recId must be positive");
    check(sig.r.signum() >= 0, "r must be positive");
    check(sig.s.signum() >= 0, "s must be positive");
    check(messageHash != null, "messageHash must not be null");
    // 1.0 For j from 0 to h (h == recId here and the loop is outside this
    // function)
    // 1.1 Let x = r + jn
    // Curve order.
    BigInteger n = CURVE.getN();
    BigInteger i = BigInteger.valueOf((long) recId / 2);
    BigInteger x = sig.r.add(i.multiply(n));
    // 1.2. 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⌉.
    // 1.3. 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 of Step 1.
    // 
    // More concisely, what these points mean is to use X as a compressed
    // public key.
    ECCurve.Fp curve = (ECCurve.Fp) CURVE.getCurve();
    // Bouncy Castle is not consistent
    BigInteger prime = curve.getQ();
    // prime.
    if (x.compareTo(prime) >= 0) {
        // 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);
    // (callers responsibility).
    if (!R.multiply(n).isInfinity()) {
        return null;
    }
    // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature
    // verification.
    BigInteger e = new BigInteger(1, messageHash);
    // 1.6. For k from 1 to 2 do the following. (loop is outside this
    // function via iterating recId)
    // 1.6.1. 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.r.modInverse(n);
    BigInteger srInv = rInv.multiply(sig.s).mod(n);
    BigInteger eInvrInv = rInv.multiply(eInv).mod(n);
    ECPoint.Fp q = (ECPoint.Fp) ECAlgorithms.sumOfTwoMultiplies(CURVE.getG(), eInvrInv, R, srInv);
    return q.getEncoded(/* compressed */
    false);
}
Also used : ECCurve(org.spongycastle.math.ec.ECCurve) BigInteger(java.math.BigInteger) ECPoint(org.spongycastle.math.ec.ECPoint)

Example 14 with ECPoint

use of org.spongycastle.math.ec.ECPoint in project SmartMesh_Android by SmartMeshFoundation.

the class Sign2 method publicKeyFromPrivate.

/**
 * Returns public key from the given private key.
 *
 * @param privKey the private key to derive the public key from
 * @return BigInteger encoded public key
 */
public static BigInteger publicKeyFromPrivate(BigInteger privKey) {
    ECPoint point = publicPointFromPrivate(privKey);
    byte[] encoded = point.getEncoded(false);
    // remove prefix
    return new BigInteger(1, Arrays.copyOfRange(encoded, 1, encoded.length));
}
Also used : BigInteger(java.math.BigInteger) ECPoint(org.spongycastle.math.ec.ECPoint)

Example 15 with ECPoint

use of org.spongycastle.math.ec.ECPoint in project rskj by rsksmart.

the class ECIESCoder method encrypt.

public static byte[] encrypt(ECPoint toPub, byte[] plaintext, byte[] macData) {
    ECKeyPairGenerator eGen = new ECKeyPairGenerator();
    SecureRandom random = new SecureRandom();
    KeyGenerationParameters gParam = new ECKeyGenerationParameters(CURVE, random);
    eGen.init(gParam);
    byte[] iv = new byte[KEY_SIZE / 8];
    new SecureRandom().nextBytes(iv);
    AsymmetricCipherKeyPair ephemPair = eGen.generateKeyPair();
    BigInteger prv = ((ECPrivateKeyParameters) ephemPair.getPrivate()).getD();
    ECPoint pub = ((ECPublicKeyParameters) ephemPair.getPublic()).getQ();
    EthereumIESEngine iesEngine = makeIESEngine(true, toPub, prv, iv);
    ECKeyGenerationParameters keygenParams = new ECKeyGenerationParameters(CURVE, random);
    ECKeyPairGenerator generator = new ECKeyPairGenerator();
    generator.init(keygenParams);
    ECKeyPairGenerator gen = new ECKeyPairGenerator();
    gen.init(new ECKeyGenerationParameters(ECKey.CURVE, random));
    byte[] cipher;
    try {
        cipher = iesEngine.processBlock(plaintext, 0, plaintext.length, macData);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bos.write(pub.getEncoded(false));
        bos.write(iv);
        bos.write(cipher);
        return bos.toByteArray();
    } catch (InvalidCipherTextException e) {
        throw Throwables.propagate(e);
    } catch (IOException e) {
        throw Throwables.propagate(e);
    }
}
Also used : ECKeyPairGenerator(org.spongycastle.crypto.generators.ECKeyPairGenerator) InvalidCipherTextException(org.spongycastle.crypto.InvalidCipherTextException) SecureRandom(java.security.SecureRandom) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ECPoint(org.spongycastle.math.ec.ECPoint) KeyGenerationParameters(org.spongycastle.crypto.KeyGenerationParameters) AsymmetricCipherKeyPair(org.spongycastle.crypto.AsymmetricCipherKeyPair) BigInteger(java.math.BigInteger)

Aggregations

ECPoint (org.spongycastle.math.ec.ECPoint)18 BigInteger (java.math.BigInteger)12 ECCurve (org.spongycastle.math.ec.ECCurve)5 Test (org.junit.Test)3 Nullable (android.support.annotation.Nullable)2 ByteBuf (io.netty.buffer.ByteBuf)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 IOException (java.io.IOException)2 SecureRandom (java.security.SecureRandom)2 Nullable (javax.annotation.Nullable)2 InvalidCipherTextException (org.spongycastle.crypto.InvalidCipherTextException)2 ECKeyPairGenerator (org.spongycastle.crypto.generators.ECKeyPairGenerator)2 Fp (org.spongycastle.math.ec.ECCurve.Fp)2 CommandApdu (es.gob.jmulticard.apdu.CommandApdu)1 ResponseApdu (es.gob.jmulticard.apdu.ResponseApdu)1 ApduConnectionException (es.gob.jmulticard.apdu.connection.ApduConnectionException)1 GeneralAuthenticateApduCommand (es.gob.jmulticard.apdu.iso7816four.GeneralAuthenticateApduCommand)1 MseSetPaceAlgorithmApduCommand (es.gob.jmulticard.apdu.iso7816four.pace.MseSetPaceAlgorithmApduCommand)1 Tlv (es.gob.jmulticard.asn1.Tlv)1