EdDSA: Reduce diff between vendored code and upstream

Includes missing license information.
This commit is contained in:
str4d
2019-08-10 15:39:41 +00:00
parent 08be6a4f4a
commit 13190931b9
45 changed files with 1008 additions and 415 deletions

View File

@ -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

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa;
import java.io.ByteArrayOutputStream;
@ -153,7 +164,7 @@ public class EdDSAEngine extends Signature {
}
} else if (!key.getParams().getHashAlgorithm().equals(digest.getAlgorithm()))
throw new InvalidKeyException("Key hash algorithm does not match chosen digest");
} else if (publicKey.getClass().getName().equals("sun.security.x509.X509Key")) {
} else if (publicKey.getFormat().equals("X.509")) {
// X509Certificate will sometimes contain an X509Key rather than the EdDSAPublicKey itself; the contained
// key is valid but needs to be instanced as an EdDSAPublicKey before it can be used.
EdDSAPublicKey parsedPublicKey;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa;
import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
@ -7,18 +18,17 @@ import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
*
* @since 0.9.15
* @author str4d
*
*/
public interface EdDSAKey {
/**
* The reported key algorithm for all EdDSA keys
* @since 0.9.36
*/
public String KEY_ALGORITHM = "EdDSA";
String KEY_ALGORITHM = "EdDSA";
/**
* @return a parameter specification representing the EdDSA domain
* parameters for the key.
*/
public EdDSAParameterSpec getParams();
EdDSAParameterSpec getParams();
}

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa;
import java.security.PrivateKey;
@ -12,21 +23,16 @@ import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
/**
* An EdDSA private key.
*<p>
* Warning: Private key encoding is based on the current curdle WG draft,
* and is subject to change. See getEncoded().
*</p><p>
* For compatibility with older releases, decoding supports both the old and new
* draft specifications. See decode().
*</p><p>
* Ref: https://tools.ietf.org/html/draft-ietf-curdle-pkix-04
*</p><p>
* Old Ref: https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04
*</p>
* <p>
* For compatibility with older releases, decoding supports both RFC 8410 and an
* older draft specifications.
*
* @since 0.9.15
* @author str4d
*
* @see <a href="https://tools.ietf.org/html/rfc8410">RFC 8410</a>
* @see <a href=
* "https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04">Older draft
* specification</a>
*/
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.
*<p>
* <p>
* This implements the following specs:
*<ul><li>
* General encoding: https://tools.ietf.org/html/draft-ietf-curdle-pkix-04
*</li><li>
* Key encoding: https://tools.ietf.org/html/rfc8032
*</li></ul>
*<p>
* 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.
*</p><p>
* <ul>
* <li>General encoding: https://tools.ietf.org/html/rfc8410</li>
* <li>Key encoding: https://tools.ietf.org/html/rfc8032</li>
* </ul>
* <p>
* 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.
* <p>
* For keys in older formats, decoding and then re-encoding is sufficient to
* migrate them to the canonical encoding.
*</p>
* <p>
* Relevant spec quotes:
*<pre>
*
* <pre>
* 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
*</pre>
* </pre>
*
*<pre>
* <pre>
* ... 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
*</pre>
* </pre>
*
*<pre>
* <pre>
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL
* }
*
* For all of the OIDs, the parameters MUST be absent.
*</pre>
* </pre>
*
*<pre>
* <pre>
* id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
*</pre>
* </pre>
*
* @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.
*<p>
* 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.
*</p><p>
* 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.
*</p><p>
* <p>
* 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.
* <p>
* 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.
* <p>
* 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;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa;
import java.security.PublicKey;
@ -12,26 +23,21 @@ import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
/**
* An EdDSA public key.
*<p>
* Warning: Public key encoding is is based on the current curdle WG draft,
* and is subject to change. See getEncoded().
*</p><p>
* For compatibility with older releases, decoding supports both the old and new
* draft specifications. See decode().
*</p><p>
* Ref: https://tools.ietf.org/html/draft-ietf-curdle-pkix-04
*</p><p>
* Old Ref: https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04
*</p>
* <p>
* For compatibility with older releases, decoding supports both RFC 8410 and an
* older draft specification.
*
* @since 0.9.15
* @author str4d
*
* @see <a href="https://tools.ietf.org/html/rfc8410">RFC 8410</a>
* @see <a href=
* "https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04">Older draft
* specification</a>
*/
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.
*<p>
* <p>
* This implements the following specs:
*<ul><li>
* General encoding: https://tools.ietf.org/html/draft-ietf-curdle-pkix-04
*</li><li>
* Key encoding: https://tools.ietf.org/html/rfc8032
*</li></ul>
*<p>
* <ul>
* <li>General encoding: https://tools.ietf.org/html/rfc8410</li>
* <li>Key encoding: https://tools.ietf.org/html/rfc8032</li>
* </ul>
* <p>
* For keys in older formats, decoding and then re-encoding is sufficient to
* migrate them to the canonical encoding.
*</p>
* <p>
* Relevant spec quotes:
*<pre>
*
* <pre>
* 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
* }
*</pre>
* </pre>
*
*<pre>
* <pre>
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL
* }
*
* For all of the OIDs, the parameters MUST be absent.
*</pre>
* </pre>
*
*<pre>
* <pre>
* id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
*</pre>
* </pre>
*
* @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.
*<p>
* 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
* <p>
* This will decode data conforming to RFC 8410 or the older draft spec at
* https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04.
*</p><p>
* 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.
*</p><p>
* <p>
* 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.
* <p>
* This is really dumb for now. It does not use a general-purpose ASN.1 decoder.
* See also getEncoded().
*</p>
*
* @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();

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa;
import java.security.InvalidKeyException;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa;
import java.security.InvalidAlgorithmParameterException;
@ -32,7 +43,7 @@ public class KeyPairGenerator extends KeyPairGeneratorSpi {
static {
edParameters = new Hashtable<Integer, AlgorithmParameterSpec>();
edParameters.put(Integer.valueOf(DEFAULT_KEYSIZE), new EdDSAGenParameterSpec(EdDSANamedCurveTable.ED_25519));
edParameters.put(Integer.valueOf(256), new EdDSAGenParameterSpec(EdDSANamedCurveTable.ED_25519));
}
public void initialize(int keysize, SecureRandom random) {

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa;
/**
@ -65,6 +76,9 @@ public class Utils {
*/
public static byte[] hexToBytes(String s) {
int len = s.length();
if (len % 2 != 0) {
throw new IllegalArgumentException("Hex string must have an even length");
}
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math;
import net.i2p.crypto.eddsa.Utils;

View File

@ -1,10 +1,21 @@
/**
* 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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math;
import java.io.Serializable;
/**
* A twisted Edwards curve.
* Points on the curve satisfy -x^2 + y^2 = 1 + d x^2y^2
* Points on the curve satisfy $-x^2 + y^2 = 1 + d x^2y^2$
*
* @since 0.9.15
* @author str4d

View File

@ -1,9 +1,20 @@
/**
* 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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math;
import java.io.Serializable;
/**
* Common interface for all (b-1)-bit encodings of elements
* Common interface for all $(b-1)$-bit encodings of elements
* of EdDSA finite fields.
*
* @since 0.9.15
@ -20,25 +31,27 @@ public abstract class Encoding implements Serializable {
}
/**
* Encode a FieldElement in its (b-1)-bit encoding.
* @return the (b-1)-bit encoding of this FieldElement.
* Encode a FieldElement in its $(b-1)$-bit encoding.
* @param x the FieldElement to encode
* @return the $(b-1)$-bit encoding of this FieldElement.
*/
public abstract byte[] encode(FieldElement x);
/**
* Decode a FieldElement from its (b-1)-bit encoding.
* Decode a FieldElement from its $(b-1)$-bit encoding.
* The highest bit is masked out.
* @param in 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);
/**
* From the Ed25519 paper:<br>
* 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\}$.
* @param x the FieldElement to check
* @return true if negative
*/
public abstract boolean isNegative(FieldElement x);

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math;
import java.io.Serializable;

View File

@ -1,13 +1,22 @@
/**
* 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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math;
import java.io.Serializable;
/**
*
* Note: concrete subclasses must implement hashCode() and equals()
*
* @since 0.9.15
*
*/
public abstract class FieldElement implements Serializable {
private static final long serialVersionUID = 1239527465875676L;
@ -22,8 +31,8 @@ public abstract class FieldElement implements Serializable {
}
/**
* Encode a FieldElement in its (b-1)-bit encoding.
* @return the (b-1)-bit encoding of this FieldElement.
* Encode a FieldElement in its $(b-1)$-bit encoding.
* @return the $(b-1)$-bit encoding of this FieldElement.
*/
public byte[] toByteArray() {
return f.getEncoding().encode(this);

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math;
import net.i2p.crypto.eddsa.Utils;
@ -6,7 +17,7 @@ import java.io.Serializable;
import java.util.Arrays;
/**
* A point (x,y) on an EdDSA curve.
* A point $(x,y)$ on an EdDSA curve.
* <p>
* Reviewed/commented by Bloody Rookie (nemproject@gmx.de)
* <p>
@ -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.
* <p><ul>
* <li>P2: Projective representation (X:Y:Z) satisfying x=X/Z, y=Y/Z.
* <li>P3: Extended projective representation (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT.
* <li>P1P1: Completed representation ((X:Z), (Y:T)) satisfying x=X/Z, y=Y/T.
* <li>PRECOMP: Precomputed representation (y+x, y-x, 2dxy).
* <li>CACHED: Cached representation (Y+X, Y-X, Z, 2dT)
* <ul>
* <li>P2: Projective representation $(X:Y:Z)$ satisfying $x=X/Z, y=Y/Z$.
* <li>P3: Extended projective representation $(X:Y:Z:T)$ satisfying $x=X/Z, y=Y/Z, XY=ZT$.
* <li>P3PrecomputedDouble: P3 but with dblPrecmp populated.
* <li>P1P1: Completed representation $((X:Z), (Y:T))$ satisfying $x=X/Z, y=Y/T$.
* <li>PRECOMP: Precomputed representation $(y+x, y-x, 2dxy)$.
* <li>CACHED: Cached representation $(Y+X, Y-X, Z, 2dT)$
* </ul>
*/
public enum Representation {
/** Projective (P^2): (X:Y:Z) satisfying x=X/Z, y=Y/Z */
/** Projective ($P^2$): $(X:Y:Z)$ satisfying $x=X/Z, y=Y/Z$ */
P2,
/** Extended (P^3): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT */
/** Extended ($P^3$): $(X:Y:Z:T)$ satisfying $x=X/Z, y=Y/Z, XY=ZT$ */
P3,
/**
* Can only be requested. Results in P3 representation but also populates dblPrecmp.
* @since 0.9.36
*/
P3PrecomputedDouble,
/** Completed (P x P): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T */
/** Completed ($P \times P$): $((X:Z),(Y:T))$ satisfying $x=X/Z, y=Y/T$ */
P1P1,
/** Precomputed (Duif): (y+x,y-x,2dxy) */
/** Precomputed (Duif): $(y+x,y-x,2dxy)$ */
PRECOMP,
/** Cached: (Y+X,Y-X,Z,2dT) */
/** Cached: $(Y+X,Y-X,Z,2dT)$ */
CACHED
}
@ -57,9 +68,9 @@ public class GroupElement implements Serializable {
* Creates a new group element in P2 representation.
*
* @param curve The curve.
* @param X The X coordinate.
* @param Y The Y coordinate.
* @param Z The Z coordinate.
* @param X The $X$ coordinate.
* @param Y The $Y$ coordinate.
* @param Z The $Z$ coordinate.
* @return The group element in P2 representation.
*/
public static GroupElement p2(
@ -71,13 +82,13 @@ public class GroupElement implements Serializable {
}
/**
* Creates a new group element in P3 representation.
* Creates a new group element in P3 representation, without pre-computation.
*
* @param curve The curve.
* @param X The X coordinate.
* @param Y The Y coordinate.
* @param Z The Z coordinate.
* @param T The T coordinate.
* @param X The $X$ coordinate.
* @param Y The $Y$ coordinate.
* @param Z The $Z$ coordinate.
* @param T The $T$ coordinate.
* @return The group element in P3 representation.
*/
public static GroupElement p3(
@ -93,10 +104,10 @@ public class GroupElement implements Serializable {
* Creates a new group element in P3 representation, potentially with pre-computation.
*
* @param curve The curve.
* @param X The X coordinate.
* @param Y The Y coordinate.
* @param Z The Z coordinate.
* @param T The T coordinate.
* @param X The $X$ coordinate.
* @param Y The $Y$ coordinate.
* @param Z The $Z$ coordinate.
* @param T The $T$ coordinate.
* @param precomputeDoubleOnly If true, populate dblPrecmp, else set to null.
* @return The group element in P3 representation.
* @since 0.9.36
@ -115,10 +126,10 @@ public class GroupElement implements Serializable {
* Creates a new group element in P1P1 representation.
*
* @param curve The curve.
* @param X The X coordinate.
* @param Y The Y coordinate.
* @param Z The Z coordinate.
* @param T The T coordinate.
* @param X The $X$ coordinate.
* @param Y The $Y$ coordinate.
* @param Z The $Z$ coordinate.
* @param T The $T$ coordinate.
* @return The group element in P1P1 representation.
*/
public static GroupElement p1p1(
@ -134,9 +145,9 @@ public class GroupElement implements Serializable {
* Creates a new group element in PRECOMP representation.
*
* @param curve The curve.
* @param ypx The y + x value.
* @param ymx The y - x value.
* @param xy2d The 2 * d * x * y value.
* @param ypx The $y + x$ value.
* @param ymx The $y - x$ value.
* @param xy2d The $2 * d * x * y$ value.
* @return The group element in PRECOMP representation.
*/
public static GroupElement precomp(
@ -151,10 +162,10 @@ public class GroupElement implements Serializable {
* Creates a new group element in CACHED representation.
*
* @param curve The curve.
* @param YpX The Y + X value.
* @param YmX The Y - X value.
* @param Z The Z coordinate.
* @param T2d The 2 * d * T value.
* @param YpX The $Y + X$ value.
* @param YmX The $Y - X$ value.
* @param Z The $Z$ coordinate.
* @param T2d The $2 * d * T$ value.
* @return The group element in CACHED representation.
*/
public static GroupElement cached(
@ -217,10 +228,10 @@ public class GroupElement implements Serializable {
*
* @param curve The curve.
* @param repr The representation used to represent the group element.
* @param X The X coordinate.
* @param Y The Y coordinate.
* @param Z The Z coordinate.
* @param T The T coordinate.
* @param X The $X$ coordinate.
* @param Y The $Y$ coordinate.
* @param Z The $Z$ coordinate.
* @param T The $T$ coordinate.
*/
public GroupElement(
final Curve curve,
@ -237,10 +248,10 @@ public class GroupElement implements Serializable {
*
* @param curve The curve.
* @param repr The representation used to represent the group element.
* @param X The X coordinate.
* @param Y The Y coordinate.
* @param Z The Z coordinate.
* @param T The T coordinate.
* @param X The $X$ coordinate.
* @param Y The $Y$ coordinate.
* @param Z The $Z$ coordinate.
* @param T The $T$ coordinate.
* @param precomputeDouble If true, populate dblPrecmp, else set to null.
* @since 0.9.36
*/
@ -263,16 +274,16 @@ public class GroupElement implements Serializable {
}
/**
* Creates a group element for a curve from a given encoded point.
* Creates a group element for a curve from a given encoded point. No pre-computation.
* <p>
* 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:
* </p><ul>
* <li>x = sign(x) * sqrt((y^2 - 1) / (d * y^2 + 1)) = sign(x) * sqrt(u / v) with u = y^2 - 1 and v = d * y^2 + 1.
* <li>Setting = (u * v^3) * (u * v^7)^((q - 5) / 8) one has ^2 = +-(u / v).
* <li>If v * = -u multiply with i=sqrt(-1).
* <li>Set x := .
* <li>If sign(x) != bit 255 of s then negate x.
* <li>$x = sign(x) * \sqrt{(y^2 - 1) / (d * y^2 + 1)} = sign(x) * \sqrt{u / v}$ with $u = y^2 - 1$ and $v = d * y^2 + 1$.
* <li>Setting = (u * v^3) * (u * v^7)^{((q - 5) / 8)}$ one has ^2 = \pm(u / v)$.
* <li>If $v * β = -u$ multiply $β$ with $i=\sqrt{-1}$.
* <li>Set $x := β$.
* <li>If $sign(x) \ne$ bit 255 of $s$ then negate $x$.
* </ul>
*
* @param curve The curve.
@ -285,14 +296,14 @@ public class GroupElement implements Serializable {
/**
* Creates a group element for a curve from a given encoded point. With optional pre-computation.
* <p>
* 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:
* </p><ul>
* <li>x = sign(x) * \sqrt{(y^2 - 1) / (d * y^2 + 1)} = sign(x) * \sqrt{u / v} with u = y^2 - 1 and v = d * y^2 + 1.
* <li>Setting β = (u * v^3) * (u * v^7)^((q - 5) / 8) one has β^2 = +-(u / v).
* <li>If v * β = -u multiply β with i=sqrt(-1).
* <li>Set x := β.
* <li>If sign(x) != bit 255 of s then negate x.
* <li>$x = sign(x) * \sqrt{(y^2 - 1) / (d * y^2 + 1)} = sign(x) * \sqrt{u / v}$ with $u = y^2 - 1$ and $v = d * y^2 + 1$.
* <li>Setting $β = (u * v^3) * (u * v^7)^{((q - 5) / 8)}$ one has $β^2 = \pm(u / v)$.
* <li>If $v * β = -u$ multiply $β$ with $i=\sqrt{-1}$.
* <li>Set $x := β$.
* <li>If $sign(x) \ne$ bit 255 of $s$ then negate $x$.
* </ul>
*
* @param curve The curve.
@ -371,40 +382,40 @@ public class GroupElement implements Serializable {
}
/**
* Gets the X value of the group element.
* This is for most representation the projective X coordinate.
* Gets the $X$ value of the group element.
* This is for most representation the projective $X$ coordinate.
*
* @return The X value.
* @return The $X$ value.
*/
public FieldElement getX() {
return this.X;
}
/**
* Gets the Y value of the group element.
* This is for most representation the projective Y coordinate.
* Gets the $Y$ value of the group element.
* This is for most representation the projective $Y$ coordinate.
*
* @return The Y value.
* @return The $Y$ value.
*/
public FieldElement getY() {
return this.Y;
}
/**
* Gets the Z value of the group element.
* This is for most representation the projective Z coordinate.
* Gets the $Z$ value of the group element.
* This is for most representation the projective $Z$ coordinate.
*
* @return The Z value.
* @return The $Z$ value.
*/
public FieldElement getZ() {
return this.Z;
}
/**
* Gets the T value of the group element.
* This is for most representation the projective T coordinate.
* Gets the $T$ value of the group element.
* This is for most representation the projective $T$ coordinate.
*
* @return The T value.
* @return The $T$ value.
*/
public FieldElement getT() {
return this.T;
@ -470,14 +481,14 @@ public class GroupElement implements Serializable {
/**
* Convert a GroupElement from one Representation to another.
* TODO-CR: Add additional conversion?
* r = p
* $r = p$
* <p>
* Supported conversions:
* </p><ul>
* <li>P3 -> P2
* <li>P3 -> CACHED (1 multiply, 1 add, 1 subtract)
* <li>P1P1 -> P2 (3 multiply)
* <li>P1P1 -> P3 (4 multiply)
* <p><ul>
* <li>P3 $\rightarrow$ P2
* <li>P3 $\rightarrow$ CACHED (1 multiply, 1 add, 1 subtract)
* <li>P1P1 $\rightarrow$ P2 (3 multiply)
* <li>P1P1 $\rightarrow$ P3 (4 multiply)
*
* @param repr The representation to convert to.
* @return A new group element in the given representation.
@ -573,33 +584,35 @@ public class GroupElement implements Serializable {
}
/**
* Doubles a given group element p in P^2 or P^3 representation and returns the result in P x P representation.
* r = 2 * p where p = (X : Y : Z) or p = (X : Y : Z : T)
* Doubles a given group element $p$ in $P^2$ or $P^3$ representation and returns the result in $P \times P$ representation.
* $r = 2 * p$ where $p = (X : Y : Z)$ or $p = (X : Y : Z : T)$
* <p>
* r in P x P representation:
* $r$ in $P \times P$ representation:
* <p>
* r = ((X' : Z'), (Y' : T')) where
* $r = ((X' : Z'), (Y' : T'))$ where
* </p><ul>
* <li>X' = (X + Y)^2 - (Y^2 + X^2)
* <li>Y' = Y^2 + X^2
* <li>Z' = y^2 - X^2
* <li>T' = 2 * Z^2 - (y^2 - X^2)
* <li>$X' = (X + Y)^2 - (Y^2 + X^2)$
* <li>$Y' = Y^2 + X^2$
* <li>$Z' = y^2 - X^2$
* <li>$T' = 2 * Z^2 - (y^2 - X^2)$
* </ul><p>
* r converted from P x P to P^2 representation:
* $r$ converted from $P \times P$ to $P^2$ representation:
* <p>
* r = (X'' : Y'' : Z'') where
* $r = (X'' : Y'' : Z'')$ where
* </p><ul>
* <li>X'' = X' * Z' = ((X + Y)^2 - Y^2 - X^2) * (2 * Z^2 - (y^2 - X^2))
* <li>Y'' = Y' * T' = (Y^2 + X^2) * (2 * Z^2 - (y^2 - X^2))
* <li>Z'' = Z' * T' = (y^2 - X^2) * (2 * Z^2 - (y^2 - X^2))
* <li>$X'' = X' * Z' = ((X + Y)^2 - Y^2 - X^2) * (2 * Z^2 - (y^2 - X^2))$
* <li>$Y'' = Y' * T' = (Y^2 + X^2) * (2 * Z^2 - (y^2 - X^2))$
* <li>$Z'' = Z' * T' = (y^2 - X^2) * (2 * Z^2 - (y^2 - X^2))$
* </ul><p>
* 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:
* <p>
* 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).
* <p>
* 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)$
* <p>
* r in P x P representation:
* $r$ in $P \times P$ representation:
* <p>
* r = ((X' : Z'), (Y' : T')) where
* </p><ul>
* <li>X' = (Y1 + X1) * q.X - (Y1 - X1) * q.Y = ((Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)) * 1/Z2
* <li>Y' = (Y1 + X1) * q.X + (Y1 - X1) * q.Y = ((Y1 + X1) * (Y2 + X2) + (Y1 - X1) * (Y2 - X2)) * 1/Z2
* <li>Z' = 2 * Z1 + T1 * q.Z = 2 * Z1 + T1 * 2 * d * X2 * Y2 * 1/Z2^2 = (2 * Z1 * Z2 + 2 * d * T1 * T2) * 1/Z2
* <li>T' = 2 * Z1 - T1 * q.Z = 2 * Z1 - T1 * 2 * d * X2 * Y2 * 1/Z2^2 = (2 * Z1 * Z2 - 2 * d * T1 * T2) * 1/Z2
* $r = ((X' : Z'), (Y' : T'))$ where
* <p><ul>
* <li>$X' = (Y1 + X1) * q.X - (Y1 - X1) * q.Y = ((Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)) * 1/Z2$
* <li>$Y' = (Y1 + X1) * q.X + (Y1 - X1) * q.Y = ((Y1 + X1) * (Y2 + X2) + (Y1 - X1) * (Y2 - X2)) * 1/Z2$
* <li>$Z' = 2 * Z1 + T1 * q.Z = 2 * Z1 + T1 * 2 * d * X2 * Y2 * 1/Z2^2 = (2 * Z1 * Z2 + 2 * d * T1 * T2) * 1/Z2$
* <li>$T' = 2 * Z1 - T1 * q.Z = 2 * Z1 - T1 * 2 * d * X2 * Y2 * 1/Z2^2 = (2 * Z1 * Z2 - 2 * d * T1 * T2) * 1/Z2$
* </ul><p>
* Setting A = (Y1 - X1) * (Y2 - X2), B = (Y1 + X1) * (Y2 + X2), C = 2 * d * T1 * T2, D = 2 * Z1 * Z2 we get
* </p><ul>
* <li>X' = (B - A) * 1/Z2
* <li>Y' = (B + A) * 1/Z2
* <li>Z' = (D + C) * 1/Z2
* <li>T' = (D - C) * 1/Z2
* Setting $A = (Y1 - X1) * (Y2 - X2), B = (Y1 + X1) * (Y2 + X2), C = 2 * d * T1 * T2, D = 2 * Z1 * Z2$ we get
* <p><ul>
* <li>$X' = (B - A) * 1/Z2$
* <li>$Y' = (B + A) * 1/Z2$
* <li>$Z' = (D + C) * 1/Z2$
* <li>$T' = (D - C) * 1/Z2$
* </ul><p>
* r converted from P x P to P^2 representation:
* $r$ converted from $P \times P$ to $P^2$ representation:
* <p>
* r = (X'' : Y'' : Z'' : T'') where
* </p><ul>
* <li>X'' = X' * Z' = (B - A) * (D + C) * 1/Z2^2
* <li>Y'' = Y' * T' = (B + A) * (D - C) * 1/Z2^2
* <li>Z'' = Z' * T' = (D + C) * (D - C) * 1/Z2^2
* <li>T'' = X' * Y' = (B - A) * (B + A) * 1/Z2^2
* $r = (X'' : Y'' : Z'' : T'')$ where
* <p><ul>
* <li>$X'' = X' * Z' = (B - A) * (D + C) * 1/Z2^2$
* <li>$Y'' = Y' * T' = (B + A) * (D - C) * 1/Z2^2$
* <li>$Z'' = Z' * T' = (D + C) * (D - C) * 1/Z2^2$
* <li>$T'' = X' * Y' = (B - A) * (B + A) * 1/Z2^2$
* </ul><p>
* TODO-CR BR: Formula for the P^2 representation is not in agreement with the formula given in [2] page 6<br>
* TODO-CR BR: (the common factor 1/Z2^2 does not matter):<br>
* E = B - A, F = D - C, G = D + C, H = B + A<br>
* 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<br>
* TODO-CR BR: (the common factor $1/Z2^2$ does not matter):<br>
* $$
* 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).
* <p>
* 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)$
* <p>
* 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).
* <p>
* 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)$
* <p>
* r in P x P representation:
* $r$ in $P \times P$ representation:
* </p><ul>
* <li>X' = (Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)
* <li>Y' = (Y1 + X1) * (Y2 + X2) + (Y1 - X1) * (Y2 - X2)
* <li>Z' = 2 * Z1 * Z2 + 2 * d * T1 * T2
* <li>T' = 2 * Z1 * T2 - 2 * d * T1 * T2
* <li>$X' = (Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)$
* <li>$Y' = (Y1 + X1) * (Y2 + X2) + (Y1 - X1) * (Y2 - X2)$
* <li>$Z' = 2 * Z1 * Z2 + 2 * d * T1 * T2$
* <li>$T' = 2 * Z1 * T2 - 2 * d * T1 * T2$
* </ul><p>
* 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
* </p><ul>
* <li>X' = (B - A)
* <li>Y' = (B + A)
* <li>Z' = (D + C)
* <li>T' = (D - C)
* <li>$X' = (B - A)$
* <li>$Y' = (B + A)$
* <li>$Z' = (D + C)$
* <li>$T' = (D - C)$
* </ul><p>
* 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).
* <p>
* r = p - q
* $r = p - q$
* <p>
* 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.
* <p>
* 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 {
* <p>
* 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.
* <p>
* Replaces this with u if b == 1.<br>
* Replaces this with this if b == 0.
* Replaces this with $u$ if $b == 1$.<br>
* Replaces this with this if $b == 0$.
* <p>
* 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.
* <p>
* No secret array indices, no secret branching.
* Constant time.
@ -903,8 +918,8 @@ public class GroupElement implements Serializable {
* <p>
* 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
* $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.
* <p>
* Preconditions: (TODO: Check this applies here)
* a[31] &lt;= 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.
* <p>
* 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\}$
* <p>
* 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.
* <p>
* 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) {

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math;
import java.io.Serializable;
/**
*
* @since 0.9.15
*
*/
public interface ScalarOps extends Serializable {
/**
* Reduce the given scalar mod l.
* Reduce the given scalar mod $l$.
* <p>
* From the Ed25519 paper:<br>
* 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);
}

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math.bigint;
import java.io.Serializable;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math.bigint;
import java.io.Serializable;
@ -25,10 +36,11 @@ public class BigIntegerLittleEndianEncoding extends Encoding implements Serializ
}
/**
* Convert x to little endian.
* Convert $x$ to little endian.
* Constant time.
*
* @return array of length b/8
* @param x the BigInteger value to encode
* @return array of length $b/8$
* @throws IllegalStateException if field not set
*/
public byte[] encode(BigInteger x) {
@ -46,10 +58,10 @@ public class BigIntegerLittleEndianEncoding extends Encoding implements Serializ
}
/**
* Decode a FieldElement from its (b-1)-bit encoding.
* Decode a FieldElement from its $(b-1)$-bit encoding.
* The highest bit is masked out.
*
* @param in the (b-1)-bit encoding of a FieldElement.
* @param in the $(b-1)$-bit encoding of a FieldElement.
* @return the FieldElement represented by 'val'.
* @throws IllegalStateException if field not set
* @throws IllegalArgumentException if encoding is invalid
@ -64,6 +76,9 @@ public class BigIntegerLittleEndianEncoding extends Encoding implements Serializ
/**
* Convert in to big endian
*
* @param in the $(b-1)$-bit encoding of a FieldElement.
* @return the decoded value as a BigInteger
*/
public BigInteger toBigInteger(byte[] in) {
byte[] out = new byte[in.length];
@ -75,10 +90,10 @@ public class BigIntegerLittleEndianEncoding extends Encoding implements Serializ
/**
* From the Ed25519 paper:<br>
* 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) {

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math.bigint;
import java.math.BigInteger;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math.ed25519;
import net.i2p.crypto.eddsa.Utils;
@ -6,11 +17,11 @@ import net.i2p.crypto.eddsa.math.*;
import java.util.Arrays;
/**
* Class to represent a field element of the finite field p=2^255-19 elements.
* Class to represent a field element of the finite field $p = 2^{255} - 19$ elements.
* <p>
* 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.
* <p>
* 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$
* <p>
* 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?
* <p>
* Preconditions:
* </p><ul>
* <li>|f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
* <li>|g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
* <li>$|f|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc.
* <li>$|g|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc.
* </ul><p>
* Postconditions:
* </p><ul>
* <li>|h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
* <li>$|h|$ bounded by $1.1*2^{26},1.1*2^{25},1.1*2^{26},1.1*2^{25},$ etc.
* </ul>
*
* @param val The field element to add.
@ -73,20 +84,20 @@ public class Ed25519FieldElement extends FieldElement {
}
/**
* h = f - g
* $h = f - g$
* <p>
* Can overlap h with f or g.
* Can overlap $h$ with $f$ or $g$.
* <p>
* TODO-CR BR: See above.
* <p>
* Preconditions:
* </p><ul>
* <li>|f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
* <li>|g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
* <li>$|f|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc.
* <li>$|g|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc.
* </ul><p>
* Postconditions:
* </p><ul>
* <li>|h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
* <li>$|h|$ bounded by $1.1*2^{26},1.1*2^{25},1.1*2^{26},1.1*2^{25},$ etc.
* </ul>
*
* @param val The field element to subtract.
@ -102,17 +113,17 @@ public class Ed25519FieldElement extends FieldElement {
}
/**
* h = -f
* $h = -f$
* <p>
* TODO-CR BR: see above.
* <p>
* Preconditions:
* </p><ul>
* <li>|f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
* <li>$|f|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc.
* </ul><p>
* Postconditions:
* </p><ul>
* <li>|h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
* <li>$|h|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc.
* </ul>
*
* @return The field element (-1) * this.
@ -126,21 +137,21 @@ public class Ed25519FieldElement extends FieldElement {
}
/**
* h = f * g
* $h = f * g$
* <p>
* Can overlap h with f or g.
* Can overlap $h$ with $f$ or $g$.
* <p>
* Preconditions:
* </p><ul>
* <li>|f| bounded by
* 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
* <li>|g| bounded by
* 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
* <li>$|f|$ bounded by
* $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc.
* <li>$|g|$ bounded by
* $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc.
* </ul><p>
* Postconditions:
* </p><ul>
* <li>|h| bounded by
* 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
* <li>$|h|$ bounded by
* $1.01*2^{25},1.01*2^{24},1.01*2^{25},1.01*2^{24},$ etc.
* </ul><p>
* Notes on implementation strategy:
* <p>
@ -377,17 +388,17 @@ public class Ed25519FieldElement extends FieldElement {
}
/**
* h = f * f
* $h = f * f$
* <p>
* Can overlap h with f.
* Can overlap $h$ with $f$.
* <p>
* Preconditions:
* </p><ul>
* <li>|f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
* <li>$|f|$ bounded by $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc.
* </ul><p>
* Postconditions:
* </p><ul>
* <li>|h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
* <li>$|h|$ bounded by $1.01*2^{25},1.01*2^{24},1.01*2^{25},1.01*2^{24},$ etc.
* </ul><p>
* 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$
* <p>
* Can overlap h with f.
* Can overlap $h$ with $f$.
* <p>
* Preconditions:
* </p><ul>
* <li>|f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
* <li>$|f|$ bounded by $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc.
* </ul><p>
* Postconditions:
* </p><ul>
* <li>|h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
* <li>$|h|$ bounded by $1.01*2^{25},1.01*2^{24},1.01*2^{25},1.01*2^{24},$ etc.
* </ul><p>
* See {@link #multiply(FieldElement)} for discussion
* of implementation strategy.
@ -698,7 +709,7 @@ public class Ed25519FieldElement extends FieldElement {
* Invert this field element.
* <p>
* The inverse is found via Fermat's little theorem:<br>
* 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.
* <p>
* 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

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math.ed25519;
import net.i2p.crypto.eddsa.math.*;
@ -9,40 +20,60 @@ import net.i2p.crypto.eddsa.math.*;
*/
public class Ed25519LittleEndianEncoding extends Encoding {
/**
* Encodes a given field element in its 32 byte representation. This is done in TWO steps.
* Step 1: Reduce the value of the field element modulo p.
* Step 2: Convert the field element to the 32 byte representation.
* <p>
* The idea for the modulo p reduction algorithm is as follows:
* <p>
* Assumption:
* </p><ul>
* <li>p = 2^255 - 19
* <li>h = h0 + 2^25 * h1 + 2^(26+25) * h2 + ... + 2^230 * h9 where 0 &lt;= |hi| &lt; 2^27 for all i=0,...,9.
* <li>h congruent r modulo p, i.e. h = r + q * p for some suitable 0 &lt;= r &lt; p and an integer q.
* Encodes a given field element in its 32 byte representation. This is done in two steps:
* <ol>
* <li>Reduce the value of the field element modulo $p$.
* <li>Convert the field element to the 32 byte representation.
* </ol><p>
* The idea for the modulo $p$ reduction algorithm is as follows:
* </p>
* <h2>Assumption:</h2>
* <ul>
* <li>$p = 2^{255} - 19$
* <li>$h = h_0 + 2^{25} * h_1 + 2^{(26+25)} * h_2 + \dots + 2^{230} * h_9$ where $0 \le |h_i| \lt 2^{27}$ for all $i=0,\dots,9$.
* <li>$h \cong r \mod p$, i.e. $h = r + q * p$ for some suitable $0 \le r \lt p$ and an integer $q$.
* </ul><p>
* Then q = [2^-255 * (h + 19 * 2^-25 * h9 + 1/2)] where [x] = floor(x).
* <p>
* Proof:
* Then $q = [2^{-255} * (h + 19 * 2^{-25} * h_9 + 1/2)]$ where $[x] = floor(x)$.
* </p>
* <h2>Proof:</h2>
* <p>
* We begin with some very raw estimation for the bounds of some expressions:
* <pre>|h| &lt; 2^230 * 2^30 = 2^260 ==&gt; |r + q * p| &lt; 2^260 ==&gt; |q| &lt; 2^10.
* ==&gt; -1/4 &lt;= a := 19^2 * 2^-255 * q &lt; 1/4.
* |h - 2^230 * h9| = |h0 + ... + 2^204 * h8| &lt; 2^204 * 2^30 = 2^234.
* ==&gt; -1/4 &lt;= b := 19 * 2^-255 * (h - 2^230 * h9) &lt; 1/4</pre>
* Therefore 0 &lt; 1/2 - a - b &lt; 1.
* <p>
* Set x := r + 19 * 2^-255 * r + 1/2 - a - b then
* 0 &lt;= x &lt; 255 - 20 + 19 + 1 = 2^255 ==&gt; 0 &lt;= 2^-255 * x &lt; 1. Since q is an integer we have
*
* <pre>[q + 2^-255 * x] = q (1)</pre>
* $$
* \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}
* $$
* <p>
* Have a closer look at x:
* <pre>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.</pre>
* Therefore $0 \lt 1/2 - a - b \lt 1$.
* <p>
* 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:
* <p>
* $$
* 0 \le x \lt 255 - 20 + 19 + 1 = 2^{255} \\
* \Rightarrow 0 \le 2^{-255} * x \lt 1.
* $$
* <p>
* Since $q$ is an integer we have
* <p>
* $$
* [q + 2^{-255} * x] = q \quad (1)
* $$
* <p>
* Have a closer look at $x$:
* <p>
* $$
* \begin{align}
* x &amp;= 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) \\
* &amp;= 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 \\
* &amp;= h + 19 * 2^{-25} * h_9 + 1/2 - q^{255}.
* \end{align}
* $$
* <p>
* 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?
* <p>
* Return true if x is in {1,3,5,...,q-2}<br>
* Return false if x is in {0,2,4,...,q-1}
* Return true if $x$ is in $\{1,3,5,\dots,q-2\}$<br>
* Return false if $x$ is in $\{0,2,4,\dots,q-1\}$
* <p>
* Preconditions:
* </p><ul>
* <li>|x| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
* <li>$|x|$ bounded by $1.1*2^{26},1.1*2^{25},1.1*2^{26},1.1*2^{25}$, etc.
* </ul>
*
* @return true if x is in {1,3,5,...,q-2}, false otherwise.
* @return true if $x$ is in $\{1,3,5,\dots,q-2\}$, false otherwise.
*/
public boolean isNegative(FieldElement x) {
byte[] s = encode(x);

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math.ed25519;
import net.i2p.crypto.eddsa.math.ScalarOps;
@ -8,21 +19,21 @@ import static net.i2p.crypto.eddsa.math.ed25519.Ed25519LittleEndianEncoding.load
* Class for reducing a huge integer modulo the group order q and
* doing a combined multiply plus add plus reduce operation.
* <p>
* q = 2^252 + 27742317777372353535851937790883648493.
* $q = 2^{252} + 27742317777372353535851937790883648493$.
* <p>
* 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$.
* <p>
* Input:
* s[0]+256*s[1]+...+256^63*s[63] = s
* $s[0]+256*s[1]+\dots+256^{63}*s[63] = s$
* <p>
* 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$
* <p>
* Input:
* <p><ul>
* <li>a[0]+256*a[1]+...+256^31*a[31] = a
* <li>b[0]+256*b[1]+...+256^31*b[31] = b
* <li>c[0]+256*c[1]+...+256^31*c[31] = c
* </p><ul>
* <li>$a[0]+256*a[1]+\dots+256^{31}*a[31] = a$
* <li>$b[0]+256*b[1]+\dots+256^{31}*b[31] = b$
* <li>$c[0]+256*c[1]+\dots+256^{31}*c[31] = c$
* </ul><p>
* 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$.
* <p>
* See the comments in {@link #reduce(byte[])} for an explanation of the algorithm.
*/

View File

@ -1,6 +1,6 @@
<html><body>
<p>
Low-level, optimized implementation using Radix 2^51 for Curve 25519.
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

@ -4,6 +4,6 @@
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.
and in <a href="ed25519/package-summary.html">ed25519</a> for Curve 25519 using Radix $2^{51}$.
</p>
</body></html>

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.spec;
import java.security.spec.AlgorithmParameterSpec;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.spec;
import net.i2p.crypto.eddsa.math.Curve;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.spec;
import java.util.HashMap;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.spec;
import java.security.MessageDigest;
@ -25,11 +36,11 @@ public class EdDSAParameterSpec implements AlgorithmParameterSpec, Serializable
private final GroupElement B;
/**
* @param curve the curve
* @param hashAlgo the JCA string for the hash algorithm
* @param sc the parameter L represented as ScalarOps
* @param B the parameter B
* @throws IllegalArgumentException if hash algorithm is unsupported or length is wrong
* @param curve the curve
* @param hashAlgo the JCA string for the hash algorithm
* @param sc the parameter L represented as ScalarOps
* @param B the parameter B
* @throws IllegalArgumentException if hash algorithm is unsupported or length is wrong
*/
public EdDSAParameterSpec(Curve curve, String hashAlgo,
ScalarOps sc, GroupElement B) {

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.spec;
import java.security.MessageDigest;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.spec;
import java.security.spec.KeySpec;
@ -12,13 +23,13 @@ import net.i2p.crypto.eddsa.math.GroupElement;
*/
public class EdDSAPublicKeySpec implements KeySpec {
private final GroupElement A;
private GroupElement Aneg;
private GroupElement Aneg = null;
private final EdDSAParameterSpec spec;
/**
* @param pk the public key
* @param spec the parameter specification for this key
* @throws IllegalArgumentException if key length is wrong
* @param pk the public key
* @param spec the parameter specification for this key
* @throws IllegalArgumentException if key length is wrong
*/
public EdDSAPublicKeySpec(byte[] pk, EdDSAParameterSpec spec) {
if (pk.length != spec.getCurve().getField().getb()/8)

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa;
import java.io.BufferedReader;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa;
import static org.hamcrest.Matchers.equalTo;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa;
import org.hamcrest.core.IsEqual;
@ -105,6 +116,11 @@ public class UtilsTest {
assertThat(Utils.bit(new byte[] {1, 2, 3}, 16), is(1));
}
@Test(expected = IllegalArgumentException.class)
public void hexToBytesThrowsOnInvalidLengthHexString() {
Utils.hexToBytes("bad");
}
@Test
public void hexToBytesReturnsCorrectByteArray() {
Assert.assertThat(Utils.hexToBytes(hex1), IsEqual.equalTo(bytes1));

View File

@ -1,6 +1,16 @@
/**
* 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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math;
import net.i2p.crypto.eddsa.math.*;
import org.hamcrest.core.*;
import org.junit.*;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math;
import static org.hamcrest.Matchers.equalTo;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math;
import net.i2p.crypto.eddsa.*;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math;
import net.i2p.crypto.eddsa.Utils;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math;
import java.io.BufferedReader;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math.bigint;
import static org.hamcrest.Matchers.*;

View File

@ -1,4 +1,12 @@
/**
* 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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math.bigint;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math.ed25519;
import net.i2p.crypto.eddsa.math.*;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math.ed25519;
import net.i2p.crypto.eddsa.math.*;

View File

@ -1,4 +1,12 @@
/**
* 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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math.ed25519;

View File

@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.spec;
import static org.hamcrest.Matchers.*;
@ -38,7 +49,7 @@ public class EdDSAPrivateKeySpecTest {
public void incorrectSeedLengthThrows() {
exception.expect(IllegalArgumentException.class);
exception.expectMessage("seed length is wrong");
EdDSAPrivateKeySpec key = new EdDSAPrivateKeySpec(new byte[2], ed25519);
new EdDSAPrivateKeySpec(new byte[2], ed25519);
}
/**
@ -56,6 +67,6 @@ public class EdDSAPrivateKeySpecTest {
public void incorrectHashLengthThrows() {
exception.expect(IllegalArgumentException.class);
exception.expectMessage("hash length is wrong");
EdDSAPrivateKeySpec key = new EdDSAPrivateKeySpec(ed25519, new byte[2]);
new EdDSAPrivateKeySpec(ed25519, new byte[2]);
}
}

View File

@ -1,3 +1,6 @@
2019-08-10 str4d:
* EdDSA: Reduce diff between vendored code and upstream
2019-08-05 zzz
* i2ptunnel:
- Add configs to override user agent

View File

@ -0,0 +1,123 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.
For more information, please see https://creativecommons.org/publicdomain/zero/1.0/