List of usage examples for org.bouncycastle.math.ec ECAlgorithms sumOfTwoMultiplies
public static ECPoint sumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b)
From source file:com.google.bitcoin.core.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>//from ww w . ja va2 s . com * * <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 message Hash of the data that was signed. * @param compressed Whether or not the original pubkey was compressed. * @return An ECKey containing only the public part, or null if recovery wasn't possible. */ @Nullable public static ECKey recoverFromSignature(int recId, ECDSASignature sig, Sha256Hash message, boolean compressed) { Preconditions.checkArgument(recId >= 0, "recId must be positive"); Preconditions.checkArgument(sig.r.compareTo(BigInteger.ZERO) >= 0, "r must be positive"); Preconditions.checkArgument(sig.s.compareTo(BigInteger.ZERO) >= 0, "s must be positive"); Preconditions.checkNotNull(message); // 1.0 For j from 0 to h (h == recId here and the loop is outside this function) // 1.1 Let x = r + jn BigInteger n = CURVE.getN(); // Curve order. 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 = curve.getQ(); // Bouncy Castle is not consistent about the letter it uses for the prime. 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 = message.toBigInteger(); // 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); if (compressed) { // We have to manually recompress the point as the compressed-ness gets lost when multiply() is used. q = new ECPoint.Fp(curve, q.getX(), q.getY(), true); } return new ECKey((byte[]) null, q.getEncoded()); }
From source file:org.ethereum.crypto.ECKey.java
License:Open Source 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>/* w ww . j ava2 s .c o m*/ * * <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. * @param compressed Whether or not the original pubkey was compressed. * @return An ECKey containing only the public part, or null if recovery wasn't possible. */ @Nullable public static ECKey recoverFromSignature(int recId, ECDSASignature sig, byte[] messageHash, boolean compressed) { 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 BigInteger n = CURVE.getN(); // Curve order. 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 = curve.getQ(); // Bouncy Castle is not consistent about the letter it uses for the prime. 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 ECKey.fromPublicOnly(q.getEncoded(compressed)); }
From source file:org.kframework.backend.java.builtins.crypto.ECDSARecover.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>//from w ww. j a v a 2 s. c o m * * <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. * @param compressed Whether or not the original pubkey was compressed. * @return An ECKey containing only the public part, or null if recovery wasn't possible. */ @Nullable public static ECDSARecover recoverFromSignature(int recId, ECDSASignature sig, byte[] messageHash, boolean compressed) { 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 BigInteger n = CURVE.getN(); // Curve order. 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 = curve.getQ(); // Bouncy Castle is not consistent about the letter it uses for the prime. 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 ECDSARecover.fromPublicOnly(q.getEncoded(compressed)); }
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 www . j a v a 2 s . c o m 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.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 *///from ww w.j av a 2s . c o m 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)); }