All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.crypto.signers.DSTU4145Signer Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for JDK 1.4.

There is a newer version: 1.79
Show newest version
package org.bouncycastle.crypto.signers;

import java.math.BigInteger;
import java.security.SecureRandom;

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DSA;
import org.bouncycastle.crypto.params.ECKeyParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.math.ec.ECAlgorithms;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.Arrays;

/**
 * DSTU 4145-2002
 * 

* National Ukrainian standard of digital signature based on elliptic curves (DSTU 4145-2002). *

*/ public class DSTU4145Signer implements DSA { private static final BigInteger ONE = BigInteger.valueOf(1); private ECKeyParameters key; private SecureRandom random; public void init(boolean forSigning, CipherParameters param) { if (forSigning) { if (param instanceof ParametersWithRandom) { ParametersWithRandom rParam = (ParametersWithRandom)param; this.random = rParam.getRandom(); param = rParam.getParameters(); } else { this.random = new SecureRandom(); } this.key = (ECPrivateKeyParameters)param; } else { this.key = (ECPublicKeyParameters)param; } } public BigInteger[] generateSignature(byte[] message) { ECFieldElement h = hash2FieldElement(key.getParameters().getCurve(), message); if (h.toBigInteger().signum() == 0) { h = key.getParameters().getCurve().fromBigInteger(ONE); } BigInteger e, r, s; ECFieldElement Fe, y; do { do { do { e = generateRandomInteger(key.getParameters().getN(), random); Fe = key.getParameters().getG().multiply(e).getX(); } while (Fe.toBigInteger().signum() == 0); y = h.multiply(Fe); r = fieldElement2Integer(key.getParameters().getN(), y); } while (r.signum() == 0); s = r.multiply(((ECPrivateKeyParameters)key).getD()).add(e).mod(key.getParameters().getN()); } while (s.signum() == 0); return new BigInteger[]{r, s}; } public boolean verifySignature(byte[] message, BigInteger r, BigInteger s) { if (r.signum() == 0 || s.signum() == 0) { return false; } if (r.compareTo(key.getParameters().getN()) >= 0 || s.compareTo(key.getParameters().getN()) >= 0) { return false; } ECFieldElement h = hash2FieldElement(key.getParameters().getCurve(), message); if (h.toBigInteger().signum() == 0) { h = key.getParameters().getCurve().fromBigInteger(ONE); } ECPoint R = ECAlgorithms.sumOfTwoMultiplies(key.getParameters().getG(), s, ((ECPublicKeyParameters)key).getQ(), r); // components must be bogus. if (R.isInfinity()) { return false; } ECFieldElement y = h.multiply(R.getX()); return fieldElement2Integer(key.getParameters().getN(), y).compareTo(r) == 0; } /** * Generates random integer such, than its bit length is less than that of n */ private static BigInteger generateRandomInteger(BigInteger n, SecureRandom random) { return new BigInteger(n.bitLength() - 1, random); } private static void reverseBytes(byte[] bytes) { byte tmp; for (int i=0; i= curve.getFieldSize()) { num = num.clearBit(num.bitLength() - 1); } return curve.fromBigInteger(num); } private static BigInteger fieldElement2Integer(BigInteger n, ECFieldElement fieldElement) { BigInteger num = fieldElement.toBigInteger(); while (num.bitLength() >= n.bitLength()) { num = num.clearBit(num.bitLength() - 1); } return num; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy