Search in sources :

Example 6 with ECDomainParameters

use of org.bouncycastle.crypto.params.ECDomainParameters in project web3sdk by FISCO-BCOS.

the class ECDSASigner method generateSignature2.

/**
 * The same generateSignature with the temporary variable ECPoint P generated by the signature
 * process is also returned together
 *
 * @param message the message that will be verified later.
 */
public Object[] generateSignature2(byte[] message) {
    ECDomainParameters ec = key.getParameters();
    BigInteger n = ec.getN();
    BigInteger e = calculateE(n, message);
    BigInteger d = ((ECPrivateKeyParameters) key).getD();
    if (kCalculator.isDeterministic()) {
        kCalculator.init(n, d, message);
    } else {
        kCalculator.init(n, random);
    }
    BigInteger r, s;
    /**
     */
    ECPoint p;
    ECMultiplier basePointMultiplier = createBasePointMultiplier();
    // 5.3.2
    do // generate s
    {
        BigInteger k;
        do // generate r
        {
            k = kCalculator.nextK();
            p = basePointMultiplier.multiply(ec.getG(), k).normalize();
            // 5.3.3
            r = p.getAffineXCoord().toBigInteger().mod(n);
        } while (r.equals(ZERO));
        s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
    } while (s.equals(ZERO));
    return new Object[] { r, s, p };
}
Also used : ECPrivateKeyParameters(org.bouncycastle.crypto.params.ECPrivateKeyParameters) ECDomainParameters(org.bouncycastle.crypto.params.ECDomainParameters) BigInteger(java.math.BigInteger) ECMultiplier(org.bouncycastle.math.ec.ECMultiplier) ECPoint(org.bouncycastle.math.ec.ECPoint)

Example 7 with ECDomainParameters

use of org.bouncycastle.crypto.params.ECDomainParameters in project web3sdk by FISCO-BCOS.

the class ECDSASigner method verifySignature.

// 5.4 pg 29
/**
 * return true if the value r and s represent a DSA signature for the passed in message (for
 * standard DSA the message should be a SHA-1 hash of the real message to be verified).
 */
@Override
public boolean verifySignature(byte[] message, BigInteger r, BigInteger s) {
    ECDomainParameters ec = key.getParameters();
    BigInteger n = ec.getN();
    BigInteger e = calculateE(n, message);
    // r in the range [1,n-1]
    if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0) {
        return false;
    }
    // s in the range [1,n-1]
    if (s.compareTo(ONE) < 0 || s.compareTo(n) >= 0) {
        return false;
    }
    BigInteger c = s.modInverse(n);
    BigInteger u1 = e.multiply(c).mod(n);
    BigInteger u2 = r.multiply(c).mod(n);
    ECPoint G = ec.getG();
    ECPoint Q = ((ECPublicKeyParameters) key).getQ();
    ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, u1, Q, u2);
    // components must be bogus.
    if (point.isInfinity()) {
        return false;
    }
    /*
         * If possible, avoid normalizing the point (to save a modular inversion in the curve field).
         *
         * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'.
         * If the cofactor is known and small, we generate those possible field values and project each
         * of them to the same "denominator" (depending on the particular projective coordinates in use)
         * as the calculated point.X. If any of the projected values matches point.X, then we have:
         *     (point.X / Denominator mod p) mod n == r
         * as required, and verification succeeds.
         *
         * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in
         * the libsecp256k1 project (https://github.com/bitcoin/secp256k1).
         */
    ECCurve curve = point.getCurve();
    if (curve != null) {
        BigInteger cofactor = curve.getCofactor();
        if (cofactor != null && cofactor.compareTo(EIGHT) <= 0) {
            ECFieldElement D = getDenominator(curve.getCoordinateSystem(), point);
            if (D != null && !D.isZero()) {
                ECFieldElement X = point.getXCoord();
                while (curve.isValidFieldElement(r)) {
                    ECFieldElement R = curve.fromBigInteger(r).multiply(D);
                    if (R.equals(X)) {
                        return true;
                    }
                    r = r.add(n);
                }
                return false;
            }
        }
    }
    BigInteger v = point.normalize().getAffineXCoord().toBigInteger().mod(n);
    return v.equals(r);
}
Also used : ECDomainParameters(org.bouncycastle.crypto.params.ECDomainParameters) ECCurve(org.bouncycastle.math.ec.ECCurve) BigInteger(java.math.BigInteger) ECPoint(org.bouncycastle.math.ec.ECPoint) ECFieldElement(org.bouncycastle.math.ec.ECFieldElement) ECPublicKeyParameters(org.bouncycastle.crypto.params.ECPublicKeyParameters)

