diff --git a/LICENSE.txt b/LICENSE.txt
index 3de838b1d..fe5b52bd7 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -82,6 +82,9 @@ Public domain except as listed below:
Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
See licenses/LICENSE-LGPLv2.1.txt
+ EdDSA-Java:
+ See licenses/LICENSE-CC0-1.0-Universal.txt
+
HostnameVerifier:
From Apache HttpClient 4.4.1 and HttpCore 4.4.1
See licenses/LICENSE-Apache2.0.txt
diff --git a/core/java/src/net/i2p/crypto/eddsa/EdDSAEngine.java b/core/java/src/net/i2p/crypto/eddsa/EdDSAEngine.java
index c55626a24..a237f22fe 100644
--- a/core/java/src/net/i2p/crypto/eddsa/EdDSAEngine.java
+++ b/core/java/src/net/i2p/crypto/eddsa/EdDSAEngine.java
@@ -1,3 +1,14 @@
+/**
+ * EdDSA-Java by str4d
+ *
+ * To the extent possible under law, the person who associated CC0 with
+ * EdDSA-Java has waived all copyright and related or neighboring rights
+ * to EdDSA-Java.
+ *
+ * You should have received a copy of the CC0 legalcode along with this
+ * work. If not, see
- * Warning: Private key encoding is based on the current curdle WG draft, - * and is subject to change. See getEncoded(). - *
- * For compatibility with older releases, decoding supports both the old and new - * draft specifications. See decode(). - *
- * Ref: https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 - *
- * Old Ref: https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04 - *
+ *+ * For compatibility with older releases, decoding supports both RFC 8410 and an + * older draft specifications. * * @since 0.9.15 * @author str4d - * + * @see RFC 8410 + * @see Older draft + * specification */ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey { private static final long serialVersionUID = 23495873459878957L; @@ -72,62 +78,62 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey { /** * Returns the private key in its canonical encoding. - *
+ *
* This implements the following specs: - *
- * This encodes the seed. It will return null if constructed from - * a spec which was directly constructed from H, in which case seed is null. - *
+ *
+ * This encodes the seed. It will return null if constructed from a spec which + * was directly constructed from H, in which case seed is null. + *
* For keys in older formats, decoding and then re-encoding is sufficient to * migrate them to the canonical encoding. - *
+ ** Relevant spec quotes: - *
+ *
+ *
* OneAsymmetricKey ::= SEQUENCE {
* version Version,
* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
* privateKey PrivateKey,
- * attributes [0] Attributes OPTIONAL,
+ * attributes [0] IMPLICIT Attributes OPTIONAL,
* ...,
- * [[2: publicKey [1] PublicKey OPTIONAL ]],
+ * [[2: publicKey [1] IMPLICIT PublicKey OPTIONAL ]],
* ...
* }
*
* Version ::= INTEGER
* PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
* PrivateKey ::= OCTET STRING
- * PublicKey ::= OCTET STRING
+ * PublicKey ::= BIT STRING
* Attributes ::= SET OF Attribute
- *
+ *
*
- *
+ *
* ... when encoding a OneAsymmetricKey object, the private key is wrapped
* in a CurvePrivateKey object and wrapped by the OCTET STRING of the
- * 'privateKey' field.
+ * "privateKey" field.
*
* CurvePrivateKey ::= OCTET STRING
- *
+ *
*
- *
+ *
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL
* }
*
* For all of the OIDs, the parameters MUST be absent.
- *
+ *
*
- *
+ *
* id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
- *
+ *
*
- * @return 48 bytes for Ed25519, null for other curves
- * @since implemented in 0.9.25
+ * @return 48 bytes for Ed25519, null for other curves
+ * @since implemented in 0.9.25
*/
@Override
public byte[] getEncoded() {
@@ -171,22 +177,20 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
/**
* Extracts the private key bytes from the provided encoding.
- *- * This will decode data conforming to the current spec at - * https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 - * or as inferred from the old spec at - * https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04. - *
- * Contrary to draft-ietf-curdle-pkix-04, it WILL accept a parameter value - * of NULL, as it is required for interoperability with the default Java - * keystore. Other implementations MUST NOT copy this behaviour from here - * unless they also need to read keys from the default Java keystore. - *
+ *
+ * This will decode data conforming to RFC 8410 or as inferred from the older + * draft spec at https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04. + *
+ * Per RFC 8410 section 3, this function WILL accept a parameter value of + * NULL, as it is required for interoperability with the default Java keystore. + * Other implementations MUST NOT copy this behaviour from here unless they also + * need to read keys from the default Java keystore. + *
* This is really dumb for now. It does not use a general-purpose ASN.1 decoder.
* See also getEncoded().
*
- * @return 32 bytes for Ed25519, throws for other curves
- * @since 0.9.25
+ * @return 32 bytes for Ed25519, throws for other curves
+ * @since 0.9.25
*/
private static byte[] decode(byte[] d) throws InvalidKeySpecException {
try {
@@ -244,13 +248,18 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
} else {
// Handle parameter value of NULL
//
- // Quote https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 :
- // For all of the OIDs, the parameters MUST be absent.
- // Regardless of the defect in the original 1997 syntax,
- // implementations MUST NOT accept a parameters value of NULL.
+ // Quoting RFC 8410 section 3:
+ // > For all of the OIDs, the parameters MUST be absent.
+ // >
+ // > It is possible to find systems that require the parameters to be
+ // > present. This can be due to either a defect in the original 1997
+ // > syntax or a programming error where developers never got input where
+ // > this was not true. The optimal solution is to fix these systems;
+ // > where this is not possible, the problem needs to be restricted to
+ // > that subsystem and not propagated to the Internet.
//
- // But Java's default keystore puts it in (when decoding as
- // PKCS8 and then re-encoding to pass on), so we must accept it.
+ // Java's default keystore puts it in (when decoding as PKCS8 and then
+ // re-encoding to pass on), so we must accept it.
if (idlen == 7) {
if (d[idx++] != 0x05 ||
d[idx++] != 0) {
@@ -281,36 +290,36 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
}
/**
- * @return will be null if constructed from a spec which was
- * directly constructed from H
+ * @return will be null if constructed from a spec which was directly
+ * constructed from H
*/
public byte[] getSeed() {
return seed;
}
/**
- * @return the hash of the seed
+ * @return the hash of the seed
*/
public byte[] getH() {
return h;
}
/**
- * @return the private key
+ * @return the private key
*/
public byte[] geta() {
return a;
}
/**
- * @return the public key
+ * @return the public key
*/
public GroupElement getA() {
return A;
}
/**
- * @return the public key
+ * @return the public key
*/
public byte[] getAbyte() {
return Abyte;
diff --git a/core/java/src/net/i2p/crypto/eddsa/EdDSAPublicKey.java b/core/java/src/net/i2p/crypto/eddsa/EdDSAPublicKey.java
index 383d46a4a..00c247950 100644
--- a/core/java/src/net/i2p/crypto/eddsa/EdDSAPublicKey.java
+++ b/core/java/src/net/i2p/crypto/eddsa/EdDSAPublicKey.java
@@ -1,3 +1,14 @@
+/**
+ * EdDSA-Java by str4d
+ *
+ * To the extent possible under law, the person who associated CC0 with
+ * EdDSA-Java has waived all copyright and related or neighboring rights
+ * to EdDSA-Java.
+ *
+ * You should have received a copy of the CC0 legalcode along with this
+ * work. If not, see
- * Warning: Public key encoding is is based on the current curdle WG draft, - * and is subject to change. See getEncoded(). - *
- * For compatibility with older releases, decoding supports both the old and new - * draft specifications. See decode(). - *
- * Ref: https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 - *
- * Old Ref: https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04 - *
+ *+ * For compatibility with older releases, decoding supports both RFC 8410 and an + * older draft specification. * * @since 0.9.15 * @author str4d - * + * @see RFC 8410 + * @see Older draft + * specification */ public class EdDSAPublicKey implements EdDSAKey, PublicKey { private static final long serialVersionUID = 9837459837498475L; private final GroupElement A; - private GroupElement Aneg; + private GroupElement Aneg = null; private final byte[] Abyte; private final EdDSAParameterSpec edDsaSpec; @@ -67,19 +73,19 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey { /** * Returns the public key in its canonical encoding. - *
+ *
* This implements the following specs: - *
+ *
* For keys in older formats, decoding and then re-encoding is sufficient to * migrate them to the canonical encoding. - *
+ ** Relevant spec quotes: - *
+ *
+ *
* In the X.509 certificate, the subjectPublicKeyInfo field has the
* SubjectPublicKeyInfo type, which has the following ASN.1 syntax:
*
@@ -87,23 +93,23 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey {
* algorithm AlgorithmIdentifier,
* subjectPublicKey BIT STRING
* }
- *
+ *
*
- *
+ *
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL
* }
*
* For all of the OIDs, the parameters MUST be absent.
- *
+ *
*
- *
+ *
* id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
- *
+ *
*
- * @return 44 bytes for Ed25519, null for other curves
- * @since implemented in 0.9.25
+ * @return 44 bytes for Ed25519, null for other curves
+ * @since implemented in 0.9.25
*/
@Override
public byte[] getEncoded() {
@@ -137,23 +143,20 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey {
/**
* Extracts the public key bytes from the provided encoding.
- *- * This will decode data conforming to the current spec at - * https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 - * or the old spec at + *
+ * This will decode data conforming to RFC 8410 or the older draft spec at * https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04. - *
- * Contrary to draft-ietf-curdle-pkix-04, it WILL accept a parameter value - * of NULL, as it is required for interoperability with the default Java - * keystore. Other implementations MUST NOT copy this behaviour from here - * unless they also need to read keys from the default Java keystore. - *
+ *
+ * Per RFC 8410 section 3, this function WILL accept a parameter value of + * NULL, as it is required for interoperability with the default Java keystore. + * Other implementations MUST NOT copy this behaviour from here unless they also + * need to read keys from the default Java keystore. + *
* This is really dumb for now. It does not use a general-purpose ASN.1 decoder. * See also getEncoded(). - *
* - * @return 32 bytes for Ed25519, throws for other curves - * @since 0.9.25 + * @return 32 bytes for Ed25519, throws for other curves + * @since 0.9.25 */ private static byte[] decode(byte[] d) throws InvalidKeySpecException { try { @@ -208,13 +211,18 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey { } else { // Handle parameter value of NULL // - // Quote https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 : - // For all of the OIDs, the parameters MUST be absent. - // Regardless of the defect in the original 1997 syntax, - // implementations MUST NOT accept a parameters value of NULL. + // Quoting RFC 8410 section 3: + // > For all of the OIDs, the parameters MUST be absent. + // > + // > It is possible to find systems that require the parameters to be + // > present. This can be due to either a defect in the original 1997 + // > syntax or a programming error where developers never got input where + // > this was not true. The optimal solution is to fix these systems; + // > where this is not possible, the problem needs to be restricted to + // > that subsystem and not propagated to the Internet. // - // But Java's default keystore puts it in (when decoding as - // PKCS8 and then re-encoding to pass on), so we must accept it. + // Java's default keystore puts it in (when decoding as PKCS8 and then + // re-encoding to pass on), so we must accept it. if (idlen == 7) { if (d[idx++] != 0x05 || d[idx++] != 0) { @@ -245,7 +253,8 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey { } public GroupElement getNegativeA() { - // Only read Aneg once, otherwise read re-ordering might occur between here and return. Requires all GroupElement's fields to be final. + // Only read Aneg once, otherwise read re-ordering might occur between + // here and return. Requires all GroupElement's fields to be final. GroupElement ourAneg = Aneg; if(ourAneg == null) { ourAneg = A.negate(); diff --git a/core/java/src/net/i2p/crypto/eddsa/KeyFactory.java b/core/java/src/net/i2p/crypto/eddsa/KeyFactory.java index 72fd03152..12ed96683 100644 --- a/core/java/src/net/i2p/crypto/eddsa/KeyFactory.java +++ b/core/java/src/net/i2p/crypto/eddsa/KeyFactory.java @@ -1,3 +1,14 @@ +/** + * EdDSA-Java by str4d + * + * To the extent possible under law, the person who associated CC0 with + * EdDSA-Java has waived all copyright and related or neighboring rights + * to EdDSA-Java. + * + * You should have received a copy of the CC0 legalcode along with this + * work. If not, see* Reviewed/commented by Bloody Rookie (nemproject@gmx.de) *
@@ -20,36 +31,36 @@ import java.util.Arrays; * * @since 0.9.15 * @author str4d - * */ public class GroupElement implements Serializable { private static final long serialVersionUID = 2395879087349587L; /** * Available representations for a group element. - *
- * A point (x,y) is encoded by storing y in bit 0 to bit 254 and the sign of x in bit 255. - * x is recovered in the following way: + * A point $(x,y)$ is encoded by storing $y$ in bit 0 to bit 254 and the sign of $x$ in bit 255. + * $x$ is recovered in the following way: *
- * A point (x,y) is encoded by storing y in bit 0 to bit 254 and the sign of x in bit 255. - * x is recovered in the following way: + * A point $(x,y)$ is encoded by storing $y$ in bit 0 to bit 254 and the sign of $x$ in bit 255. + * $x$ is recovered in the following way: *
* Supported conversions: - *
- * r in P x P representation: + * $r$ in $P \times P$ representation: *
- * r = ((X' : Z'), (Y' : T')) where + * $r = ((X' : Z'), (Y' : T'))$ where *
- * r converted from P x P to P^2 representation: + * $r$ converted from $P \times P$ to $P^2$ representation: *
- * r = (X'' : Y'' : Z'') where + * $r = (X'' : Y'' : Z'')$ where *
- * Formula for the P^2 representation is in agreement with the formula given in [4] page 12 (with a = -1) + * Formula for the $P^2$ representation is in agreement with the formula given in [4] page 12 (with $a = -1$) * up to a common factor -1 which does not matter: *
- * B = (X + Y)^2; C = X^2; D = Y^2; E = -C = -X^2; F := E + D = Y^2 - X^2; H = Z^2; J = F − 2 * H; - * X3 = (B − C − D) · J = X' * (-T'); - * Y3 = F · (E − D) = Z' * (-Y'); + * $$ + * B = (X + Y)^2; C = X^2; D = Y^2; E = -C = -X^2; F := E + D = Y^2 - X^2; H = Z^2; J = F − 2 * H; \\ + * X3 = (B − C − D) · J = X' * (-T'); \\ + * Y3 = F · (E − D) = Z' * (-Y'); \\ * Z3 = F · J = Z' * (-T'). + * $$ * * @return The P1P1 representation */ @@ -625,41 +638,43 @@ public class GroupElement implements Serializable { * GroupElement addition using the twisted Edwards addition law with * extended coordinates (Hisil2008). *
- * this must be in P^3 representation and q in PRECOMP representation. - * r = p + q where p = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z) = (Y2/Z2 + X2/Z2, Y2/Z2 - X2/Z2, 2 * d * X2/Z2 * Y2/Z2) + * this must be in $P^3$ representation and $q$ in PRECOMP representation. + * $r = p + q$ where $p = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z) = (Y2/Z2 + X2/Z2, Y2/Z2 - X2/Z2, 2 * d * X2/Z2 * Y2/Z2)$ *
- * r in P x P representation: + * $r$ in $P \times P$ representation: *
- * r = ((X' : Z'), (Y' : T')) where - *
- * Setting A = (Y1 - X1) * (Y2 - X2), B = (Y1 + X1) * (Y2 + X2), C = 2 * d * T1 * T2, D = 2 * Z1 * Z2 we get - *
- * r converted from P x P to P^2 representation: + * $r$ converted from $P \times P$ to $P^2$ representation: *
- * r = (X'' : Y'' : Z'' : T'') where - *
- * TODO-CR BR: Formula for the P^2 representation is not in agreement with the formula given in [2] page 6
- * TODO-CR BR: (the common factor 1/Z2^2 does not matter):
- * E = B - A, F = D - C, G = D + C, H = B + A
- * X3 = E * F = (B - A) * (D - C);
- * Y3 = G * H = (D + C) * (B + A);
- * Z3 = F * G = (D - C) * (D + C);
+ * TODO-CR BR: Formula for the $P^2$ representation is not in agreement with the formula given in [2] page 6
+ * TODO-CR BR: (the common factor $1/Z2^2$ does not matter):
+ * $$
+ * E = B - A, F = D - C, G = D + C, H = B + A \\
+ * X3 = E * F = (B - A) * (D - C); \\
+ * Y3 = G * H = (D + C) * (B + A); \\
+ * Z3 = F * G = (D - C) * (D + C); \\
* T3 = E * H = (B - A) * (B + A);
+ * $$
*
* @param q the PRECOMP representation of the GroupElement to add.
* @return the P1P1 representation of the result.
@@ -684,10 +699,10 @@ public class GroupElement implements Serializable {
* GroupElement subtraction using the twisted Edwards addition law with
* extended coordinates (Hisil2008).
*
- * this must be in P^3 representation and q in PRECOMP representation. - * r = p - q where p = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z) = (Y2/Z2 + X2/Z2, Y2/Z2 - X2/Z2, 2 * d * X2/Z2 * Y2/Z2) + * this must be in $P^3$ representation and $q$ in PRECOMP representation. + * $r = p - q$ where $p = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z) = (Y2/Z2 + X2/Z2, Y2/Z2 - X2/Z2, 2 * d * X2/Z2 * Y2/Z2)$ *
- * Negating q means negating the value of X2 and T2 (the latter is irrelevant here). + * Negating $q$ means negating the value of $X2$ and $T2$ (the latter is irrelevant here). * The formula is in accordance to {@link #madd the above addition}. * * @param q the PRECOMP representation of the GroupElement to subtract. @@ -713,22 +728,22 @@ public class GroupElement implements Serializable { * GroupElement addition using the twisted Edwards addition law with * extended coordinates (Hisil2008). *
- * this must be in P^3 representation and q in CACHED representation. - * r = p + q where p = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z, q.T) = (Y2 + X2, Y2 - X2, Z2, 2 * d * T2) + * this must be in $P^3$ representation and $q$ in CACHED representation. + * $r = p + q$ where $p = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z, q.T) = (Y2 + X2, Y2 - X2, Z2, 2 * d * T2)$ *
- * r in P x P representation: + * $r$ in $P \times P$ representation: *
- * Setting A = (Y1 - X1) * (Y2 - X2), B = (Y1 + X1) * (Y2 + X2), C = 2 * d * T1 * T2, D = 2 * Z1 * Z2 we get + * Setting $A = (Y1 - X1) * (Y2 - X2), B = (Y1 + X1) * (Y2 + X2), C = 2 * d * T1 * T2, D = 2 * Z1 * Z2$ we get *
* Same result as in {@link #madd} (up to a common factor which does not matter). * @@ -756,9 +771,9 @@ public class GroupElement implements Serializable { * GroupElement subtraction using the twisted Edwards addition law with * extended coordinates (Hisil2008). *
- * r = p - q + * $r = p - q$ *
- * Negating q means negating the value of the coordinate X2 and T2. + * Negating $q$ means negating the value of the coordinate $X2$ and $T2$. * The formula is in accordance to {@link #add the above addition}. * * @param q the PRECOMP representation of the GroupElement to subtract. @@ -784,7 +799,7 @@ public class GroupElement implements Serializable { /** * Negates this group element by subtracting it from the neutral group element. *
- * TODO-CR BR: why not simply negate the coordinates X and T? + * TODO-CR BR: why not simply negate the coordinates $X$ and $T$? * * @return The negative of this group element. */ @@ -852,7 +867,7 @@ public class GroupElement implements Serializable { *
* Method is package private only so that tests run. * - * @param a = a[0]+256*a[1]+...+256^31 a[31] + * @param a $= a[0]+256*a[1]+...+256^{31} a[31]$ * @return 64 bytes, each between -8 and 7 */ static byte[] toRadix16(final byte[] a) { @@ -880,21 +895,21 @@ public class GroupElement implements Serializable { /** * Constant-time conditional move. *
- * Replaces this with u if b == 1.
- * Replaces this with this if b == 0.
+ * Replaces this with $u$ if $b == 1$.
+ * Replaces this with this if $b == 0$.
*
* Method is package private only so that tests run. * - * @param u The group element to return if b == 1. - * @param b in {0, 1} - * @return u if b == 1; this if b == 0; Results undefined if b is not in {0, 1}. + * @param u The group element to return if $b == 1$. + * @param b in $\{0, 1\}$ + * @return $u$ if $b == 1$; this if $b == 0$. Results undefined if $b$ is not in $\{0, 1\}$. */ GroupElement cmov(final GroupElement u, final int b) { return precomp(curve, X.cmov(u.X, b), Y.cmov(u.Y, b), Z.cmov(u.Z, b)); } /** - * Look up 16^i r_i B in the precomputed table. + * Look up $16^i r_i B$ in the precomputed table. *
* No secret array indices, no secret branching. * Constant time. @@ -903,8 +918,8 @@ public class GroupElement implements Serializable { *
* Method is package private only so that tests run. * - * @param pos = i/2 for i in {0, 2, 4,..., 62} - * @param b = r_i + * @param pos $= i/2$ for $i$ in $\{0, 2, 4,..., 62\}$ + * @param b $= r_i$ * @return the GroupElement */ GroupElement select(final int pos, final int b) { @@ -930,14 +945,14 @@ public class GroupElement implements Serializable { } /** - * h = a * B where a = a[0]+256*a[1]+...+256^31 a[31] and - * B is this point. If its lookup table has not been precomputed, it - * will be at the start of the method (and cached for later calls). + * $h = a * B$ where $a = a[0]+256*a[1]+\dots+256^{31} a[31]$ and + * $B$ is this point. If its lookup table has not been precomputed, it + * will be at the start of the method (and cached for later calls). * Constant time. *
* Preconditions: (TODO: Check this applies here) - * a[31] <= 127 - * @param a = a[0]+256*a[1]+...+256^31 a[31] + * $a[31] \le 127$ + * @param a $= a[0]+256*a[1]+\dots+256^{31} a[31]$ * @return the GroupElement */ public GroupElement scalarMultiply(final byte[] a) { @@ -963,16 +978,16 @@ public class GroupElement implements Serializable { } /** - * Calculates a sliding-windows base 2 representation for a given value a. + * Calculates a sliding-windows base 2 representation for a given value $a$. * To learn more about it see [6] page 8. *
- * Output: r which satisfies - * a = r0 * 2^0 + r1 * 2^1 + ... + r255 * 2^255 with ri in {-15, -13, -11, -9, -7, -5, -3, -1, 0, 1, 3, 5, 7, 9, 11, 13, 15} + * Output: $r$ which satisfies + * $a = r0 * 2^0 + r1 * 2^1 + \dots + r255 * 2^{255}$ with $ri$ in $\{-15, -13, -11, -9, -7, -5, -3, -1, 0, 1, 3, 5, 7, 9, 11, 13, 15\}$ *
* Method is package private only so that tests run. * - * @param a = a[0]+256*a[1]+...+256^31 a[31]. - * @return The byte array r in the above described form. + * @param a $= a[0]+256*a[1]+\dots+256^{31} a[31]$. + * @return The byte array $r$ in the above described form. */ static byte[] slide(final byte[] a) { byte[] r = new byte[256]; @@ -1011,14 +1026,14 @@ public class GroupElement implements Serializable { } /** - * r = a * A + b * B where a = a[0]+256*a[1]+...+256^31 a[31], - * b = b[0]+256*b[1]+...+256^31 b[31] and B is this point. + * $r = a * A + b * B$ where $a = a[0]+256*a[1]+\dots+256^{31} a[31]$, + * $b = b[0]+256*b[1]+\dots+256^{31} b[31]$ and $B$ is this point. *
- * A must have been previously precomputed.
+ * $A$ must have been previously precomputed.
*
* @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]
+ * @param a $= a[0]+256*a[1]+\dots+256^{31} a[31]$
+ * @param b $= b[0]+256*b[1]+\dots+256^{31} b[31]$
* @return the GroupElement
*/
public GroupElement doubleScalarMultiplyVariableTime(final GroupElement A, final byte[] a, final byte[] b) {
diff --git a/core/java/src/net/i2p/crypto/eddsa/math/ScalarOps.java b/core/java/src/net/i2p/crypto/eddsa/math/ScalarOps.java
index 2243969c7..627ef6e41 100644
--- a/core/java/src/net/i2p/crypto/eddsa/math/ScalarOps.java
+++ b/core/java/src/net/i2p/crypto/eddsa/math/ScalarOps.java
@@ -1,30 +1,39 @@
+/**
+ * EdDSA-Java by str4d
+ *
+ * To the extent possible under law, the person who associated CC0 with
+ * EdDSA-Java has waived all copyright and related or neighboring rights
+ * to EdDSA-Java.
+ *
+ * You should have received a copy of the CC0 legalcode along with this
+ * work. If not, see
* From the Ed25519 paper:
- * Here we interpret 2b-bit strings in little-endian form as integers in
- * {0, 1,..., 2^(2b)-1}.
- * @param s
- * @return s mod l
+ * Here we interpret $2b$-bit strings in little-endian form as integers in
+ * $\{0, 1,..., 2^{(2b)}-1\}$.
+ * @param s the scalar to reduce
+ * @return $s \bmod l$
*/
public byte[] reduce(byte[] s);
/**
- * r = (a * b + c) mod l
- * @param a
- * @param b
- * @param c
- * @return (a*b + c) mod l
+ * $r = (a * b + c) \bmod l$
+ * @param a a scalar
+ * @param b a scalar
+ * @param c a scalar
+ * @return $(a*b + c) \bmod l$
*/
public byte[] multiplyAndAdd(byte[] a, byte[] b, byte[] c);
}
diff --git a/core/java/src/net/i2p/crypto/eddsa/math/bigint/BigIntegerFieldElement.java b/core/java/src/net/i2p/crypto/eddsa/math/bigint/BigIntegerFieldElement.java
index 8d856263d..db8d18a3f 100644
--- a/core/java/src/net/i2p/crypto/eddsa/math/bigint/BigIntegerFieldElement.java
+++ b/core/java/src/net/i2p/crypto/eddsa/math/bigint/BigIntegerFieldElement.java
@@ -1,3 +1,14 @@
+/**
+ * EdDSA-Java by str4d
+ *
+ * To the extent possible under law, the person who associated CC0 with
+ * EdDSA-Java has waived all copyright and related or neighboring rights
+ * to EdDSA-Java.
+ *
+ * You should have received a copy of the CC0 legalcode along with this
+ * work. If not, see
- * x is negative if the (b-1)-bit encoding of x is lexicographically larger
- * 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}.
+ * $x$ is negative if the $(b-1)$-bit encoding of $x$ is lexicographically larger
+ * 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,\dots, q-1\}$ then the negative
+ * elements of $F_q$ are $\{1, 3, 5,\dots, q-2\}$.
* @return true if negative
*/
public boolean isNegative(FieldElement x) {
diff --git a/core/java/src/net/i2p/crypto/eddsa/math/bigint/BigIntegerScalarOps.java b/core/java/src/net/i2p/crypto/eddsa/math/bigint/BigIntegerScalarOps.java
index 5e199791a..68169dc89 100644
--- a/core/java/src/net/i2p/crypto/eddsa/math/bigint/BigIntegerScalarOps.java
+++ b/core/java/src/net/i2p/crypto/eddsa/math/bigint/BigIntegerScalarOps.java
@@ -1,3 +1,14 @@
+/**
+ * EdDSA-Java by str4d
+ *
+ * To the extent possible under law, the person who associated CC0 with
+ * EdDSA-Java has waived all copyright and related or neighboring rights
+ * to EdDSA-Java.
+ *
+ * You should have received a copy of the CC0 legalcode along with this
+ * work. If not, see
- * An element t, entries t[0]...t[9], represents the integer - * t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. - * Bounds on each t[i] vary depending on context. + * An element $t$, entries $t[0] \dots t[9]$, represents the integer + * $t[0]+2^{26} t[1]+2^{51} t[2]+2^{77} t[3]+2^{102} t[4]+\dots+2^{230} t[9]$. + * Bounds on each $t[i]$ vary depending on context. *
* Reviewed/commented by Bloody Rookie (nemproject@gmx.de) */ @@ -23,8 +34,8 @@ public class Ed25519FieldElement extends FieldElement { /** * Creates a field element. * - * @param f The underlying field, must be the finite field with p = 2^255 - 19 elements - * @param t The 2^25.5 bit representation of the field element. + * @param f The underlying field, must be the finite field with $p = 2^{255} - 19$ elements + * @param t The $2^{25.5}$ bit representation of the field element. */ public Ed25519FieldElement(Field f, int[] t) { super(f); @@ -46,18 +57,18 @@ public class Ed25519FieldElement extends FieldElement { } /** - * h = f + g + * $h = f + g$ *
- * TODO-CR BR: h is allocated via new, probably not a good idea. Do we need the copying into temp variables if we do that? + * TODO-CR BR: $h$ is allocated via new, probably not a good idea. Do we need the copying into temp variables if we do that? *
* Preconditions: *
* Postconditions: *
- * Can overlap h with f or g. + * Can overlap $h$ with $f$ or $g$. *
* TODO-CR BR: See above. *
* Preconditions: *
* Postconditions: *
* TODO-CR BR: see above. *
* Preconditions: *
* Postconditions: *
- * Can overlap h with f or g. + * Can overlap $h$ with $f$ or $g$. *
* Preconditions: *
* Postconditions: *
* Notes on implementation strategy: *
@@ -377,17 +388,17 @@ public class Ed25519FieldElement extends FieldElement { } /** - * h = f * f + * $h = f * f$ *
- * Can overlap h with f. + * Can overlap $h$ with $f$. *
* Preconditions: *
* Postconditions: *
* See {@link #multiply(FieldElement)} for discussion * of implementation strategy. @@ -533,17 +544,17 @@ public class Ed25519FieldElement extends FieldElement { } /** - * h = 2 * f * f + * $h = 2 * f * f$ *
- * Can overlap h with f. + * Can overlap $h$ with $f$. *
* Preconditions: *
* Postconditions: *
* See {@link #multiply(FieldElement)} for discussion * of implementation strategy. @@ -698,7 +709,7 @@ public class Ed25519FieldElement extends FieldElement { * Invert this field element. *
* The inverse is found via Fermat's little theorem:
- * a^p congruent a mod p and therefore a^(p-2) congruent a^-1 mod p
+ * $a^p \cong a \mod p$ and therefore $a^{(p-2)} \cong a^{-1} \mod p$
*
* @return The inverse of this field element.
*/
@@ -816,12 +827,12 @@ public class Ed25519FieldElement extends FieldElement {
}
/**
- * Gets this field element to the power of (2^252 - 3).
+ * Gets this field element to the power of $(2^{252} - 3)$.
* This is a helper function for calculating the square root.
*
* TODO-CR BR: I think it makes sense to have a sqrt function.
*
- * @return This field element to the power of (2^252 - 3).
+ * @return This field element to the power of $(2^{252} - 3)$.
*/
public FieldElement pow22523() {
FieldElement t0, t1, t2;
@@ -941,7 +952,7 @@ public class Ed25519FieldElement extends FieldElement {
*
* @param val the other field element.
* @param b must be 0 or 1, otherwise results are undefined.
- * @return a copy of this if b == 0, or a copy of val if b == 1.
+ * @return a copy of this if $b == 0$, or a copy of val if $b == 1$.
* @since 0.9.36
*/
@Override
diff --git a/core/java/src/net/i2p/crypto/eddsa/math/ed25519/Ed25519LittleEndianEncoding.java b/core/java/src/net/i2p/crypto/eddsa/math/ed25519/Ed25519LittleEndianEncoding.java
index f5f0c3260..126b638bb 100644
--- a/core/java/src/net/i2p/crypto/eddsa/math/ed25519/Ed25519LittleEndianEncoding.java
+++ b/core/java/src/net/i2p/crypto/eddsa/math/ed25519/Ed25519LittleEndianEncoding.java
@@ -1,3 +1,14 @@
+/**
+ * EdDSA-Java by str4d
+ *
+ * To the extent possible under law, the person who associated CC0 with
+ * EdDSA-Java has waived all copyright and related or neighboring rights
+ * to EdDSA-Java.
+ *
+ * You should have received a copy of the CC0 legalcode along with this
+ * work. If not, see
- * The idea for the modulo p reduction algorithm is as follows: - *
- * Assumption: - *
+ * The idea for the modulo $p$ reduction algorithm is as follows: + *
+ *- * Then q = [2^-255 * (h + 19 * 2^-25 * h9 + 1/2)] where [x] = floor(x). - *
- * Proof: + * Then $q = [2^{-255} * (h + 19 * 2^{-25} * h_9 + 1/2)]$ where $[x] = floor(x)$. + *
+ ** We begin with some very raw estimation for the bounds of some expressions: - *
|h| < 2^230 * 2^30 = 2^260 ==> |r + q * p| < 2^260 ==> |q| < 2^10. - * ==> -1/4 <= a := 19^2 * 2^-255 * q < 1/4. - * |h - 2^230 * h9| = |h0 + ... + 2^204 * h8| < 2^204 * 2^30 = 2^234. - * ==> -1/4 <= b := 19 * 2^-255 * (h - 2^230 * h9) < 1/4- * Therefore 0 < 1/2 - a - b < 1. *
- * Set x := r + 19 * 2^-255 * r + 1/2 - a - b then - * 0 <= x < 255 - 20 + 19 + 1 = 2^255 ==> 0 <= 2^-255 * x < 1. Since q is an integer we have - * - *
[q + 2^-255 * x] = q (1)+ * $$ + * \begin{equation} + * |h| \lt 2^{230} * 2^{30} = 2^{260} \Rightarrow |r + q * p| \lt 2^{260} \Rightarrow |q| \lt 2^{10}. \\ + * \Rightarrow -1/4 \le a := 19^2 * 2^{-255} * q \lt 1/4. \\ + * |h - 2^{230} * h_9| = |h_0 + \dots + 2^{204} * h_8| \lt 2^{204} * 2^{30} = 2^{234}. \\ + * \Rightarrow -1/4 \le b := 19 * 2^{-255} * (h - 2^{230} * h_9) \lt 1/4 + * \end{equation} + * $$ *
- * Have a closer look at x: - *
x = h - q * (2^255 - 19) + 19 * 2^-255 * (h - q * (2^255 - 19)) + 1/2 - 19^2 * 2^-255 * q - 19 * 2^-255 * (h - 2^230 * h9) - * = h - q * 2^255 + 19 * q + 19 * 2^-255 * h - 19 * q + 19^2 * 2^-255 * q + 1/2 - 19^2 * 2^-255 * q - 19 * 2^-255 * h + 19 * 2^-25 * h9 - * = h + 19 * 2^-25 * h9 + 1/2 - q^255.+ * Therefore $0 \lt 1/2 - a - b \lt 1$. *
- * Inserting the expression for x into (1) we get the desired expression for q. + * Set $x := r + 19 * 2^{-255} * r + 1/2 - a - b$. Then: + *
+ * $$ + * 0 \le x \lt 255 - 20 + 19 + 1 = 2^{255} \\ + * \Rightarrow 0 \le 2^{-255} * x \lt 1. + * $$ + *
+ * Since $q$ is an integer we have + *
+ * $$ + * [q + 2^{-255} * x] = q \quad (1) + * $$ + *
+ * Have a closer look at $x$: + *
+ * $$ + * \begin{align} + * x &= h - q * (2^{255} - 19) + 19 * 2^{-255} * (h - q * (2^{255} - 19)) + 1/2 - 19^2 * 2^{-255} * q - 19 * 2^{-255} * (h - 2^{230} * h_9) \\ + * &= h - q * 2^{255} + 19 * q + 19 * 2^{-255} * h - 19 * q + 19^2 * 2^{-255} * q + 1/2 - 19^2 * 2^{-255} * q - 19 * 2^{-255} * h + 19 * 2^{-25} * h_9 \\ + * &= h + 19 * 2^{-25} * h_9 + 1/2 - q^{255}. + * \end{align} + * $$ + *
+ * Inserting the expression for $x$ into $(1)$ we get the desired expression for $q$. */ public byte[] encode(FieldElement x) { int[] h = ((Ed25519FieldElement)x).t; @@ -150,10 +181,10 @@ public class Ed25519LittleEndianEncoding extends Encoding { } /** - * Decodes a given field element in its 10 byte 2^25.5 representation. + * Decodes a given field element in its 10 byte $2^{25.5}$ representation. * * @param in The 32 byte representation. - * @return The field element in its 2^25.5 bit representation. + * @return The field element in its $2^{25.5}$ bit representation. */ public FieldElement decode(byte[] in) { long h0 = load_4(in, 0); @@ -207,15 +238,15 @@ public class Ed25519LittleEndianEncoding extends Encoding { /** * Is the FieldElement negative in this encoding? *
- * Return true if x is in {1,3,5,...,q-2}
- * Return false if x is in {0,2,4,...,q-1}
+ * Return true if $x$ is in $\{1,3,5,\dots,q-2\}$
+ * Return false if $x$ is in $\{0,2,4,\dots,q-1\}$
*
* Preconditions: *
- * q = 2^252 + 27742317777372353535851937790883648493. + * $q = 2^{252} + 27742317777372353535851937790883648493$. *
* Reviewed/commented by Bloody Rookie (nemproject@gmx.de) */ public class Ed25519ScalarOps implements ScalarOps { /** - * Reduction modulo the group order q. + * Reduction modulo the group order $q$. *
* Input: - * s[0]+256*s[1]+...+256^63*s[63] = s + * $s[0]+256*s[1]+\dots+256^{63}*s[63] = s$ *
* Output: - * s[0]+256*s[1]+...+256^31*s[31] = s mod q - * where q = 2^252 + 27742317777372353535851937790883648493. + * $s[0]+256*s[1]+\dots+256^{31}*s[31] = s \bmod q$ + * where $q = 2^{252} + 27742317777372353535851937790883648493$. */ public byte[] reduce(byte[] s) { // s0,..., s22 have 21 bits, s23 has 29 bits @@ -313,15 +324,17 @@ public class Ed25519ScalarOps implements ScalarOps { /** + * $(ab+c) \bmod q$ + *
* Input: - *
* Output: - * result[0]+256*result[1]+...+256^31*result[31] = (ab+c) mod q - * where q = 2^252 + 27742317777372353535851937790883648493. + * $result[0]+256*result[1]+\dots+256^{31}*result[31] = (ab+c) \bmod q$ + * where $q = 2^{252} + 27742317777372353535851937790883648493$. *
* See the comments in {@link #reduce(byte[])} for an explanation of the algorithm. */ diff --git a/core/java/src/net/i2p/crypto/eddsa/math/ed25519/package.html b/core/java/src/net/i2p/crypto/eddsa/math/ed25519/package.html index 58e980f45..553122db9 100644 --- a/core/java/src/net/i2p/crypto/eddsa/math/ed25519/package.html +++ b/core/java/src/net/i2p/crypto/eddsa/math/ed25519/package.html @@ -1,6 +1,6 @@
- Low-level, optimized implementation using Radix 2^51 for Curve 25519. + Low-level, optimized implementation using Radix $2^{51}$ for Curve 25519. See the bigint implementation for other curves.
diff --git a/core/java/src/net/i2p/crypto/eddsa/math/package.html b/core/java/src/net/i2p/crypto/eddsa/math/package.html index 282a352c5..f227f2c12 100644 --- a/core/java/src/net/i2p/crypto/eddsa/math/package.html +++ b/core/java/src/net/i2p/crypto/eddsa/math/package.html @@ -4,6 +4,6 @@ the mathematical operaions on them.Low-level implementation is in bigint for any curve using BigIntegers, - and in ed25519 for Curve 25519 using Radix 2^51. + and in ed25519 for Curve 25519 using Radix $2^{51}$.