use of net.i2p.util.NativeBigInteger in project i2p.i2p by i2p.
the class KeyGenerator method getPublicKey.
/**
* Convert a PrivateKey to its corresponding PublicKey
* @param priv PrivateKey object
* @return the corresponding PublicKey object
* @throws IllegalArgumentException on bad key
*/
public static PublicKey getPublicKey(PrivateKey priv) {
BigInteger a = new NativeBigInteger(1, priv.toByteArray());
BigInteger aalpha = CryptoConstants.elgg.modPow(a, CryptoConstants.elgp);
PublicKey pub = new PublicKey();
try {
pub.setData(SigUtil.rectify(aalpha, PublicKey.KEYSIZE_BYTES));
} catch (InvalidKeyException ike) {
throw new IllegalArgumentException(ike);
}
return pub;
}
use of net.i2p.util.NativeBigInteger in project i2p.i2p by i2p.
the class KeyGenerator method getSigningPublicKey.
/**
* Convert a SigningPrivateKey to a SigningPublicKey.
* As of 0.9.16, supports all key types.
*
* @param priv a SigningPrivateKey object
* @return a SigningPublicKey object
* @throws IllegalArgumentException on bad key or unknown type
*/
public static SigningPublicKey getSigningPublicKey(SigningPrivateKey priv) {
SigType type = priv.getType();
if (type == null)
throw new IllegalArgumentException("Unknown type");
try {
switch(type.getBaseAlgorithm()) {
case DSA:
BigInteger x = new NativeBigInteger(1, priv.toByteArray());
BigInteger y = CryptoConstants.dsag.modPow(x, CryptoConstants.dsap);
SigningPublicKey pub = new SigningPublicKey();
pub.setData(SigUtil.rectify(y, SigningPublicKey.KEYSIZE_BYTES));
return pub;
case EC:
ECPrivateKey ecpriv = SigUtil.toJavaECKey(priv);
BigInteger s = ecpriv.getS();
ECParameterSpec spec = (ECParameterSpec) type.getParams();
EllipticCurve curve = spec.getCurve();
ECPoint g = spec.getGenerator();
ECPoint w = ECUtil.scalarMult(g, s, curve);
ECPublicKeySpec ecks = new ECPublicKeySpec(w, ecpriv.getParams());
KeyFactory eckf = KeyFactory.getInstance("EC");
ECPublicKey ecpub = (ECPublicKey) eckf.generatePublic(ecks);
return SigUtil.fromJavaKey(ecpub, type);
case RSA:
RSAPrivateKey rsapriv = SigUtil.toJavaRSAKey(priv);
BigInteger exp = ((RSAKeyGenParameterSpec) type.getParams()).getPublicExponent();
RSAPublicKeySpec rsaks = new RSAPublicKeySpec(rsapriv.getModulus(), exp);
KeyFactory rsakf = KeyFactory.getInstance("RSA");
RSAPublicKey rsapub = (RSAPublicKey) rsakf.generatePublic(rsaks);
return SigUtil.fromJavaKey(rsapub, type);
case EdDSA:
EdDSAPrivateKey epriv = SigUtil.toJavaEdDSAKey(priv);
EdDSAPublicKey epub = new EdDSAPublicKey(new EdDSAPublicKeySpec(epriv.getA(), epriv.getParams()));
return SigUtil.fromJavaKey(epub, type);
default:
throw new IllegalArgumentException("Unsupported algorithm");
}
} catch (GeneralSecurityException gse) {
throw new IllegalArgumentException("Conversion failed", gse);
}
}
use of net.i2p.util.NativeBigInteger in project i2p.i2p by i2p.
the class DSAEngine method signIt.
/**
* Sign using DSA-SHA1 or Syndie DSA-SHA256 ONLY.
*
* @param hash either a Hash or a SHA1Hash
* @return null on error
* @since 0.8.3
*/
private Signature signIt(SimpleDataStructure hash, SigningPrivateKey signingKey) {
if ((signingKey == null) || (hash == null))
return null;
if (signingKey.getType() != SigType.DSA_SHA1)
throw new IllegalArgumentException("Bad key type " + signingKey.getType());
long start = _context.clock().now();
BigInteger k;
boolean ok;
do {
k = new NativeBigInteger(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.modPowCT(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 (rbytes.length > 21) {
_log.error("Bad R length " + rbytes.length);
return null;
} else {
// 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 (sbytes.length > 21) {
_log.error("Bad S length " + sbytes.length);
return null;
} else {
// 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];
}
long diff = _context.clock().now() - start;
if (diff > 1000) {
if (_log.shouldLog(Log.WARN))
_log.warn("Took too long to sign (" + diff + "ms)");
}
return new Signature(out);
}
use of net.i2p.util.NativeBigInteger in project i2p.i2p by i2p.
the class DSAEngine method verifySig.
/**
* Verify using DSA-SHA1 or Syndie DSA-SHA256 ONLY.
* @param hash either a Hash or a SHA1Hash
* @since 0.8.3
*/
private boolean verifySig(Signature signature, SimpleDataStructure hash, SigningPublicKey verifyingKey) {
if (signature.getType() != SigType.DSA_SHA1)
throw new IllegalArgumentException("Bad sig type " + signature.getType());
if (verifyingKey.getType() != SigType.DSA_SHA1)
throw new IllegalArgumentException("Bad key type " + verifyingKey.getType());
long start = _context.clock().now();
try {
byte[] sigbytes = signature.getData();
byte[] rbytes = new byte[20];
byte[] sbytes = new byte[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;
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 (RuntimeException e) {
_log.log(Log.CRIT, "Error verifying the signature", e);
return false;
}
}
Aggregations