Example 8 with ECDomainParameters

use of org.bouncycastle.crypto.params.ECDomainParameters in project web3sdk by FISCO-BCOS.

the class ECCEncrypt method createBCECPublicKey.

/**
 * 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;
}
Also used : ECDomainParameters(org.bouncycastle.crypto.params.ECDomainParameters) SecP256K1Point(org.bouncycastle.math.ec.custom.sec.SecP256K1Point) BCECPublicKey(org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey) BigInteger(java.math.BigInteger) SecP256K1Curve(org.bouncycastle.math.ec.custom.sec.SecP256K1Curve) ECPublicKeyParameters(org.bouncycastle.crypto.params.ECPublicKeyParameters)

Example 9 with ECDomainParameters

use of org.bouncycastle.crypto.params.ECDomainParameters in project rskj by rsksmart.

the class BridgeSupportTest method addSignatureFromValidFederator.

/**
 * Helper method to test addSignature() with a valid federatorPublicKey parameter and both valid/invalid signatures
 *
 * @param privateKeysToSignWith keys used to sign the tx. Federator key when we want to produce a valid signature, a random key when we want to produce an invalid signature
 * @param numberOfInputsToSign  There is just 1 input. 1 when testing the happy case, other values to test attacks/bugs.
 * @param signatureCanonical    Signature should be canonical. true when testing the happy case, false to test attacks/bugs.
 * @param signTwice             Sign again with the same key
 * @param expectedResult        "InvalidParameters", "PartiallySigned" or "FullySigned"
 */
