From 1e375c6de9d2f8b0b901d736385ebdf2228bcb91 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Sun, 2 Oct 2016 15:42:07 +0000
Subject: [PATCH] Crypto: EdDSA add private key spec constructor for hash
 javadocs

---
 .../net/i2p/crypto/eddsa/EdDSAPrivateKey.java | 19 +++++++++++
 .../crypto/eddsa/spec/EdDSAParameterSpec.java |  3 ++
 .../eddsa/spec/EdDSAPrivateKeySpec.java       | 33 +++++++++++++++++++
 3 files changed, 55 insertions(+)

diff --git a/core/java/src/net/i2p/crypto/eddsa/EdDSAPrivateKey.java b/core/java/src/net/i2p/crypto/eddsa/EdDSAPrivateKey.java
index 3092ee12ad..f875f0d6c5 100644
--- a/core/java/src/net/i2p/crypto/eddsa/EdDSAPrivateKey.java
+++ b/core/java/src/net/i2p/crypto/eddsa/EdDSAPrivateKey.java
@@ -90,6 +90,9 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
      *  This will hopefully be clarified in the next draft.
      *  But sun.security.pkcs.PKCS8Key expects them so we must include them for keytool to work.
      *
+     *  This encodes the seed. It will return null if constructed from
+     *  a spec which was directly constructed from H, in which case seed is null.
+     *
      *  @return 49 bytes for Ed25519, null for other curves
      *  @since implemented in 0.9.25
      */
@@ -174,22 +177,38 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
         return edDsaSpec;
     }
 
+    /**
+     *  @return will be null if constructed from a spec which was
+     *          directly constructed from H
+     */
     public byte[] getSeed() {
         return seed;
     }
 
+    /**
+     *  @return the hash of the seed
+     */
     public byte[] getH() {
         return h;
     }
 
+    /**
+     *  @return the private key
+     */
     public byte[] geta() {
         return a;
     }
 
+    /**
+     *  @return the public key
+     */
     public GroupElement getA() {
         return A;
     }
 
+    /**
+     *  @return the public key
+     */
     public byte[] getAbyte() {
         return Abyte;
     }
diff --git a/core/java/src/net/i2p/crypto/eddsa/spec/EdDSAParameterSpec.java b/core/java/src/net/i2p/crypto/eddsa/spec/EdDSAParameterSpec.java
index 75b0140c6a..dc98e566d0 100644
--- a/core/java/src/net/i2p/crypto/eddsa/spec/EdDSAParameterSpec.java
+++ b/core/java/src/net/i2p/crypto/eddsa/spec/EdDSAParameterSpec.java
@@ -56,6 +56,9 @@ public class EdDSAParameterSpec implements AlgorithmParameterSpec, Serializable
         return sc;
     }
 
+    /**
+     *  @return the base (generator)
+     */
     public GroupElement getB() {
         return B;
     }
diff --git a/core/java/src/net/i2p/crypto/eddsa/spec/EdDSAPrivateKeySpec.java b/core/java/src/net/i2p/crypto/eddsa/spec/EdDSAPrivateKeySpec.java
index 26f5c3a2d4..240ac4f3bf 100644
--- a/core/java/src/net/i2p/crypto/eddsa/spec/EdDSAPrivateKeySpec.java
+++ b/core/java/src/net/i2p/crypto/eddsa/spec/EdDSAPrivateKeySpec.java
@@ -51,6 +51,27 @@ public class EdDSAPrivateKeySpec implements KeySpec {
         }
     }
 
+    /**
+     *  Initialize directly from the hash.
+     *  getSeed() will return null if this constructor is used.
+     *
+     *  @param h the private key
+     *  @since 0.9.27 (GitHub issue #17)
+     */
+    public EdDSAPrivateKeySpec(EdDSAParameterSpec spec, byte[] h) {
+	this.seed = null;
+	this.h = h;
+	this.spec = spec;
+	int b = spec.getCurve().getField().getb();
+
+        h[0] &= 248;
+        h[(b/8)-1] &= 63;
+        h[(b/8)-1] |= 64;
+        a = Arrays.copyOfRange(h, 0, b/8);
+
+        A = spec.getB().scalarMultiply(a);
+    }
+
     public EdDSAPrivateKeySpec(byte[] seed, byte[] h, byte[] a, GroupElement A, EdDSAParameterSpec spec) {
         this.seed = seed;
         this.h = h;
@@ -59,18 +80,30 @@ public class EdDSAPrivateKeySpec implements KeySpec {
         this.spec = spec;        
     }
 
+    /**
+     *  @return will be null if constructed directly from the private key
+     */
     public byte[] getSeed() {
         return seed;
     }
 
+    /**
+     *  @return the hash
+     */
     public byte[] getH() {
         return h;
     }
 
+    /**
+     *  @return the private key
+     */
     public byte[] geta() {
         return a;
     }
 
+    /**
+     *  @return the public key
+     */
     public GroupElement getA() {
         return A;
     }
-- 
GitLab