/** * @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; } }
/** * Alternate to verifySignature() using java.security libraries. * * @throws GeneralSecurityException if algorithm unvailable or on other errors * @since 0.8.7 */ private boolean altVerifySigSHA1(Signature signature, byte[] data, SigningPublicKey verifyingKey) throws GeneralSecurityException { java.security.Signature jsig = java.security.Signature.getInstance("SHA1withDSA"); KeyFactory keyFact = KeyFactory.getInstance("DSA"); // y p q g KeySpec spec = new DSAPublicKeySpec( new NativeBigInteger(1, verifyingKey.getData()), CryptoConstants.dsap, CryptoConstants.dsaq, CryptoConstants.dsag); PublicKey pubKey = keyFact.generatePublic(spec); jsig.initVerify(pubKey); jsig.update(data); boolean rv = jsig.verify(sigBytesToASN1(signature.getData())); // if (!rv) { // System.out.println("BAD SIG\n" + net.i2p.util.HexDump.dump(signature.getData())); // System.out.println("BAD SIG\n" + // net.i2p.util.HexDump.dump(sigBytesToASN1(signature.getData()))); // } return rv; }