private void addSignatureFromValidFederator(List<BtcECKey> privateKeysToSignWith, int numberOfInputsToSign, boolean signatureCanonical, boolean signTwice, String expectedResult) throws Exception {
    // Federation is the genesis federation ATM
    Federation federation = bridgeConstants.getGenesisFederation();
    Repository repository = createRepository();
    final Keccak256 keccak256 = PegTestUtils.createHash3();
    Repository track = repository.startTracking();
    BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants, activationsBeforeForks);
    BtcTransaction prevTx = new BtcTransaction(btcParams);
    TransactionOutput prevOut = new TransactionOutput(btcParams, prevTx, Coin.FIFTY_COINS, federation.getAddress());
    prevTx.addOutput(prevOut);
    BtcTransaction t = new BtcTransaction(btcParams);
    TransactionOutput output = new TransactionOutput(btcParams, t, Coin.COIN, new BtcECKey().toAddress(btcParams));
    t.addOutput(output);
    t.addInput(prevOut).setScriptSig(createBaseInputScriptThatSpendsFromTheFederation(federation));
    provider.getRskTxsWaitingForSignatures().put(keccak256, t);
    provider.save();
    track.commit();
    track = repository.startTracking();
    ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class);
    List<LogInfo> logs = new ArrayList<>();
    BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeConstants, activations, logs);
    BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, new BridgeStorageProvider(track, contractAddress, bridgeConstants, activationsAfterForks), track, eventLogger, mock(Block.class), null);
    Script inputScript = t.getInputs().get(0).getScriptSig();
    List<ScriptChunk> chunks = inputScript.getChunks();
    byte[] program = chunks.get(chunks.size() - 1).data;
    Script redeemScript = new Script(program);
    Sha256Hash sighash = t.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false);
    BtcECKey.ECDSASignature sig = privateKeysToSignWith.get(0).sign(sighash);
    if (!signatureCanonical) {
        sig = new BtcECKey.ECDSASignature(sig.r, BtcECKey.CURVE.getN().subtract(sig.s));
    }
    byte[] derEncodedSig = sig.encodeToDER();
    List derEncodedSigs = new ArrayList();
    for (int i = 0; i < numberOfInputsToSign; i++) {
        derEncodedSigs.add(derEncodedSig);
    }
    bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeysToSignWith.get(0)), derEncodedSigs, keccak256.getBytes());
    if (signTwice) {
        // Create another valid signature with the same private key
        ECDSASigner signer = new ECDSASigner();
        X9ECParameters CURVE_PARAMS = CustomNamedCurves.getByName("secp256k1");
        ECDomainParameters CURVE = new ECDomainParameters(CURVE_PARAMS.getCurve(), CURVE_PARAMS.getG(), CURVE_PARAMS.getN(), CURVE_PARAMS.getH());
        ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(privateKeysToSignWith.get(0).getPrivKey(), CURVE);
        signer.init(true, privKey);
        BigInteger[] components = signer.generateSignature(sighash.getBytes());
        BtcECKey.ECDSASignature sig2 = new BtcECKey.ECDSASignature(components[0], components[1]).toCanonicalised();
        bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeysToSignWith.get(0)), Lists.newArrayList(sig2.encodeToDER()), keccak256.getBytes());
    }
    if (privateKeysToSignWith.size() > 1) {
        BtcECKey.ECDSASignature sig2 = privateKeysToSignWith.get(1).sign(sighash);
        byte[] derEncodedSig2 = sig2.encodeToDER();
        List derEncodedSigs2 = new ArrayList();
        for (int i = 0; i < numberOfInputsToSign; i++) {
            derEncodedSigs2.add(derEncodedSig2);
        }
        bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeysToSignWith.get(1)), derEncodedSigs2, keccak256.getBytes());
    }
    bridgeSupport.save();
    track.commit();
    provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants, activationsBeforeForks);
    if ("FullySigned".equals(expectedResult)) {
        Assert.assertTrue(provider.getRskTxsWaitingForSignatures().isEmpty());
        Assert.assertThat(logs, is(not(empty())));
        Assert.assertThat(logs, hasSize(3));
        LogInfo releaseTxEvent = logs.get(2);
        Assert.assertThat(releaseTxEvent.getTopics(), hasSize(1));
        Assert.assertThat(releaseTxEvent.getTopics(), hasItem(Bridge.RELEASE_BTC_TOPIC));
        BtcTransaction releaseTx = new BtcTransaction(btcParams, ((RLPList) RLP.decode2(releaseTxEvent.getData()).get(0)).get(1).getRLPData());
        Script retrievedScriptSig = releaseTx.getInput(0).getScriptSig();
        Assert.assertEquals(4, retrievedScriptSig.getChunks().size());
        Assert.assertEquals(true, retrievedScriptSig.getChunks().get(1).data.length > 0);
        Assert.assertEquals(true, retrievedScriptSig.getChunks().get(2).data.length > 0);
    } else {
        Script retrievedScriptSig = provider.getRskTxsWaitingForSignatures().get(keccak256).getInput(0).getScriptSig();
        Assert.assertEquals(4, retrievedScriptSig.getChunks().size());
        // for "InvalidParameters"
        boolean expectSignatureToBePersisted = false;
        if ("PartiallySigned".equals(expectedResult)) {
            expectSignatureToBePersisted = true;
        }
        Assert.assertEquals(expectSignatureToBePersisted, retrievedScriptSig.getChunks().get(1).data.length > 0);
        Assert.assertEquals(false, retrievedScriptSig.getChunks().get(2).data.length > 0);
    }
}
Also used : ECDomainParameters(org.bouncycastle.crypto.params.ECDomainParameters) X9ECParameters(org.bouncycastle.asn1.x9.X9ECParameters) PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(co.rsk.peg.PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation) PegTestUtils.createBaseRedeemScriptThatSpendsFromTheFederation(co.rsk.peg.PegTestUtils.createBaseRedeemScriptThatSpendsFromTheFederation) RLPList(org.ethereum.util.RLPList) Script(co.rsk.bitcoinj.script.Script) LogInfo(org.ethereum.vm.LogInfo) ECDSASigner(org.bouncycastle.crypto.signers.ECDSASigner) Keccak256(co.rsk.crypto.Keccak256) ScriptChunk(co.rsk.bitcoinj.script.ScriptChunk) RLPList(org.ethereum.util.RLPList) ActivationConfig(org.ethereum.config.blockchain.upgrades.ActivationConfig) ECPrivateKeyParameters(org.bouncycastle.crypto.params.ECPrivateKeyParameters) Repository(org.ethereum.core.Repository) MutableRepository(org.ethereum.db.MutableRepository) Block(org.ethereum.core.Block) BigInteger(java.math.BigInteger)

Example 10 with ECDomainParameters

use of org.bouncycastle.crypto.params.ECDomainParameters in project hutool by looly.

the class ECKeyUtil method getPublicParams.

/**
 * 根据私钥参数获取公钥参数
 *
 * @param privateKeyParameters 私钥参数
 * @return 公钥参数
 * @since 5.5.9
 */
public static ECPublicKeyParameters getPublicParams(ECPrivateKeyParameters privateKeyParameters) {
    final ECDomainParameters domainParameters = privateKeyParameters.getParameters();
    final ECPoint q = new FixedPointCombMultiplier().multiply(domainParameters.getG(), privateKeyParameters.getD());
    return new ECPublicKeyParameters(q, domainParameters);
}
Also used : FixedPointCombMultiplier(org.bouncycastle.math.ec.FixedPointCombMultiplier) ECDomainParameters(org.bouncycastle.crypto.params.ECDomainParameters) ECPoint(org.bouncycastle.math.ec.ECPoint) ECPublicKeyParameters(org.bouncycastle.crypto.params.ECPublicKeyParameters)

Aggregations

ECDomainParameters (org.bouncycastle.crypto.params.ECDomainParameters)17 BigInteger (java.math.BigInteger)11 ECPrivateKeyParameters (org.bouncycastle.crypto.params.ECPrivateKeyParameters)8 ECPublicKeyParameters (org.bouncycastle.crypto.params.ECPublicKeyParameters)8 X9ECParameters (org.bouncycastle.asn1.x9.X9ECParameters)7 DSAParameters (org.bouncycastle.crypto.params.DSAParameters)5 ECParameterSpec (org.bouncycastle.jce.spec.ECParameterSpec)5 InvalidKeyException (java.security.InvalidKeyException)4 DHParameter (org.bouncycastle.asn1.pkcs.DHParameter)4 AlgorithmIdentifier (org.bouncycastle.asn1.x509.AlgorithmIdentifier)4 DSAParameter (org.bouncycastle.asn1.x509.DSAParameter)4 X962Parameters (org.bouncycastle.asn1.x9.X962Parameters)4 DHParameters (org.bouncycastle.crypto.params.DHParameters)4 ECPoint (org.bouncycastle.math.ec.ECPoint)4 ASN1Integer (org.bouncycastle.asn1.ASN1Integer)3 DSAPublicKeyParameters (org.bouncycastle.crypto.params.DSAPublicKeyParameters)3 RSAKeyParameters (org.bouncycastle.crypto.params.RSAKeyParameters)3 ASN1Encodable (org.bouncycastle.asn1.ASN1Encodable)2 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)2 ASN1OctetString (org.bouncycastle.asn1.ASN1OctetString)2