예제 #1
0
파일: DSAEngine.java 프로젝트: hfeeki/I2P
  /**
   * @param hash either a Hash or a SHA1Hash
   * @since 0.8.3
   */
  private boolean verifySig(
      Signature signature, SimpleDataStructure hash, SigningPublicKey verifyingKey) {
    long start = _context.clock().now();

    try {
      byte[] sigbytes = signature.getData();
      byte rbytes[] = new byte[20];
      byte sbytes[] = new byte[20];
      // System.arraycopy(sigbytes, 0, rbytes, 0, 20);
      // System.arraycopy(sigbytes, 20, sbytes, 0, 20);
      for (int x = 0; x < 40; x++) {
        if (x < 20) {
          rbytes[x] = sigbytes[x];
        } else {
          sbytes[x - 20] = sigbytes[x];
        }
      }

      BigInteger s = new NativeBigInteger(1, sbytes);
      BigInteger r = new NativeBigInteger(1, rbytes);
      BigInteger y = new NativeBigInteger(1, verifyingKey.getData());
      BigInteger w = null;
      try {
        w = s.modInverse(CryptoConstants.dsaq);
      } catch (ArithmeticException ae) {
        _log.warn("modInverse() error", ae);
        return false;
      }
      byte data[] = hash.getData();
      NativeBigInteger bi = new NativeBigInteger(1, data);
      BigInteger u1 = bi.multiply(w).mod(CryptoConstants.dsaq);
      BigInteger u2 = r.multiply(w).mod(CryptoConstants.dsaq);
      BigInteger modval = CryptoConstants.dsag.modPow(u1, CryptoConstants.dsap);
      BigInteger modmulval = modval.multiply(y.modPow(u2, CryptoConstants.dsap));
      BigInteger v = (modmulval).mod(CryptoConstants.dsap).mod(CryptoConstants.dsaq);

      boolean ok = v.compareTo(r) == 0;

      long diff = _context.clock().now() - start;
      if (diff > 1000) {
        if (_log.shouldLog(Log.WARN))
          _log.warn("Took too long to verify the signature (" + diff + "ms)");
      }
      return ok;
    } catch (Exception e) {
      _log.log(Log.CRIT, "Error verifying the signature", e);
      return false;
    }
  }
예제 #2
0
파일: DSAEngine.java 프로젝트: hfeeki/I2P
  /**
   * @param hash either a Hash or a SHA1Hash
   * @since 0.8.3
   */
  private Signature signIt(SimpleDataStructure hash, SigningPrivateKey signingKey) {
    if ((signingKey == null) || (hash == null)) return null;
    long start = _context.clock().now();

    Signature sig = new Signature();
    BigInteger k;

    boolean ok = false;
    do {
      k = new BigInteger(160, _context.random());
      ok = k.compareTo(CryptoConstants.dsaq) != 1;
      ok = ok && !k.equals(BigInteger.ZERO);
      // System.out.println("K picked (ok? " + ok + "): " + k.bitLength() + ": " + k.toString());
    } while (!ok);

    BigInteger r = CryptoConstants.dsag.modPow(k, CryptoConstants.dsap).mod(CryptoConstants.dsaq);
    BigInteger kinv = k.modInverse(CryptoConstants.dsaq);

    BigInteger M = new NativeBigInteger(1, hash.getData());
    BigInteger x = new NativeBigInteger(1, signingKey.getData());
    BigInteger s = (kinv.multiply(M.add(x.multiply(r)))).mod(CryptoConstants.dsaq);

    byte[] rbytes = r.toByteArray();
    byte[] sbytes = s.toByteArray();
    byte[] out = new byte[40];

    // (q^random)%p is computationally random
    _context.random().harvester().feedEntropy("DSA.sign", rbytes, 0, rbytes.length);

    if (rbytes.length == 20) {
      // System.arraycopy(rbytes, 0, out, 0, 20);
      for (int i = 0; i < 20; i++) {
        out[i] = rbytes[i];
      }
    } else if (rbytes.length == 21) {
      // System.arraycopy(rbytes, 1, out, 0, 20);
      for (int i = 0; i < 20; i++) {
        out[i] = rbytes[i + 1];
      }
    } else {
      if (_log.shouldLog(Log.DEBUG))
        _log.debug("Using short rbytes.length [" + rbytes.length + "]");
      // System.arraycopy(rbytes, 0, out, 20 - rbytes.length, rbytes.length);
      for (int i = 0; i < rbytes.length; i++) out[i + 20 - rbytes.length] = rbytes[i];
    }
    if (sbytes.length == 20) {
      // System.arraycopy(sbytes, 0, out, 20, 20);
      for (int i = 0; i < 20; i++) {
        out[i + 20] = sbytes[i];
      }
    } else if (sbytes.length == 21) {
      // System.arraycopy(sbytes, 1, out, 20, 20);
      for (int i = 0; i < 20; i++) {
        out[i + 20] = sbytes[i + 1];
      }
    } else {
      if (_log.shouldLog(Log.DEBUG))
        _log.debug("Using short sbytes.length [" + sbytes.length + "]");
      // System.arraycopy(sbytes, 0, out, 40 - sbytes.length, sbytes.length);
      for (int i = 0; i < sbytes.length; i++) out[i + 20 + 20 - sbytes.length] = sbytes[i];
    }
    sig.setData(out);

    long diff = _context.clock().now() - start;
    if (diff > 1000) {
      if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to sign (" + diff + "ms)");
    }

    return sig;
  }