Package org.bouncycastle.crypto.signers

Source Code of org.bouncycastle.crypto.signers.ECDSASigner

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.ECConstants;
import org.bouncycastle.math.ec.ECPoint;

/**
* EC-DSA as described in X9.62
*/
public class ECDSASigner
    implements ECConstants, DSA
{
  ECKeyParameters key;

  SecureRandom    random;

  public void init(
        boolean                 forSigning,
        CipherParameters        param)
  {
        if (forSigning)
        {
            if (param instanceof ParametersWithRandom)
            {
                ParametersWithRandom    rParam = (ParametersWithRandom)param;

                this.random = rParam.getRandom();
                this.key = (ECPrivateKeyParameters)rParam.getParameters();
            }
            else
            {
                this.random = new SecureRandom();
                this.key = (ECPrivateKeyParameters)param;
            }
        }
        else
        {
        this.key = (ECPublicKeyParameters)param;
        }
  }

  // 5.3 pg 28
    /**
     * generate a signature for the given message using the key we were
     * initialised with. For conventional DSA the message should be a SHA-1
     * hash of the message of interest.
     *
     * @param message the message that will be verified later.
     */
  public BigInteger[] generateSignature(
        byte[] message)
  {
    BigInteger e = new BigInteger(1, message);
    BigInteger n = key.getParameters().getN();

    BigInteger r = null;
    BigInteger s = null;

    // 5.3.2
    do // generate s
    {
      BigInteger k = null;
      int      nBitLength = n.bitLength();

      do // generate r
      {
        do
        {
          k = new BigInteger(nBitLength, random);
        }
        while (k.equals(ZERO));

        ECPoint p = key.getParameters().getG().multiply(k);

        // 5.3.3
        BigInteger x = p.getX().toBigInteger();

        r = x.mod(n);
      }
      while ( r.equals(ZERO) );

      BigInteger d = ((ECPrivateKeyParameters)key).getD();

      s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
    }
    while ( s.equals(ZERO) );

        BigInteger[]  res = new BigInteger[2];

        res[0] = r;
        res[1] = s;

        return res;
  }

  // 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).
     */
  public boolean verifySignature(
        byte[]      message,
        BigInteger  r,
        BigInteger  s)
  {
    BigInteger e = new BigInteger(1, message);
    BigInteger n = key.getParameters().getN();

    // 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 = key.getParameters().getG();
    ECPoint Q = ((ECPublicKeyParameters)key).getQ();

    ECPoint point = G.multiply(u1).add(Q.multiply(u2));

    BigInteger v = point.getX().toBigInteger().mod(n);

    return v.equals(r);
  }
}
TOP

Related Classes of org.bouncycastle.crypto.signers.ECDSASigner

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.