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) Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
See licenses/LICENSE-LGPLv2.1.txt See licenses/LICENSE-LGPLv2.1.txt
EdDSA-Java:
See licenses/LICENSE-CC0-1.0-Universal.txt
HostnameVerifier: HostnameVerifier:
From Apache HttpClient 4.4.1 and HttpCore 4.4.1 From Apache HttpClient 4.4.1 and HttpCore 4.4.1
See licenses/LICENSE-Apache2.0.txt 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; package net.i2p.crypto.eddsa;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -153,7 +164,7 @@ public class EdDSAEngine extends Signature {
} }
} else if (!key.getParams().getHashAlgorithm().equals(digest.getAlgorithm())) } else if (!key.getParams().getHashAlgorithm().equals(digest.getAlgorithm()))
throw new InvalidKeyException("Key hash algorithm does not match chosen digest"); 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 // 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. // key is valid but needs to be instanced as an EdDSAPublicKey before it can be used.
EdDSAPublicKey parsedPublicKey; 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; package net.i2p.crypto.eddsa;
import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec; import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
@ -7,18 +18,17 @@ import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
* *
* @since 0.9.15 * @since 0.9.15
* @author str4d * @author str4d
*
*/ */
public interface EdDSAKey { public interface EdDSAKey {
/** /**
* The reported key algorithm for all EdDSA keys * The reported key algorithm for all EdDSA keys
* @since 0.9.36 * @since 0.9.36
*/ */
public String KEY_ALGORITHM = "EdDSA"; String KEY_ALGORITHM = "EdDSA";
/** /**
* @return a parameter specification representing the EdDSA domain * @return a parameter specification representing the EdDSA domain
* parameters for the key. * 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; package net.i2p.crypto.eddsa;
import java.security.PrivateKey; import java.security.PrivateKey;
@ -12,21 +23,16 @@ import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
/** /**
* An EdDSA private key. * An EdDSA private key.
*<p> * <p>
* Warning: Private key encoding is based on the current curdle WG draft, * For compatibility with older releases, decoding supports both RFC 8410 and an
* and is subject to change. See getEncoded(). * older draft specifications.
*</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>
* *
* @since 0.9.15 * @since 0.9.15
* @author str4d * @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 { public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
private static final long serialVersionUID = 23495873459878957L; private static final long serialVersionUID = 23495873459878957L;
@ -72,62 +78,62 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
/** /**
* Returns the private key in its canonical encoding. * Returns the private key in its canonical encoding.
*<p> * <p>
* This implements the following specs: * This implements the following specs:
*<ul><li> * <ul>
* General encoding: https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 * <li>General encoding: https://tools.ietf.org/html/rfc8410</li>
*</li><li> * <li>Key encoding: https://tools.ietf.org/html/rfc8032</li>
* Key encoding: https://tools.ietf.org/html/rfc8032 * </ul>
*</li></ul> * <p>
*<p> * This encodes the seed. It will return null if constructed from a spec which
* This encodes the seed. It will return null if constructed from * was directly constructed from H, in which case seed is null.
* a spec which was directly constructed from H, in which case seed is null. * <p>
*</p><p>
* For keys in older formats, decoding and then re-encoding is sufficient to * For keys in older formats, decoding and then re-encoding is sufficient to
* migrate them to the canonical encoding. * migrate them to the canonical encoding.
*</p> * <p>
* Relevant spec quotes: * Relevant spec quotes:
*<pre> *
* <pre>
* OneAsymmetricKey ::= SEQUENCE { * OneAsymmetricKey ::= SEQUENCE {
* version Version, * version Version,
* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
* privateKey PrivateKey, * privateKey PrivateKey,
* attributes [0] Attributes OPTIONAL, * attributes [0] IMPLICIT Attributes OPTIONAL,
* ..., * ...,
* [[2: publicKey [1] PublicKey OPTIONAL ]], * [[2: publicKey [1] IMPLICIT PublicKey OPTIONAL ]],
* ... * ...
* } * }
* *
* Version ::= INTEGER * Version ::= INTEGER
* PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
* PrivateKey ::= OCTET STRING * PrivateKey ::= OCTET STRING
* PublicKey ::= OCTET STRING * PublicKey ::= BIT STRING
* Attributes ::= SET OF Attribute * Attributes ::= SET OF Attribute
*</pre> * </pre>
* *
*<pre> * <pre>
* ... when encoding a OneAsymmetricKey object, the private key is wrapped * ... when encoding a OneAsymmetricKey object, the private key is wrapped
* in a CurvePrivateKey object and wrapped by the OCTET STRING of the * in a CurvePrivateKey object and wrapped by the OCTET STRING of the
* 'privateKey' field. * "privateKey" field.
* *
* CurvePrivateKey ::= OCTET STRING * CurvePrivateKey ::= OCTET STRING
*</pre> * </pre>
* *
*<pre> * <pre>
* AlgorithmIdentifier ::= SEQUENCE { * AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER, * algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL * parameters ANY DEFINED BY algorithm OPTIONAL
* } * }
* *
* For all of the OIDs, the parameters MUST be absent. * For all of the OIDs, the parameters MUST be absent.
*</pre> * </pre>
* *
*<pre> * <pre>
* id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 } * id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
*</pre> * </pre>
* *
* @return 48 bytes for Ed25519, null for other curves * @return 48 bytes for Ed25519, null for other curves
* @since implemented in 0.9.25 * @since implemented in 0.9.25
*/ */
@Override @Override
public byte[] getEncoded() { public byte[] getEncoded() {
@ -171,22 +177,20 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
/** /**
* Extracts the private key bytes from the provided encoding. * Extracts the private key bytes from the provided encoding.
*<p> * <p>
* This will decode data conforming to the current spec at * This will decode data conforming to RFC 8410 or as inferred from the older
* https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 * draft spec at https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04.
* or as inferred from the old spec at * <p>
* https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04. * Per RFC 8410 section 3, this function WILL accept a parameter value of
*</p><p> * NULL, as it is required for interoperability with the default Java keystore.
* Contrary to draft-ietf-curdle-pkix-04, it WILL accept a parameter value * Other implementations MUST NOT copy this behaviour from here unless they also
* of NULL, as it is required for interoperability with the default Java * need to read keys from the default Java keystore.
* keystore. Other implementations MUST NOT copy this behaviour from here * <p>
* unless they also need to read keys from the default Java keystore.
*</p><p>
* This is really dumb for now. It does not use a general-purpose ASN.1 decoder. * This is really dumb for now. It does not use a general-purpose ASN.1 decoder.
* See also getEncoded(). * See also getEncoded().
* *
* @return 32 bytes for Ed25519, throws for other curves * @return 32 bytes for Ed25519, throws for other curves
* @since 0.9.25 * @since 0.9.25
*/ */
private static byte[] decode(byte[] d) throws InvalidKeySpecException { private static byte[] decode(byte[] d) throws InvalidKeySpecException {
try { try {
@ -244,13 +248,18 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
} else { } else {
// Handle parameter value of NULL // Handle parameter value of NULL
// //
// Quote https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 : // Quoting RFC 8410 section 3:
// For all of the OIDs, the parameters MUST be absent. // > 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. // > 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 // Java's default keystore puts it in (when decoding as PKCS8 and then
// PKCS8 and then re-encoding to pass on), so we must accept it. // re-encoding to pass on), so we must accept it.
if (idlen == 7) { if (idlen == 7) {
if (d[idx++] != 0x05 || if (d[idx++] != 0x05 ||
d[idx++] != 0) { d[idx++] != 0) {
@ -281,36 +290,36 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
} }
/** /**
* @return will be null if constructed from a spec which was * @return will be null if constructed from a spec which was directly
* directly constructed from H * constructed from H
*/ */
public byte[] getSeed() { public byte[] getSeed() {
return seed; return seed;
} }
/** /**
* @return the hash of the seed * @return the hash of the seed
*/ */
public byte[] getH() { public byte[] getH() {
return h; return h;
} }
/** /**
* @return the private key * @return the private key
*/ */
public byte[] geta() { public byte[] geta() {
return a; return a;
} }
/** /**
* @return the public key * @return the public key
*/ */
public GroupElement getA() { public GroupElement getA() {
return A; return A;
} }
/** /**
* @return the public key * @return the public key
*/ */
public byte[] getAbyte() { public byte[] getAbyte() {
return Abyte; 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; package net.i2p.crypto.eddsa;
import java.security.PublicKey; import java.security.PublicKey;
@ -12,26 +23,21 @@ import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
/** /**
* An EdDSA public key. * An EdDSA public key.
*<p> * <p>
* Warning: Public key encoding is is based on the current curdle WG draft, * For compatibility with older releases, decoding supports both RFC 8410 and an
* and is subject to change. See getEncoded(). * older draft specification.
*</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>
* *
* @since 0.9.15 * @since 0.9.15
* @author str4d * @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 { public class EdDSAPublicKey implements EdDSAKey, PublicKey {
private static final long serialVersionUID = 9837459837498475L; private static final long serialVersionUID = 9837459837498475L;
private final GroupElement A; private final GroupElement A;
private GroupElement Aneg; private GroupElement Aneg = null;
private final byte[] Abyte; private final byte[] Abyte;
private final EdDSAParameterSpec edDsaSpec; private final EdDSAParameterSpec edDsaSpec;
@ -67,19 +73,19 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey {
/** /**
* Returns the public key in its canonical encoding. * Returns the public key in its canonical encoding.
*<p> * <p>
* This implements the following specs: * This implements the following specs:
*<ul><li> * <ul>
* General encoding: https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 * <li>General encoding: https://tools.ietf.org/html/rfc8410</li>
*</li><li> * <li>Key encoding: https://tools.ietf.org/html/rfc8032</li>
* Key encoding: https://tools.ietf.org/html/rfc8032 * </ul>
*</li></ul> * <p>
*<p>
* For keys in older formats, decoding and then re-encoding is sufficient to * For keys in older formats, decoding and then re-encoding is sufficient to
* migrate them to the canonical encoding. * migrate them to the canonical encoding.
*</p> * <p>
* Relevant spec quotes: * Relevant spec quotes:
*<pre> *
* <pre>
* In the X.509 certificate, the subjectPublicKeyInfo field has the * In the X.509 certificate, the subjectPublicKeyInfo field has the
* SubjectPublicKeyInfo type, which has the following ASN.1 syntax: * SubjectPublicKeyInfo type, which has the following ASN.1 syntax:
* *
@ -87,23 +93,23 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey {
* algorithm AlgorithmIdentifier, * algorithm AlgorithmIdentifier,
* subjectPublicKey BIT STRING * subjectPublicKey BIT STRING
* } * }
*</pre> * </pre>
* *
*<pre> * <pre>
* AlgorithmIdentifier ::= SEQUENCE { * AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER, * algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL * parameters ANY DEFINED BY algorithm OPTIONAL
* } * }
* *
* For all of the OIDs, the parameters MUST be absent. * For all of the OIDs, the parameters MUST be absent.
*</pre> * </pre>
* *
*<pre> * <pre>
* id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 } * id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
*</pre> * </pre>
* *
* @return 44 bytes for Ed25519, null for other curves * @return 44 bytes for Ed25519, null for other curves
* @since implemented in 0.9.25 * @since implemented in 0.9.25
*/ */
@Override @Override
public byte[] getEncoded() { public byte[] getEncoded() {
@ -137,23 +143,20 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey {
/** /**
* Extracts the public key bytes from the provided encoding. * Extracts the public key bytes from the provided encoding.
*<p> * <p>
* This will decode data conforming to the current spec at * This will decode data conforming to RFC 8410 or the older draft spec at
* https://tools.ietf.org/html/draft-ietf-curdle-pkix-04
* or the old spec at
* https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04. * https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04.
*</p><p> * <p>
* Contrary to draft-ietf-curdle-pkix-04, it WILL accept a parameter value * Per RFC 8410 section 3, this function WILL accept a parameter value of
* of NULL, as it is required for interoperability with the default Java * NULL, as it is required for interoperability with the default Java keystore.
* keystore. Other implementations MUST NOT copy this behaviour from here * Other implementations MUST NOT copy this behaviour from here unless they also
* unless they also need to read keys from the default Java keystore. * need to read keys from the default Java keystore.
*</p><p> * <p>
* This is really dumb for now. It does not use a general-purpose ASN.1 decoder. * This is really dumb for now. It does not use a general-purpose ASN.1 decoder.
* See also getEncoded(). * See also getEncoded().
*</p>
* *
* @return 32 bytes for Ed25519, throws for other curves * @return 32 bytes for Ed25519, throws for other curves
* @since 0.9.25 * @since 0.9.25
*/ */
private static byte[] decode(byte[] d) throws InvalidKeySpecException { private static byte[] decode(byte[] d) throws InvalidKeySpecException {
try { try {
@ -208,13 +211,18 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey {
} else { } else {
// Handle parameter value of NULL // Handle parameter value of NULL
// //
// Quote https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 : // Quoting RFC 8410 section 3:
// For all of the OIDs, the parameters MUST be absent. // > 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. // > 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 // Java's default keystore puts it in (when decoding as PKCS8 and then
// PKCS8 and then re-encoding to pass on), so we must accept it. // re-encoding to pass on), so we must accept it.
if (idlen == 7) { if (idlen == 7) {
if (d[idx++] != 0x05 || if (d[idx++] != 0x05 ||
d[idx++] != 0) { d[idx++] != 0) {
@ -245,7 +253,8 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey {
} }
public GroupElement getNegativeA() { 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; GroupElement ourAneg = Aneg;
if(ourAneg == null) { if(ourAneg == null) {
ourAneg = A.negate(); 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; package net.i2p.crypto.eddsa;
import java.security.InvalidKeyException; 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; package net.i2p.crypto.eddsa;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
@ -32,7 +43,7 @@ public class KeyPairGenerator extends KeyPairGeneratorSpi {
static { static {
edParameters = new Hashtable<Integer, AlgorithmParameterSpec>(); 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) { 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; package net.i2p.crypto.eddsa;
/** /**
@ -65,6 +76,9 @@ public class Utils {
*/ */
public static byte[] hexToBytes(String s) { public static byte[] hexToBytes(String s) {
int len = s.length(); int len = s.length();
if (len % 2 != 0) {
throw new IllegalArgumentException("Hex string must have an even length");
}
byte[] data = new byte[len / 2]; byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) { for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 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; package net.i2p.crypto.eddsa.math;
import net.i2p.crypto.eddsa.Utils; 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; package net.i2p.crypto.eddsa.math;
import java.io.Serializable; import java.io.Serializable;
/** /**
* A twisted Edwards curve. * 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 * @since 0.9.15
* @author str4d * @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; package net.i2p.crypto.eddsa.math;
import java.io.Serializable; 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. * of EdDSA finite fields.
* *
* @since 0.9.15 * @since 0.9.15
@ -20,25 +31,27 @@ public abstract class Encoding implements Serializable {
} }
/** /**
* Encode a FieldElement in its (b-1)-bit encoding. * Encode a FieldElement in its $(b-1)$-bit encoding.
* @return the (b-1)-bit encoding of this FieldElement. * @param x the FieldElement to encode
* @return the $(b-1)$-bit encoding of this FieldElement.
*/ */
public abstract byte[] encode(FieldElement x); 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. * 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'. * @return the FieldElement represented by 'val'.
*/ */
public abstract FieldElement decode(byte[] in); public abstract FieldElement decode(byte[] in);
/** /**
* From the Ed25519 paper:<br> * From the Ed25519 paper:<br>
* x is negative if the (b-1)-bit encoding of x is lexicographically larger * $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 * 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 * is the little-endian representation of $\{0, 1,\dots, q-1\}$ then the negative
* elements of F_q are {1, 3, 5,..., q-2}. * elements of $F_q$ are $\{1, 3, 5,\dots, q-2\}$.
* @param x the FieldElement to check
* @return true if negative * @return true if negative
*/ */
public abstract boolean isNegative(FieldElement x); 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; package net.i2p.crypto.eddsa.math;
import java.io.Serializable; 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; package net.i2p.crypto.eddsa.math;
import java.io.Serializable; import java.io.Serializable;
/** /**
*
* Note: concrete subclasses must implement hashCode() and equals() * Note: concrete subclasses must implement hashCode() and equals()
* *
* @since 0.9.15 * @since 0.9.15
*
*/ */
public abstract class FieldElement implements Serializable { public abstract class FieldElement implements Serializable {
private static final long serialVersionUID = 1239527465875676L; 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. * Encode a FieldElement in its $(b-1)$-bit encoding.
* @return the (b-1)-bit encoding of this FieldElement. * @return the $(b-1)$-bit encoding of this FieldElement.
*/ */
public byte[] toByteArray() { public byte[] toByteArray() {
return f.getEncoding().encode(this); 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; package net.i2p.crypto.eddsa.math;
import net.i2p.crypto.eddsa.Utils; import net.i2p.crypto.eddsa.Utils;
@ -6,7 +17,7 @@ import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
/** /**
* A point (x,y) on an EdDSA curve. * A point $(x,y)$ on an EdDSA curve.
* <p> * <p>
* Reviewed/commented by Bloody Rookie (nemproject@gmx.de) * Reviewed/commented by Bloody Rookie (nemproject@gmx.de)
* <p> * <p>
@ -20,36 +31,36 @@ import java.util.Arrays;
* *
* @since 0.9.15 * @since 0.9.15
* @author str4d * @author str4d
*
*/ */
public class GroupElement implements Serializable { public class GroupElement implements Serializable {
private static final long serialVersionUID = 2395879087349587L; private static final long serialVersionUID = 2395879087349587L;
/** /**
* Available representations for a group element. * Available representations for a group element.
* <p><ul> * <ul>
* <li>P2: Projective representation (X:Y:Z) satisfying x=X/Z, y=Y/Z. * <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>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>P3PrecomputedDouble: P3 but with dblPrecmp populated.
* <li>PRECOMP: Precomputed representation (y+x, y-x, 2dxy). * <li>P1P1: Completed representation $((X:Z), (Y:T))$ satisfying $x=X/Z, y=Y/T$.
* <li>CACHED: Cached representation (Y+X, Y-X, Z, 2dT) * <li>PRECOMP: Precomputed representation $(y+x, y-x, 2dxy)$.
* <li>CACHED: Cached representation $(Y+X, Y-X, Z, 2dT)$
* </ul> * </ul>
*/ */
public enum Representation { 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, 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, P3,
/** /**
* Can only be requested. Results in P3 representation but also populates dblPrecmp. * Can only be requested. Results in P3 representation but also populates dblPrecmp.
* @since 0.9.36 * @since 0.9.36
*/ */
P3PrecomputedDouble, 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, P1P1,
/** Precomputed (Duif): (y+x,y-x,2dxy) */ /** Precomputed (Duif): $(y+x,y-x,2dxy)$ */
PRECOMP, PRECOMP,
/** Cached: (Y+X,Y-X,Z,2dT) */ /** Cached: $(Y+X,Y-X,Z,2dT)$ */
CACHED CACHED
} }
@ -57,9 +68,9 @@ public class GroupElement implements Serializable {
* Creates a new group element in P2 representation. * Creates a new group element in P2 representation.
* *
* @param curve The curve. * @param curve The curve.
* @param X The X coordinate. * @param X The $X$ coordinate.
* @param Y The Y coordinate. * @param Y The $Y$ coordinate.
* @param Z The Z coordinate. * @param Z The $Z$ coordinate.
* @return The group element in P2 representation. * @return The group element in P2 representation.
*/ */
public static GroupElement p2( 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 curve The curve.
* @param X The X coordinate. * @param X The $X$ coordinate.
* @param Y The Y coordinate. * @param Y The $Y$ coordinate.
* @param Z The Z coordinate. * @param Z The $Z$ coordinate.
* @param T The T coordinate. * @param T The $T$ coordinate.
* @return The group element in P3 representation. * @return The group element in P3 representation.
*/ */
public static GroupElement p3( 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. * Creates a new group element in P3 representation, potentially with pre-computation.
* *
* @param curve The curve. * @param curve The curve.
* @param X The X coordinate. * @param X The $X$ coordinate.
* @param Y The Y coordinate. * @param Y The $Y$ coordinate.
* @param Z The Z coordinate. * @param Z The $Z$ coordinate.
* @param T The T coordinate. * @param T The $T$ coordinate.
* @param precomputeDoubleOnly If true, populate dblPrecmp, else set to null. * @param precomputeDoubleOnly If true, populate dblPrecmp, else set to null.
* @return The group element in P3 representation. * @return The group element in P3 representation.
* @since 0.9.36 * @since 0.9.36
@ -115,10 +126,10 @@ public class GroupElement implements Serializable {
* Creates a new group element in P1P1 representation. * Creates a new group element in P1P1 representation.
* *
* @param curve The curve. * @param curve The curve.
* @param X The X coordinate. * @param X The $X$ coordinate.
* @param Y The Y coordinate. * @param Y The $Y$ coordinate.
* @param Z The Z coordinate. * @param Z The $Z$ coordinate.
* @param T The T coordinate. * @param T The $T$ coordinate.
* @return The group element in P1P1 representation. * @return The group element in P1P1 representation.
*/ */
public static GroupElement p1p1( public static GroupElement p1p1(
@ -134,9 +145,9 @@ public class GroupElement implements Serializable {
* Creates a new group element in PRECOMP representation. * Creates a new group element in PRECOMP representation.
* *
* @param curve The curve. * @param curve The curve.
* @param ypx The y + x value. * @param ypx The $y + x$ value.
* @param ymx The y - x value. * @param ymx The $y - x$ value.
* @param xy2d The 2 * d * x * y value. * @param xy2d The $2 * d * x * y$ value.
* @return The group element in PRECOMP representation. * @return The group element in PRECOMP representation.
*/ */
public static GroupElement precomp( public static GroupElement precomp(
@ -151,10 +162,10 @@ public class GroupElement implements Serializable {
* Creates a new group element in CACHED representation. * Creates a new group element in CACHED representation.
* *
* @param curve The curve. * @param curve The curve.
* @param YpX The Y + X value. * @param YpX The $Y + X$ value.
* @param YmX The Y - X value. * @param YmX The $Y - X$ value.
* @param Z The Z coordinate. * @param Z The $Z$ coordinate.
* @param T2d The 2 * d * T value. * @param T2d The $2 * d * T$ value.
* @return The group element in CACHED representation. * @return The group element in CACHED representation.
*/ */
public static GroupElement cached( public static GroupElement cached(
@ -217,10 +228,10 @@ public class GroupElement implements Serializable {
* *
* @param curve The curve. * @param curve The curve.
* @param repr The representation used to represent the group element. * @param repr The representation used to represent the group element.
* @param X The X coordinate. * @param X The $X$ coordinate.
* @param Y The Y coordinate. * @param Y The $Y$ coordinate.
* @param Z The Z coordinate. * @param Z The $Z$ coordinate.
* @param T The T coordinate. * @param T The $T$ coordinate.
*/ */
public GroupElement( public GroupElement(
final Curve curve, final Curve curve,
@ -237,10 +248,10 @@ public class GroupElement implements Serializable {
* *
* @param curve The curve. * @param curve The curve.
* @param repr The representation used to represent the group element. * @param repr The representation used to represent the group element.
* @param X The X coordinate. * @param X The $X$ coordinate.
* @param Y The Y coordinate. * @param Y The $Y$ coordinate.
* @param Z The Z coordinate. * @param Z The $Z$ coordinate.
* @param T The T coordinate. * @param T The $T$ coordinate.
* @param precomputeDouble If true, populate dblPrecmp, else set to null. * @param precomputeDouble If true, populate dblPrecmp, else set to null.
* @since 0.9.36 * @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> * <p>
* A point (x,y) is encoded by storing y in bit 0 to bit 254 and the sign of x in bit 255. * 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: * $x$ is recovered in the following way:
* </p><ul> * </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>$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>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>If $v * β = -u$ multiply $β$ with $i=\sqrt{-1}$.
* <li>Set x := . * <li>Set $x := β$.
* <li>If sign(x) != bit 255 of s then negate x. * <li>If $sign(x) \ne$ bit 255 of $s$ then negate $x$.
* </ul> * </ul>
* *
* @param curve The curve. * @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. * Creates a group element for a curve from a given encoded point. With optional pre-computation.
* <p> * <p>
* A point (x,y) is encoded by storing y in bit 0 to bit 254 and the sign of x in bit 255. * 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: * $x$ is recovered in the following way:
* </p><ul> * </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>$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>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>If $v * β = -u$ multiply $β$ with $i=\sqrt{-1}$.
* <li>Set x := β. * <li>Set $x := β$.
* <li>If sign(x) != bit 255 of s then negate x. * <li>If $sign(x) \ne$ bit 255 of $s$ then negate $x$.
* </ul> * </ul>
* *
* @param curve The curve. * @param curve The curve.
@ -305,7 +316,7 @@ public class GroupElement implements Serializable {
y = curve.getField().fromByteArray(s); y = curve.getField().fromByteArray(s);
yy = y.square(); yy = y.square();
// u = y^2-1 // u = y^2-1
u = yy.subtractOne(); u = yy.subtractOne();
// v = dy^2+1 // v = dy^2+1
@ -371,40 +382,40 @@ public class GroupElement implements Serializable {
} }
/** /**
* Gets the X value of the group element. * Gets the $X$ value of the group element.
* This is for most representation the projective X coordinate. * This is for most representation the projective $X$ coordinate.
* *
* @return The X value. * @return The $X$ value.
*/ */
public FieldElement getX() { public FieldElement getX() {
return this.X; return this.X;
} }
/** /**
* Gets the Y value of the group element. * Gets the $Y$ value of the group element.
* This is for most representation the projective Y coordinate. * This is for most representation the projective $Y$ coordinate.
* *
* @return The Y value. * @return The $Y$ value.
*/ */
public FieldElement getY() { public FieldElement getY() {
return this.Y; return this.Y;
} }
/** /**
* Gets the Z value of the group element. * Gets the $Z$ value of the group element.
* This is for most representation the projective Z coordinate. * This is for most representation the projective $Z$ coordinate.
* *
* @return The Z value. * @return The $Z$ value.
*/ */
public FieldElement getZ() { public FieldElement getZ() {
return this.Z; return this.Z;
} }
/** /**
* Gets the T value of the group element. * Gets the $T$ value of the group element.
* This is for most representation the projective T coordinate. * This is for most representation the projective $T$ coordinate.
* *
* @return The T value. * @return The $T$ value.
*/ */
public FieldElement getT() { public FieldElement getT() {
return this.T; return this.T;
@ -470,14 +481,14 @@ public class GroupElement implements Serializable {
/** /**
* Convert a GroupElement from one Representation to another. * Convert a GroupElement from one Representation to another.
* TODO-CR: Add additional conversion? * TODO-CR: Add additional conversion?
* r = p * $r = p$
* <p> * <p>
* Supported conversions: * Supported conversions:
* </p><ul> * <p><ul>
* <li>P3 -> P2 * <li>P3 $\rightarrow$ P2
* <li>P3 -> CACHED (1 multiply, 1 add, 1 subtract) * <li>P3 $\rightarrow$ CACHED (1 multiply, 1 add, 1 subtract)
* <li>P1P1 -> P2 (3 multiply) * <li>P1P1 $\rightarrow$ P2 (3 multiply)
* <li>P1P1 -> P3 (4 multiply) * <li>P1P1 $\rightarrow$ P3 (4 multiply)
* *
* @param repr The representation to convert to. * @param repr The representation to convert to.
* @return A new group element in the given representation. * @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. * 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) * $r = 2 * p$ where $p = (X : Y : Z)$ or $p = (X : Y : Z : T)$
* <p> * <p>
* r in P x P representation: * $r$ in $P \times P$ representation:
* <p> * <p>
* r = ((X' : Z'), (Y' : T')) where * $r = ((X' : Z'), (Y' : T'))$ where
* </p><ul> * </p><ul>
* <li>X' = (X + Y)^2 - (Y^2 + X^2) * <li>$X' = (X + Y)^2 - (Y^2 + X^2)$
* <li>Y' = Y^2 + X^2 * <li>$Y' = Y^2 + X^2$
* <li>Z' = y^2 - X^2 * <li>$Z' = y^2 - X^2$
* <li>T' = 2 * Z^2 - (y^2 - X^2) * <li>$T' = 2 * Z^2 - (y^2 - X^2)$
* </ul><p> * </ul><p>
* r converted from P x P to P^2 representation: * $r$ converted from $P \times P$ to $P^2$ representation:
* <p> * <p>
* r = (X'' : Y'' : Z'') where * $r = (X'' : Y'' : Z'')$ where
* </p><ul> * </p><ul>
* <li>X'' = X' * Z' = ((X + Y)^2 - 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>$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>$Z'' = Z' * T' = (y^2 - X^2) * (2 * Z^2 - (y^2 - X^2))$
* </ul><p> * </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: * up to a common factor -1 which does not matter:
* <p> * <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'); * 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; \\
* Y3 = F · (E D) = Z' * (-Y'); * X3 = (B C D) · J = X' * (-T'); \\
* Y3 = F · (E D) = Z' * (-Y'); \\
* Z3 = F · J = Z' * (-T'). * Z3 = F · J = Z' * (-T').
* $$
* *
* @return The P1P1 representation * @return The P1P1 representation
*/ */
@ -625,41 +638,43 @@ public class GroupElement implements Serializable {
* GroupElement addition using the twisted Edwards addition law with * GroupElement addition using the twisted Edwards addition law with
* extended coordinates (Hisil2008). * extended coordinates (Hisil2008).
* <p> * <p>
* this must be in P^3 representation and q in PRECOMP representation. * 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 = 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> * <p>
* r in P x P representation: * $r$ in $P \times P$ representation:
* <p> * <p>
* r = ((X' : Z'), (Y' : T')) where * $r = ((X' : Z'), (Y' : T'))$ where
* </p><ul> * <p><ul>
* <li>X' = (Y1 + X1) * q.X - (Y1 - X1) * q.Y = ((Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)) * 1/Z2 * <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>$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>$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 * <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> * </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> * <p><ul>
* <li>X' = (B - A) * 1/Z2 * <li>$X' = (B - A) * 1/Z2$
* <li>Y' = (B + A) * 1/Z2 * <li>$Y' = (B + A) * 1/Z2$
* <li>Z' = (D + C) * 1/Z2 * <li>$Z' = (D + C) * 1/Z2$
* <li>T' = (D - C) * 1/Z2 * <li>$T' = (D - C) * 1/Z2$
* </ul><p> * </ul><p>
* r converted from P x P to P^2 representation: * $r$ converted from $P \times P$ to $P^2$ representation:
* <p> * <p>
* r = (X'' : Y'' : Z'' : T'') where * $r = (X'' : Y'' : Z'' : T'')$ where
* </p><ul> * <p><ul>
* <li>X'' = X' * Z' = (B - A) * (D + C) * 1/Z2^2 * <li>$X'' = X' * Z' = (B - A) * (D + C) * 1/Z2^2$
* <li>Y'' = Y' * T' = (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>$Z'' = Z' * T' = (D + C) * (D - C) * 1/Z2^2$
* <li>T'' = X' * Y' = (B - A) * (B + A) * 1/Z2^2 * <li>$T'' = X' * Y' = (B - A) * (B + A) * 1/Z2^2$
* </ul><p> * </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: 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> * 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); * E = B - A, F = D - C, G = D + C, H = B + A \\
* Y3 = G * H = (D + C) * (B + A); * X3 = E * F = (B - A) * (D - C); \\
* Z3 = F * G = (D - C) * (D + C); * Y3 = G * H = (D + C) * (B + A); \\
* Z3 = F * G = (D - C) * (D + C); \\
* T3 = E * H = (B - A) * (B + A); * T3 = E * H = (B - A) * (B + A);
* $$
* *
* @param q the PRECOMP representation of the GroupElement to add. * @param q the PRECOMP representation of the GroupElement to add.
* @return the P1P1 representation of the result. * @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 * GroupElement subtraction using the twisted Edwards addition law with
* extended coordinates (Hisil2008). * extended coordinates (Hisil2008).
* <p> * <p>
* this must be in P^3 representation and q in PRECOMP representation. * 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 = 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> * <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}. * The formula is in accordance to {@link #madd the above addition}.
* *
* @param q the PRECOMP representation of the GroupElement to subtract. * @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 * GroupElement addition using the twisted Edwards addition law with
* extended coordinates (Hisil2008). * extended coordinates (Hisil2008).
* <p> * <p>
* this must be in P^3 representation and q in CACHED representation. * 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 = 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> * <p>
* r in P x P representation: * $r$ in $P \times P$ representation:
* </p><ul> * </p><ul>
* <li>X' = (Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2) * <li>$X' = (Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)$
* <li>Y' = (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>$Z' = 2 * Z1 * Z2 + 2 * d * T1 * T2$
* <li>T' = 2 * Z1 * T2 - 2 * d * T1 * T2 * <li>$T' = 2 * Z1 * T2 - 2 * d * T1 * T2$
* </ul><p> * </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> * </p><ul>
* <li>X' = (B - A) * <li>$X' = (B - A)$
* <li>Y' = (B + A) * <li>$Y' = (B + A)$
* <li>Z' = (D + C) * <li>$Z' = (D + C)$
* <li>T' = (D - C) * <li>$T' = (D - C)$
* </ul><p> * </ul><p>
* Same result as in {@link #madd} (up to a common factor which does not matter). * 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 * GroupElement subtraction using the twisted Edwards addition law with
* extended coordinates (Hisil2008). * extended coordinates (Hisil2008).
* <p> * <p>
* r = p - q * $r = p - q$
* <p> * <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}. * The formula is in accordance to {@link #add the above addition}.
* *
* @param q the PRECOMP representation of the GroupElement to subtract. * @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. * Negates this group element by subtracting it from the neutral group element.
* <p> * <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. * @return The negative of this group element.
*/ */
@ -852,7 +867,7 @@ public class GroupElement implements Serializable {
* <p> * <p>
* Method is package private only so that tests run. * 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 * @return 64 bytes, each between -8 and 7
*/ */
static byte[] toRadix16(final byte[] a) { static byte[] toRadix16(final byte[] a) {
@ -880,21 +895,21 @@ public class GroupElement implements Serializable {
/** /**
* Constant-time conditional move. * Constant-time conditional move.
* <p> * <p>
* Replaces this with u if b == 1.<br> * Replaces this with $u$ if $b == 1$.<br>
* Replaces this with this if b == 0. * Replaces this with this if $b == 0$.
* <p> * <p>
* Method is package private only so that tests run. * Method is package private only so that tests run.
* *
* @param u The group element to return if b == 1. * @param u The group element to return if $b == 1$.
* @param b in {0, 1} * @param b in $\{0, 1\}$
* @return u if b == 1; this if b == 0; Results undefined if b is not 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) { 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)); 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> * <p>
* No secret array indices, no secret branching. * No secret array indices, no secret branching.
* Constant time. * Constant time.
@ -903,8 +918,8 @@ public class GroupElement implements Serializable {
* <p> * <p>
* Method is package private only so that tests run. * Method is package private only so that tests run.
* *
* @param pos = i/2 for i in {0, 2, 4,..., 62} * @param pos $= i/2$ for $i$ in $\{0, 2, 4,..., 62\}$
* @param b = r_i * @param b $= r_i$
* @return the GroupElement * @return the GroupElement
*/ */
GroupElement select(final int pos, final int b) { 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 * $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 * $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). * will be at the start of the method (and cached for later calls).
* Constant time. * Constant time.
* <p> * <p>
* Preconditions: (TODO: Check this applies here) * Preconditions: (TODO: Check this applies here)
* a[31] &lt;= 127 * $a[31] \le 127$
* @param a = a[0]+256*a[1]+...+256^31 a[31] * @param a $= a[0]+256*a[1]+\dots+256^{31} a[31]$
* @return the GroupElement * @return the GroupElement
*/ */
public GroupElement scalarMultiply(final byte[] a) { 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. * To learn more about it see [6] page 8.
* <p> * <p>
* Output: r which satisfies * 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} * $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> * <p>
* Method is package private only so that tests run. * 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]+\dots+256^{31} a[31]$.
* @return The byte array r in the above described form. * @return The byte array $r$ in the above described form.
*/ */
static byte[] slide(final byte[] a) { static byte[] slide(final byte[] a) {
byte[] r = new byte[256]; 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], * $r = a * A + b * B$ where $a = a[0]+256*a[1]+\dots+256^{31} a[31]$,
* b = b[0]+256*b[1]+...+256^31 b[31] and B is this point. * $b = b[0]+256*b[1]+\dots+256^{31} b[31]$ and $B$ is this point.
* <p> * <p>
* A must have been previously precomputed. * $A$ must have been previously precomputed.
* *
* @param A in P3 representation. * @param A in P3 representation.
* @param a = a[0]+256*a[1]+...+256^31 a[31] * @param a $= a[0]+256*a[1]+\dots+256^{31} a[31]$
* @param b = b[0]+256*b[1]+...+256^31 b[31] * @param b $= b[0]+256*b[1]+\dots+256^{31} b[31]$
* @return the GroupElement * @return the GroupElement
*/ */
public GroupElement doubleScalarMultiplyVariableTime(final GroupElement A, final byte[] a, final byte[] b) { 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; package net.i2p.crypto.eddsa.math;
import java.io.Serializable; import java.io.Serializable;
/** /**
*
* @since 0.9.15 * @since 0.9.15
*
*/ */
public interface ScalarOps extends Serializable { public interface ScalarOps extends Serializable {
/** /**
* Reduce the given scalar mod l. * Reduce the given scalar mod $l$.
* <p> * <p>
* From the Ed25519 paper:<br> * From the Ed25519 paper:<br>
* Here we interpret 2b-bit strings in little-endian form as integers in * Here we interpret $2b$-bit strings in little-endian form as integers in
* {0, 1,..., 2^(2b)-1}. * $\{0, 1,..., 2^{(2b)}-1\}$.
* @param s * @param s the scalar to reduce
* @return s mod l * @return $s \bmod l$
*/ */
public byte[] reduce(byte[] s); public byte[] reduce(byte[] s);
/** /**
* r = (a * b + c) mod l * $r = (a * b + c) \bmod l$
* @param a * @param a a scalar
* @param b * @param b a scalar
* @param c * @param c a scalar
* @return (a*b + c) mod l * @return $(a*b + c) \bmod l$
*/ */
public byte[] multiplyAndAdd(byte[] a, byte[] b, byte[] c); 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; package net.i2p.crypto.eddsa.math.bigint;
import java.io.Serializable; 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; package net.i2p.crypto.eddsa.math.bigint;
import java.io.Serializable; 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. * 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 * @throws IllegalStateException if field not set
*/ */
public byte[] encode(BigInteger x) { 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. * 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'. * @return the FieldElement represented by 'val'.
* @throws IllegalStateException if field not set * @throws IllegalStateException if field not set
* @throws IllegalArgumentException if encoding is invalid * @throws IllegalArgumentException if encoding is invalid
@ -64,6 +76,9 @@ public class BigIntegerLittleEndianEncoding extends Encoding implements Serializ
/** /**
* Convert in to big endian * 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) { public BigInteger toBigInteger(byte[] in) {
byte[] out = new byte[in.length]; byte[] out = new byte[in.length];
@ -75,10 +90,10 @@ public class BigIntegerLittleEndianEncoding extends Encoding implements Serializ
/** /**
* From the Ed25519 paper:<br> * From the Ed25519 paper:<br>
* x is negative if the (b-1)-bit encoding of x is lexicographically larger * $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 * 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 * is the little-endian representation of $\{0, 1,\dots, q-1\}$ then the negative
* elements of F_q are {1, 3, 5,..., q-2}. * elements of $F_q$ are $\{1, 3, 5,\dots, q-2\}$.
* @return true if negative * @return true if negative
*/ */
public boolean isNegative(FieldElement x) { 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; package net.i2p.crypto.eddsa.math.bigint;
import java.math.BigInteger; 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; package net.i2p.crypto.eddsa.math.ed25519;
import net.i2p.crypto.eddsa.Utils; import net.i2p.crypto.eddsa.Utils;
@ -6,11 +17,11 @@ import net.i2p.crypto.eddsa.math.*;
import java.util.Arrays; 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> * <p>
* An element t, entries t[0]...t[9], represents the integer * 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]+...+2^230 t[9]. * $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. * Bounds on each $t[i]$ vary depending on context.
* <p> * <p>
* Reviewed/commented by Bloody Rookie (nemproject@gmx.de) * Reviewed/commented by Bloody Rookie (nemproject@gmx.de)
*/ */
@ -23,8 +34,8 @@ public class Ed25519FieldElement extends FieldElement {
/** /**
* Creates a field element. * Creates a field element.
* *
* @param f The underlying field, must be the finite field with p = 2^255 - 19 elements * @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 t The $2^{25.5}$ bit representation of the field element.
*/ */
public Ed25519FieldElement(Field f, int[] t) { public Ed25519FieldElement(Field f, int[] t) {
super(f); super(f);
@ -46,18 +57,18 @@ public class Ed25519FieldElement extends FieldElement {
} }
/** /**
* h = f + g * $h = f + g$
* <p> * <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> * <p>
* Preconditions: * Preconditions:
* </p><ul> * </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.
* <li>|g| 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> * </ul><p>
* Postconditions: * Postconditions:
* </p><ul> * </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> * </ul>
* *
* @param val The field element to add. * @param val The field element to add.
@ -73,20 +84,20 @@ public class Ed25519FieldElement extends FieldElement {
} }
/** /**
* h = f - g * $h = f - g$
* <p> * <p>
* Can overlap h with f or g. * Can overlap $h$ with $f$ or $g$.
* <p> * <p>
* TODO-CR BR: See above. * TODO-CR BR: See above.
* <p> * <p>
* Preconditions: * Preconditions:
* </p><ul> * </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.
* <li>|g| 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> * </ul><p>
* Postconditions: * Postconditions:
* </p><ul> * </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> * </ul>
* *
* @param val The field element to subtract. * @param val The field element to subtract.
@ -102,17 +113,17 @@ public class Ed25519FieldElement extends FieldElement {
} }
/** /**
* h = -f * $h = -f$
* <p> * <p>
* TODO-CR BR: see above. * TODO-CR BR: see above.
* <p> * <p>
* Preconditions: * Preconditions:
* </p><ul> * </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> * </ul><p>
* Postconditions: * Postconditions:
* </p><ul> * </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> * </ul>
* *
* @return The field element (-1) * this. * @return The field element (-1) * this.
@ -126,21 +137,21 @@ public class Ed25519FieldElement extends FieldElement {
} }
/** /**
* h = f * g * $h = f * g$
* <p> * <p>
* Can overlap h with f or g. * Can overlap $h$ with $f$ or $g$.
* <p> * <p>
* Preconditions: * Preconditions:
* </p><ul> * </p><ul>
* <li>|f| bounded by * <li>$|f|$ bounded by
* 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. * $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc.
* <li>|g| bounded by * <li>$|g|$ bounded by
* 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. * $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc.
* </ul><p> * </ul><p>
* Postconditions: * Postconditions:
* </p><ul> * </p><ul>
* <li>|h| bounded by * <li>$|h|$ bounded by
* 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. * $1.01*2^{25},1.01*2^{24},1.01*2^{25},1.01*2^{24},$ etc.
* </ul><p> * </ul><p>
* Notes on implementation strategy: * Notes on implementation strategy:
* <p> * <p>
@ -377,17 +388,17 @@ public class Ed25519FieldElement extends FieldElement {
} }
/** /**
* h = f * f * $h = f * f$
* <p> * <p>
* Can overlap h with f. * Can overlap $h$ with $f$.
* <p> * <p>
* Preconditions: * Preconditions:
* </p><ul> * </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> * </ul><p>
* Postconditions: * Postconditions:
* </p><ul> * </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> * </ul><p>
* See {@link #multiply(FieldElement)} for discussion * See {@link #multiply(FieldElement)} for discussion
* of implementation strategy. * of implementation strategy.
@ -533,17 +544,17 @@ public class Ed25519FieldElement extends FieldElement {
} }
/** /**
* h = 2 * f * f * $h = 2 * f * f$
* <p> * <p>
* Can overlap h with f. * Can overlap $h$ with $f$.
* <p> * <p>
* Preconditions: * Preconditions:
* </p><ul> * </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> * </ul><p>
* Postconditions: * Postconditions:
* </p><ul> * </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> * </ul><p>
* See {@link #multiply(FieldElement)} for discussion * See {@link #multiply(FieldElement)} for discussion
* of implementation strategy. * of implementation strategy.
@ -698,7 +709,7 @@ public class Ed25519FieldElement extends FieldElement {
* Invert this field element. * Invert this field element.
* <p> * <p>
* The inverse is found via Fermat's little theorem:<br> * 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. * @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. * This is a helper function for calculating the square root.
* <p> * <p>
* TODO-CR BR: I think it makes sense to have a sqrt function. * 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() { public FieldElement pow22523() {
FieldElement t0, t1, t2; FieldElement t0, t1, t2;
@ -941,7 +952,7 @@ public class Ed25519FieldElement extends FieldElement {
* *
* @param val the other field element. * @param val the other field element.
* @param b must be 0 or 1, otherwise results are undefined. * @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 * @since 0.9.36
*/ */
@Override @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; package net.i2p.crypto.eddsa.math.ed25519;
import net.i2p.crypto.eddsa.math.*; import net.i2p.crypto.eddsa.math.*;
@ -9,40 +20,60 @@ import net.i2p.crypto.eddsa.math.*;
*/ */
public class Ed25519LittleEndianEncoding extends Encoding { public class Ed25519LittleEndianEncoding extends Encoding {
/** /**
* Encodes a given field element in its 32 byte representation. This is done in TWO steps. * 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. * <ol>
* Step 2: Convert the field element to the 32 byte representation. * <li>Reduce the value of the field element modulo $p$.
* <p> * <li>Convert the field element to the 32 byte representation.
* The idea for the modulo p reduction algorithm is as follows: * </ol><p>
* <p> * The idea for the modulo $p$ reduction algorithm is as follows:
* Assumption: * </p>
* </p><ul> * <h2>Assumption:</h2>
* <li>p = 2^255 - 19 * <ul>
* <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>$p = 2^{255} - 19$
* <li>h congruent r modulo p, i.e. h = r + q * p for some suitable 0 &lt;= r &lt; p and an integer q. * <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> * </ul><p>
* Then q = [2^-255 * (h + 19 * 2^-25 * h9 + 1/2)] where [x] = floor(x). * Then $q = [2^{-255} * (h + 19 * 2^{-25} * h_9 + 1/2)]$ where $[x] = floor(x)$.
* <p> * </p>
* Proof: * <h2>Proof:</h2>
* <p> * <p>
* We begin with some very raw estimation for the bounds of some expressions: * 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> * <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 * \begin{equation}
* * |h| \lt 2^{230} * 2^{30} = 2^{260} \Rightarrow |r + q * p| \lt 2^{260} \Rightarrow |q| \lt 2^{10}. \\
* <pre>[q + 2^-255 * x] = q (1)</pre> * \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> * <p>
* Have a closer look at x: * Therefore $0 \lt 1/2 - a - b \lt 1$.
* <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>
* <p> * <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) { public byte[] encode(FieldElement x) {
int[] h = ((Ed25519FieldElement)x).t; 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. * @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) { public FieldElement decode(byte[] in) {
long h0 = load_4(in, 0); long h0 = load_4(in, 0);
@ -207,15 +238,15 @@ public class Ed25519LittleEndianEncoding extends Encoding {
/** /**
* Is the FieldElement negative in this encoding? * Is the FieldElement negative in this encoding?
* <p> * <p>
* Return true if x is in {1,3,5,...,q-2}<br> * Return true if $x$ is in $\{1,3,5,\dots,q-2\}$<br>
* Return false if x is in {0,2,4,...,q-1} * Return false if $x$ is in $\{0,2,4,\dots,q-1\}$
* <p> * <p>
* Preconditions: * Preconditions:
* </p><ul> * </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> * </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) { public boolean isNegative(FieldElement x) {
byte[] s = encode(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; package net.i2p.crypto.eddsa.math.ed25519;
import net.i2p.crypto.eddsa.math.ScalarOps; 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 * Class for reducing a huge integer modulo the group order q and
* doing a combined multiply plus add plus reduce operation. * doing a combined multiply plus add plus reduce operation.
* <p> * <p>
* q = 2^252 + 27742317777372353535851937790883648493. * $q = 2^{252} + 27742317777372353535851937790883648493$.
* <p> * <p>
* Reviewed/commented by Bloody Rookie (nemproject@gmx.de) * Reviewed/commented by Bloody Rookie (nemproject@gmx.de)
*/ */
public class Ed25519ScalarOps implements ScalarOps { public class Ed25519ScalarOps implements ScalarOps {
/** /**
* Reduction modulo the group order q. * Reduction modulo the group order $q$.
* <p> * <p>
* Input: * Input:
* s[0]+256*s[1]+...+256^63*s[63] = s * $s[0]+256*s[1]+\dots+256^{63}*s[63] = s$
* <p> * <p>
* Output: * Output:
* s[0]+256*s[1]+...+256^31*s[31] = s mod q * $s[0]+256*s[1]+\dots+256^{31}*s[31] = s \bmod q$
* where q = 2^252 + 27742317777372353535851937790883648493. * where $q = 2^{252} + 27742317777372353535851937790883648493$.
*/ */
public byte[] reduce(byte[] s) { public byte[] reduce(byte[] s) {
// s0,..., s22 have 21 bits, s23 has 29 bits // s0,..., s22 have 21 bits, s23 has 29 bits
@ -313,15 +324,17 @@ public class Ed25519ScalarOps implements ScalarOps {
/** /**
* $(ab+c) \bmod q$
* <p>
* Input: * Input:
* <p><ul> * </p><ul>
* <li>a[0]+256*a[1]+...+256^31*a[31] = a * <li>$a[0]+256*a[1]+\dots+256^{31}*a[31] = a$
* <li>b[0]+256*b[1]+...+256^31*b[31] = b * <li>$b[0]+256*b[1]+\dots+256^{31}*b[31] = b$
* <li>c[0]+256*c[1]+...+256^31*c[31] = c * <li>$c[0]+256*c[1]+\dots+256^{31}*c[31] = c$
* </ul><p> * </ul><p>
* Output: * Output:
* result[0]+256*result[1]+...+256^31*result[31] = (ab+c) mod q * $result[0]+256*result[1]+\dots+256^{31}*result[31] = (ab+c) \bmod q$
* where q = 2^252 + 27742317777372353535851937790883648493. * where $q = 2^{252} + 27742317777372353535851937790883648493$.
* <p> * <p>
* See the comments in {@link #reduce(byte[])} for an explanation of the algorithm. * See the comments in {@link #reduce(byte[])} for an explanation of the algorithm.
*/ */

View File

@ -1,6 +1,6 @@
<html><body> <html><body>
<p> <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. See the <a href="../bigint/package-summary.html">bigint</a> implementation for other curves.
</p> </p>
</body></html> </body></html>

View File

@ -4,6 +4,6 @@
the mathematical operaions on them. the mathematical operaions on them.
</p><p> </p><p>
Low-level implementation is in <a href="bigint/package-summary.html">bigint</a> for any curve using BigIntegers, 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> </p>
</body></html> </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; package net.i2p.crypto.eddsa.spec;
import java.security.spec.AlgorithmParameterSpec; 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; package net.i2p.crypto.eddsa.spec;
import net.i2p.crypto.eddsa.math.Curve; 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; package net.i2p.crypto.eddsa.spec;
import java.util.HashMap; 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; package net.i2p.crypto.eddsa.spec;
import java.security.MessageDigest; import java.security.MessageDigest;
@ -25,11 +36,11 @@ public class EdDSAParameterSpec implements AlgorithmParameterSpec, Serializable
private final GroupElement B; private final GroupElement B;
/** /**
* @param curve the curve * @param curve the curve
* @param hashAlgo the JCA string for the hash algorithm * @param hashAlgo the JCA string for the hash algorithm
* @param sc the parameter L represented as ScalarOps * @param sc the parameter L represented as ScalarOps
* @param B the parameter B * @param B the parameter B
* @throws IllegalArgumentException if hash algorithm is unsupported or length is wrong * @throws IllegalArgumentException if hash algorithm is unsupported or length is wrong
*/ */
public EdDSAParameterSpec(Curve curve, String hashAlgo, public EdDSAParameterSpec(Curve curve, String hashAlgo,
ScalarOps sc, GroupElement B) { 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; package net.i2p.crypto.eddsa.spec;
import java.security.MessageDigest; 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; package net.i2p.crypto.eddsa.spec;
import java.security.spec.KeySpec; import java.security.spec.KeySpec;
@ -12,13 +23,13 @@ import net.i2p.crypto.eddsa.math.GroupElement;
*/ */
public class EdDSAPublicKeySpec implements KeySpec { public class EdDSAPublicKeySpec implements KeySpec {
private final GroupElement A; private final GroupElement A;
private GroupElement Aneg; private GroupElement Aneg = null;
private final EdDSAParameterSpec spec; private final EdDSAParameterSpec spec;
/** /**
* @param pk the public key * @param pk the public key
* @param spec the parameter specification for this key * @param spec the parameter specification for this key
* @throws IllegalArgumentException if key length is wrong * @throws IllegalArgumentException if key length is wrong
*/ */
public EdDSAPublicKeySpec(byte[] pk, EdDSAParameterSpec spec) { public EdDSAPublicKeySpec(byte[] pk, EdDSAParameterSpec spec) {
if (pk.length != spec.getCurve().getField().getb()/8) 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; package net.i2p.crypto.eddsa;
import java.io.BufferedReader; 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; package net.i2p.crypto.eddsa;
import static org.hamcrest.Matchers.equalTo; 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; package net.i2p.crypto.eddsa;
import org.hamcrest.core.IsEqual; import org.hamcrest.core.IsEqual;
@ -105,6 +116,11 @@ public class UtilsTest {
assertThat(Utils.bit(new byte[] {1, 2, 3}, 16), is(1)); assertThat(Utils.bit(new byte[] {1, 2, 3}, 16), is(1));
} }
@Test(expected = IllegalArgumentException.class)
public void hexToBytesThrowsOnInvalidLengthHexString() {
Utils.hexToBytes("bad");
}
@Test @Test
public void hexToBytesReturnsCorrectByteArray() { public void hexToBytesReturnsCorrectByteArray() {
Assert.assertThat(Utils.hexToBytes(hex1), IsEqual.equalTo(bytes1)); 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; package net.i2p.crypto.eddsa.math;
import net.i2p.crypto.eddsa.math.*;
import org.hamcrest.core.*; import org.hamcrest.core.*;
import org.junit.*; 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; package net.i2p.crypto.eddsa.math;
import static org.hamcrest.Matchers.equalTo; 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; package net.i2p.crypto.eddsa.math;
import net.i2p.crypto.eddsa.*; 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; package net.i2p.crypto.eddsa.math;
import net.i2p.crypto.eddsa.Utils; 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; package net.i2p.crypto.eddsa.math;
import java.io.BufferedReader; 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; package net.i2p.crypto.eddsa.math.bigint;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;

View File

@ -1,5 +1,13 @@
/** /**
* * 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; 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; package net.i2p.crypto.eddsa.math.ed25519;
import net.i2p.crypto.eddsa.math.*; 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; package net.i2p.crypto.eddsa.math.ed25519;
import net.i2p.crypto.eddsa.math.*; import net.i2p.crypto.eddsa.math.*;

View File

@ -1,5 +1,13 @@
/** /**
* * 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; 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; package net.i2p.crypto.eddsa.spec;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
@ -38,7 +49,7 @@ public class EdDSAPrivateKeySpecTest {
public void incorrectSeedLengthThrows() { public void incorrectSeedLengthThrows() {
exception.expect(IllegalArgumentException.class); exception.expect(IllegalArgumentException.class);
exception.expectMessage("seed length is wrong"); 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() { public void incorrectHashLengthThrows() {
exception.expect(IllegalArgumentException.class); exception.expect(IllegalArgumentException.class);
exception.expectMessage("hash length is wrong"); 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 2019-08-05 zzz
* i2ptunnel: * i2ptunnel:
- Add configs to override user agent - 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/