propagate from branch 'i2p.i2p' (head e606c473eb1e461a477e45419f6295b6430a7353)

to branch 'i2p.i2p.zzz.test2' (head 6212892778308db10a86e58f9f275c838f604973)
This commit is contained in:
zzz
2014-09-09 19:27:10 +00:00
83 changed files with 1081 additions and 236 deletions

View File

@ -42,6 +42,7 @@ import java.security.interfaces.ECKey;
import java.security.interfaces.RSAKey;
import net.i2p.I2PAppContext;
import net.i2p.crypto.eddsa.EdDSAEngine;
import net.i2p.crypto.eddsa.EdDSAKey;
import net.i2p.data.Hash;
import net.i2p.data.Signature;
@ -517,7 +518,7 @@ public class DSAEngine {
java.security.Signature jsig;
if (type.getBaseAlgorithm() == SigAlgo.EdDSA)
jsig = new net.i2p.crypto.eddsa.EdDSAEngine(type.getDigestInstance());
jsig = new EdDSAEngine(type.getDigestInstance());
else
jsig = java.security.Signature.getInstance(type.getAlgorithmName());
PublicKey pubKey = SigUtil.toJavaKey(verifyingKey);
@ -566,7 +567,7 @@ public class DSAEngine {
String algo = getRawAlgo(type);
java.security.Signature jsig;
if (type.getBaseAlgorithm() == SigAlgo.EdDSA)
jsig = new net.i2p.crypto.eddsa.EdDSAEngine(); // Ignore algo, EdDSAKey includes a hash specification.
jsig = new EdDSAEngine(); // Ignore algo, EdDSAKey includes a hash specification.
else
jsig = java.security.Signature.getInstance(algo);
jsig.initVerify(pubKey);
@ -608,7 +609,7 @@ public class DSAEngine {
java.security.Signature jsig;
if (type.getBaseAlgorithm() == SigAlgo.EdDSA)
jsig = new net.i2p.crypto.eddsa.EdDSAEngine(type.getDigestInstance());
jsig = new EdDSAEngine(type.getDigestInstance());
else
jsig = java.security.Signature.getInstance(type.getAlgorithmName());
PrivateKey privKey = SigUtil.toJavaKey(privateKey);
@ -651,7 +652,7 @@ public class DSAEngine {
java.security.Signature jsig;
if (type.getBaseAlgorithm() == SigAlgo.EdDSA)
jsig = new net.i2p.crypto.eddsa.EdDSAEngine(); // Ignore algo, EdDSAKey includes a hash specification.
jsig = new EdDSAEngine(); // Ignore algo, EdDSAKey includes a hash specification.
else
jsig = java.security.Signature.getInstance(algo);
jsig.initSign(privKey, _context.random());

View File

@ -123,6 +123,7 @@ class ECConstants {
Gy= 07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811
*/
/*
private static final ECParms PARM_P192 = new ECParms(
// P N Seed B Gx Gy
"6277101735386680763835789423207666416083908700390324961279",
@ -132,6 +133,7 @@ class ECConstants {
"188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012",
"07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811"
);
*/
/*
@ -318,17 +320,17 @@ class ECConstants {
// standard curve names
// first is OpenJDK 6/7
// second is BC
public static final ECParameterSpec P192_SPEC = genSpec("secp192r1", "P-192", PARM_P192);
//public static final ECParameterSpec P192_SPEC = genSpec("secp192r1", "P-192", PARM_P192);
public static final ECParameterSpec P256_SPEC = genSpec("secp256r1", "P-256", PARM_P256);
public static final ECParameterSpec P384_SPEC = genSpec("secp384r1", "P-384", PARM_P384);
public static final ECParameterSpec P521_SPEC = genSpec("secp521r1", "P-521", PARM_P521);
// Koblitz
public static final ECParameterSpec K163_SPEC = genSpec("sect163k1", "K-163", null);
public static final ECParameterSpec K233_SPEC = genSpec("sect233k1", "K-233", null);
public static final ECParameterSpec K283_SPEC = genSpec("sect283k1", "K-283", null);
public static final ECParameterSpec K409_SPEC = genSpec("sect409k1", "K-409", null);
public static final ECParameterSpec K571_SPEC = genSpec("sect571k1", "K-571", null);
//public static final ECParameterSpec K163_SPEC = genSpec("sect163k1", "K-163", null);
//public static final ECParameterSpec K233_SPEC = genSpec("sect233k1", "K-233", null);
//public static final ECParameterSpec K283_SPEC = genSpec("sect283k1", "K-283", null);
//public static final ECParameterSpec K409_SPEC = genSpec("sect409k1", "K-409", null);
//public static final ECParameterSpec K571_SPEC = genSpec("sect571k1", "K-571", null);
}

View File

@ -67,12 +67,16 @@ public class SU3File {
private static final int VERSION_OFFSET = 40; // Signature.SIGNATURE_BYTES; avoid early ctx init
public static final int TYPE_ZIP = 0;
/** @since 0.9.15 */
public static final int TYPE_XML = 1;
/** @since 0.9.15 */
public static final int TYPE_HTML = 2;
public static final int CONTENT_UNKNOWN = 0;
public static final int CONTENT_ROUTER = 1;
public static final int CONTENT_PLUGIN = 2;
public static final int CONTENT_RESEED = 3;
/** @since 0.9.15 */
public static final int CONTENT_NEWS = 4;
private enum ContentType {

View File

@ -95,6 +95,7 @@ public enum SigType {
private final SigAlgo base;
private final String digestName, algoName, since;
private final AlgorithmParameterSpec params;
private final boolean isAvail;
SigType(int cod, int pubLen, int privLen, int hLen, int sLen, SigAlgo baseAlgo,
String mdName, String aName, AlgorithmParameterSpec pSpec, String supportedSince) {
@ -108,6 +109,7 @@ public enum SigType {
algoName = aName;
params = pSpec;
since = supportedSince;
isAvail = x_isAvailable();
}
/** the unique identifier for this type */
@ -180,6 +182,10 @@ public enum SigType {
* @return true if supported in this JVM
*/
public boolean isAvailable() {
return isAvail;
}
private boolean x_isAvailable() {
if (DSA_SHA1 == this)
return true;
try {

View File

@ -16,6 +16,7 @@ import net.i2p.crypto.eddsa.math.GroupElement;
import net.i2p.crypto.eddsa.math.ScalarOps;
/**
* @since 0.9.15
* @author str4d
*
*/

View File

@ -4,6 +4,8 @@ import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
/**
* Common interface for all EdDSA keys.
*
* @since 0.9.15
* @author str4d
*
*/

View File

@ -8,6 +8,8 @@ import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
/**
* An EdDSA private key.
*
* @since 0.9.15
* @author str4d
*
*/

View File

@ -8,6 +8,8 @@ import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
/**
* An EdDSA public key.
*
* @since 0.9.15
* @author str4d
*
*/

View File

@ -12,6 +12,7 @@ import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
/**
* @since 0.9.15
* @author str4d
*
*/

View File

@ -17,6 +17,8 @@ import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
/**
* Default strength is 256
*
* @since 0.9.15
*/
public class KeyPairGenerator extends KeyPairGeneratorSpi {
private static final int DEFAULT_STRENGTH = 256;

View File

@ -1,6 +1,10 @@
package net.i2p.crypto.eddsa;
/**
* Basic utilities for eddsa.
* Not for external use, not maintained as a public API.
*
* @since 0.9.15
* @author str4d
*
*/
@ -18,6 +22,18 @@ public class Utils {
return (result ^ 0x01) & 0x01;
}
/**
* Constant-time byte[] comparison.
* @return 1 if b and c are equal, 0 otherwise.
*/
public static int equal(byte[] b, byte[] c) {
int result = 0;
for (int i = 0; i < 32; i++) {
result |= b[i] ^ c[i];
}
return ~equal(result, 0) & 0x01;
}
/**
* Constant-time determine if byte is negative.
* @param b the byte to check.
@ -34,7 +50,7 @@ public class Utils {
* @return 0 or 1, the value of the i'th bit in h
*/
public static int bit(byte[] h, int i) {
return (h[i/8] >> (i%8)) & 1;
return (h[i >> 3] >> (i & 7)) & 1;
}
/**
@ -51,4 +67,22 @@ public class Utils {
}
return data;
}
/**
* Converts bytes to a hex string.
* @param raw the byte[] to be converted.
* @return the hex representation as a string.
*/
public static String bytesToHex(byte[] raw) {
if ( raw == null ) {
return null;
}
final StringBuilder hex = new StringBuilder(2 * raw.length);
for (final byte b : raw) {
hex.append(Character.forDigit((b & 0xF0) >> 4, 16))
.append(Character.forDigit((b & 0x0F), 16));
}
return hex.toString();
}
}

View File

@ -5,6 +5,8 @@ import java.io.Serializable;
/**
* A twisted Edwards curve.
* Points on the curve satisfy -x^2 + y^2 = 1 + d x^2y^2
*
* @since 0.9.15
* @author str4d
*
*/

View File

@ -3,6 +3,8 @@ package net.i2p.crypto.eddsa.math;
/**
* Common interface for all (b-1)-bit encodings of elements
* of EdDSA finite fields.
*
* @since 0.9.15
* @author str4d
*
*/
@ -22,7 +24,7 @@ public abstract class Encoding {
/**
* Decode a FieldElement from its (b-1)-bit encoding.
* The highest bit is masked out.
* @param val the (b-1)-bit encoding of a FieldElement.
* @param in the (b-1)-bit encoding of a FieldElement.
* @return the FieldElement represented by 'val'.
*/
public abstract FieldElement decode(byte[] in);
@ -33,7 +35,7 @@ public abstract class Encoding {
* than the (b-1)-bit encoding of -x. If q is an odd prime and the encoding
* is the little-endian representation of {0, 1,..., q-1} then the negative
* elements of F_q are {1, 3, 5,..., q-2}.
* @return
* @return true if negative
*/
public abstract boolean isNegative(FieldElement x);
}

View File

@ -4,6 +4,8 @@ import java.io.Serializable;
/**
* An EdDSA finite field. Includes several pre-computed values.
*
* @since 0.9.15
* @author str4d
*
*/

View File

@ -1,5 +1,10 @@
package net.i2p.crypto.eddsa.math;
/**
*
* @since 0.9.15
*
*/
public abstract class FieldElement {
protected final Field f;

View File

@ -6,6 +6,8 @@ import net.i2p.crypto.eddsa.Utils;
/**
* A point (x,y) on an EdDSA curve.
*
* @since 0.9.15
* @author str4d
*
*/
@ -489,7 +491,7 @@ public class GroupElement implements Serializable {
*
* @param pos = i/2 for i in {0, 2, 4,..., 62}
* @param b = r_i
* @return
* @return the GroupElement
*/
GroupElement select(int pos, int b) {
// Is r_i negative?
@ -522,7 +524,7 @@ public class GroupElement implements Serializable {
* Preconditions: (TODO: Check this applies here)
* a[31] <= 127
* @param a = a[0]+256*a[1]+...+256^31 a[31]
* @return
* @return the GroupElement
*/
public GroupElement scalarMultiply(byte[] a) {
GroupElement t;
@ -603,7 +605,7 @@ public class GroupElement implements Serializable {
* @param A in P3 representation.
* @param a = a[0]+256*a[1]+...+256^31 a[31]
* @param b = b[0]+256*b[1]+...+256^31 b[31]
* @return
* @return the GroupElement
*/
public GroupElement doubleScalarMultiplyVariableTime(GroupElement A, byte[] a, byte[] b) {
byte[] aslide = slide(a);
@ -645,7 +647,6 @@ public class GroupElement implements Serializable {
/**
* Verify that a point is on its curve.
* @param P The point to check.
* @return true if the point lies on its curve.
*/
public boolean isOnCurve() {

View File

@ -1,5 +1,10 @@
package net.i2p.crypto.eddsa.math;
/**
*
* @since 0.9.15
*
*/
public interface ScalarOps {
/**
* Reduce the given scalar mod l.

View File

@ -65,7 +65,7 @@ public class BigIntegerLittleEndianEncoding extends Encoding implements Serializ
* than the (b-1)-bit encoding of -x. If q is an odd prime and the encoding
* is the little-endian representation of {0, 1,..., q-1} then the negative
* elements of F_q are {1, 3, 5,..., q-2}.
* @return
* @return true if negative
*/
public boolean isNegative(FieldElement x) {
return ((BigIntegerFieldElement)x).bi.testBit(0);

View File

@ -0,0 +1,6 @@
<html><body>
<p>
Low-level, non-optimized implementation using BigIntegers for any curve.
Unused. See the <a href="../ed25519/package-summary.html">ed25519</a> implementation for Curve 25519.
</p>
</body></html>

View File

@ -1,8 +1,8 @@
package net.i2p.crypto.eddsa.math.ed25519;
import net.i2p.crypto.eddsa.Utils;
import net.i2p.crypto.eddsa.math.Field;
import net.i2p.crypto.eddsa.math.FieldElement;
import net.i2p.data.DataHelper;
/**
* An element t, entries t[0]...t[9], represents the integer
@ -26,11 +26,7 @@ public class Ed25519FieldElement extends FieldElement {
public boolean isNonZero() {
byte[] s = toByteArray();
int result = 0;
for (int i = 0; i < 32; i++) {
result |= s[i] ^ zero[i];
}
return result != 0;
return Utils.equal(s, zero) == 1;
}
/**
@ -959,13 +955,11 @@ public class Ed25519FieldElement extends FieldElement {
if (!(obj instanceof Ed25519FieldElement))
return false;
Ed25519FieldElement fe = (Ed25519FieldElement) obj;
// XXX why does direct byte[] comparison fail?
// TODO should this be constant time?
return DataHelper.toString(toByteArray()).equals(DataHelper.toString(fe.toByteArray()));
return 1==Utils.equal(toByteArray(), fe.toByteArray());
}
@Override
public String toString() {
return "[Ed25519FieldElement val="+DataHelper.toString(toByteArray())+"]";
return "[Ed25519FieldElement val="+Utils.bytesToHex(toByteArray())+"]";
}
}

View File

@ -0,0 +1,6 @@
<html><body>
<p>
Low-level, optimized implementation using Radix 2^51 for Curve 25519.
See the <a href="../bigint/package-summary.html">bigint</a> implementation for other curves.
</p>
</body></html>

View File

@ -0,0 +1,9 @@
<html><body>
<p>
Data structures that definie curves and fields, and
the mathematical operaions on them.
</p><p>
Low-level implementation is in <a href="bigint/package-summary.html">bigint</a> for any curve using BigIntegers,
and in <a href="ed25519/package-summary.html">ed25519</a> for Curve 25519 using Radix 2^51.
</p>
</body></html>

View File

@ -0,0 +1,11 @@
<html><body>
<p>
Java implementation of EdDSA, a digital signature scheme using
a variant of elliptic curve cryptography based on Twisted Edwards curves.
</p><p>
Contains a generic implementation for any curve using BigIntegers,
and an optimized implementation for Curve 25519 using Radix 2^51.
</p><p>
Since 0.9.15.
</p>
</body></html>

View File

@ -5,6 +5,8 @@ import java.security.spec.AlgorithmParameterSpec;
/**
* Implementation of AlgorithmParameterSpec that holds the name of a named
* EdDSA curve specification.
*
* @since 0.9.15
* @author str4d
*
*/

View File

@ -6,6 +6,8 @@ import net.i2p.crypto.eddsa.math.ScalarOps;
/**
* EdDSA Curve specification that can also be referred to by name.
*
* @since 0.9.15
* @author str4d
*
*/

View File

@ -10,6 +10,8 @@ import net.i2p.crypto.eddsa.math.ed25519.Ed25519ScalarOps;
/**
* The named EdDSA curves.
*
* @since 0.9.15
* @author str4d
*
*/

View File

@ -12,6 +12,8 @@ import java.io.Serializable;
/**
* Parameter specification for an EdDSA algorithm.
*
* @since 0.9.15
* @author str4d
*
*/

View File

@ -8,6 +8,8 @@ import java.util.Arrays;
import net.i2p.crypto.eddsa.math.GroupElement;
/**
*
* @since 0.9.15
* @author str4d
*
*/

View File

@ -5,6 +5,8 @@ import java.security.spec.KeySpec;
import net.i2p.crypto.eddsa.math.GroupElement;
/**
*
* @since 0.9.15
* @author str4d
*
*/

View File

@ -0,0 +1,6 @@
<html><body>
<p>
Specifications for curves and keys, and a table for named curves,
initially containing only the 25519 curve "ed25519-sha-512".
</p>
</body></html>

View File

@ -0,0 +1,11 @@
<html><body>
<p>
I2P implementation of java.security.Provider for EdDSA.
</p><p>
This should only be required when
using runtime registration of the provider with the
<code>Security.addProvider()</code> mechanism.
</p><p>
Since 0.9.15. Other I2P algorithms may be added later.
</p>
</body></html>

View File

@ -104,7 +104,8 @@ public class Destination extends KeysAndCert {
}
/**
* deprecated, used only by Packet.java in streaming
* Deprecated, used only by Packet.java in streaming.
* Broken for sig types P521 and RSA before 0.9.15
* @return the written length (NOT the new offset)
*/
public int writeBytes(byte target[], int offset) {
@ -115,8 +116,9 @@ public class Destination extends KeysAndCert {
System.arraycopy(_padding, 0, target, cur, _padding.length);
cur += _padding.length;
}
System.arraycopy(_signingKey.getData(), 0, target, cur, _signingKey.length());
cur += _signingKey.length();
int spkTrunc = Math.min(SigningPublicKey.KEYSIZE_BYTES, _signingKey.length());
System.arraycopy(_signingKey.getData(), 0, target, cur, spkTrunc);
cur += spkTrunc;
cur += _certificate.writeBytes(target, cur);
return cur - offset;
}

View File

@ -81,7 +81,9 @@ public abstract class SimpleDataStructure extends DataStructureImpl {
int length = length();
_data = new byte[length];
int read = read(in, _data);
if (read != length) throw new DataFormatException("Not enough bytes to read the data");
if (read != length)
throw new DataFormatException("EOF reading " + getClass().getSimpleName() +
", read: " + read + ", required: " + length);
}
public void writeBytes(OutputStream out) throws DataFormatException, IOException {

View File

@ -23,5 +23,7 @@ public enum UpdateType {
/** unused */
ADDRESSBOOK,
/** @since 0.9.9 */
ROUTER_SIGNED_SU3
ROUTER_SIGNED_SU3,
/** @since 0.9.15 */
NEWS_SU3
}

View File

@ -475,7 +475,7 @@ public class NativeBigInteger extends BigInteger {
}
if (!_nativeOk) {
warn("Native BigInteger library jbigi not loaded - using pure Java - " +
"poor performance may result - see http://www.i2p2.i2p/jbigi for help");
"poor performance may result - see http://i2p-projekt.i2p/jbigi for help");
}
} catch(Exception e) {
warn("Native BigInteger library jbigi not loaded, using pure java", e);

View File

@ -26,6 +26,7 @@ public abstract class SystemVersion {
private static final boolean _oneDotSix;
private static final boolean _oneDotSeven;
private static final boolean _oneDotEight;
private static final int _androidSDK;
static {
@ -60,9 +61,11 @@ public abstract class SystemVersion {
if (_isAndroid) {
_oneDotSix = _androidSDK >= 9;
_oneDotSeven = _androidSDK >= 19;
_oneDotEight = false;
} else {
_oneDotSix = VersionComparator.comp(System.getProperty("java.version"), "1.6") >= 0;
_oneDotSeven = VersionComparator.comp(System.getProperty("java.version"), "1.7") >= 0;
_oneDotSeven = _oneDotSix && VersionComparator.comp(System.getProperty("java.version"), "1.7") >= 0;
_oneDotEight = _oneDotSeven && VersionComparator.comp(System.getProperty("java.version"), "1.8") >= 0;
}
}
@ -127,6 +130,15 @@ public abstract class SystemVersion {
return _oneDotSeven;
}
/**
*
* @return true if Java 1.8 or higher, false for Android.
* @since 0.9.15
*/
public static boolean isJava8() {
return _oneDotEight;
}
/**
* This isn't always correct.
* http://stackoverflow.com/questions/807263/how-do-i-detect-which-kind-of-jre-is-installed-32bit-vs-64bit