Migrate the Ed25519{Private,Public}KeyManager to a KeyTypeManager.

PiperOrigin-RevId: 267316006
diff --git a/java/src/main/java/com/google/crypto/tink/signature/Ed25519PrivateKeyManager.java b/java/src/main/java/com/google/crypto/tink/signature/Ed25519PrivateKeyManager.java
index 0c565ce..121d72e 100644
--- a/java/src/main/java/com/google/crypto/tink/signature/Ed25519PrivateKeyManager.java
+++ b/java/src/main/java/com/google/crypto/tink/signature/Ed25519PrivateKeyManager.java
@@ -16,13 +16,11 @@
 
 package com.google.crypto.tink.signature;
 
-import com.google.crypto.tink.KeyManagerBase;
-import com.google.crypto.tink.PrivateKeyManager;
+import com.google.crypto.tink.PrivateKeyTypeManager;
 import com.google.crypto.tink.PublicKeySign;
+import com.google.crypto.tink.proto.Ed25519KeyFormat;
 import com.google.crypto.tink.proto.Ed25519PrivateKey;
 import com.google.crypto.tink.proto.Ed25519PublicKey;
-import com.google.crypto.tink.proto.Empty;
-import com.google.crypto.tink.proto.KeyData;
 import com.google.crypto.tink.proto.KeyData.KeyMaterialType;
 import com.google.crypto.tink.subtle.Ed25519Sign;
 import com.google.crypto.tink.subtle.Validators;
@@ -34,82 +32,79 @@
  * This instance of {@code KeyManager} generates new {@code Ed25519PrivateKey} keys and produces new
  * instances of {@code Ed25519Sign}.
  */
-class Ed25519PrivateKeyManager
-    extends KeyManagerBase<PublicKeySign, Ed25519PrivateKey, Empty>
-    implements PrivateKeyManager<PublicKeySign> {
+class Ed25519PrivateKeyManager extends PrivateKeyTypeManager<Ed25519PrivateKey, Ed25519PublicKey> {
   public Ed25519PrivateKeyManager() {
-    super(PublicKeySign.class, Ed25519PrivateKey.class, Empty.class, TYPE_URL);
-  }
-
-  public static final String TYPE_URL = "type.googleapis.com/google.crypto.tink.Ed25519PrivateKey";
-
-  private static final int VERSION = 0;
-
-  @Override
-  public PublicKeySign getPrimitiveFromKey(Ed25519PrivateKey keyProto)
-      throws GeneralSecurityException {
-    return new Ed25519Sign(keyProto.getKeyValue().toByteArray());
+    super(
+        Ed25519PrivateKey.class,
+        Ed25519PublicKey.class,
+        new PrimitiveFactory<PublicKeySign, Ed25519PrivateKey>(PublicKeySign.class) {
+          @Override
+          public PublicKeySign getPrimitive(Ed25519PrivateKey keyProto)
+              throws GeneralSecurityException {
+            return new Ed25519Sign(keyProto.getKeyValue().toByteArray());
+          }
+        });
   }
 
   @Override
-  public Ed25519PrivateKey newKeyFromFormat(Empty unused) throws GeneralSecurityException {
-    Ed25519Sign.KeyPair keyPair = Ed25519Sign.KeyPair.newKeyPair();
-    Ed25519PublicKey publicKey =
-        Ed25519PublicKey.newBuilder()
-            .setVersion(VERSION)
-            .setKeyValue(ByteString.copyFrom(keyPair.getPublicKey()))
-            .build();
-    return Ed25519PrivateKey.newBuilder()
-        .setVersion(VERSION)
-        .setKeyValue(ByteString.copyFrom(keyPair.getPrivateKey()))
-        .setPublicKey(publicKey)
-        .build();
-  }
-
-  @Override
-  public KeyData getPublicKeyData(ByteString serializedKey) throws GeneralSecurityException {
-    try {
-      Ed25519PrivateKey privKeyProto = Ed25519PrivateKey.parseFrom(serializedKey);
-      return KeyData.newBuilder()
-          .setTypeUrl(Ed25519PublicKeyManager.TYPE_URL)
-          .setValue(privKeyProto.getPublicKey().toByteString())
-          .setKeyMaterialType(KeyData.KeyMaterialType.ASYMMETRIC_PUBLIC)
-          .build();
-    } catch (InvalidProtocolBufferException e) {
-      throw new GeneralSecurityException("expected serialized Ed25519PrivateKey proto", e);
-    }
-  }
-
-  @Override
-  protected KeyMaterialType keyMaterialType() {
-    return KeyMaterialType.ASYMMETRIC_PRIVATE;
-  }
-
-  @Override
-  protected Ed25519PrivateKey parseKeyProto(ByteString byteString)
-      throws InvalidProtocolBufferException {
-    return Ed25519PrivateKey.parseFrom(byteString);
-  }
-
-  @Override
-  protected Empty parseKeyFormatProto(ByteString byteString)
-      throws InvalidProtocolBufferException {
-    return Empty.parseFrom(byteString);
+  public String getKeyType() {
+    return "type.googleapis.com/google.crypto.tink.Ed25519PrivateKey";
   }
 
   @Override
   public int getVersion() {
-    return VERSION;
+    return 0;
   }
 
   @Override
-  protected void validateKey(Ed25519PrivateKey keyProto) throws GeneralSecurityException {
-    Validators.validateVersion(keyProto.getVersion(), VERSION);
+  public Ed25519PublicKey getPublicKey(Ed25519PrivateKey key) throws GeneralSecurityException {
+    return key.getPublicKey();
+  }
+
+  @Override
+  public KeyMaterialType keyMaterialType() {
+    return KeyMaterialType.ASYMMETRIC_PRIVATE;
+  }
+
+  @Override
+  public Ed25519PrivateKey parseKey(ByteString byteString) throws InvalidProtocolBufferException {
+    return Ed25519PrivateKey.parseFrom(byteString);
+  }
+
+  @Override
+  public void validateKey(Ed25519PrivateKey keyProto) throws GeneralSecurityException {
+    Validators.validateVersion(keyProto.getVersion(), getVersion());
     if (keyProto.getKeyValue().size() != Ed25519Sign.SECRET_KEY_LEN) {
       throw new GeneralSecurityException("invalid Ed25519 private key: incorrect key length");
     }
   }
 
   @Override
-  protected void validateKeyFormat(Empty unused) {}
+  public KeyFactory<Ed25519KeyFormat, Ed25519PrivateKey> keyFactory() {
+    return new KeyFactory<Ed25519KeyFormat, Ed25519PrivateKey>(Ed25519KeyFormat.class) {
+      @Override
+      public void validateKeyFormat(Ed25519KeyFormat format) throws GeneralSecurityException {}
+
+      @Override
+      public Ed25519KeyFormat parseKeyFormat(ByteString byteString)
+          throws InvalidProtocolBufferException {
+        return Ed25519KeyFormat.parseFrom(byteString);
+      }
+
+      @Override
+      public Ed25519PrivateKey createKey(Ed25519KeyFormat format) throws GeneralSecurityException {
+        Ed25519Sign.KeyPair keyPair = Ed25519Sign.KeyPair.newKeyPair();
+        Ed25519PublicKey publicKey =
+            Ed25519PublicKey.newBuilder()
+                .setVersion(getVersion())
+                .setKeyValue(ByteString.copyFrom(keyPair.getPublicKey()))
+                .build();
+        return Ed25519PrivateKey.newBuilder()
+            .setVersion(getVersion())
+            .setKeyValue(ByteString.copyFrom(keyPair.getPrivateKey()))
+            .setPublicKey(publicKey)
+            .build();
+      }
+    };
+  }
 }
diff --git a/java/src/main/java/com/google/crypto/tink/signature/Ed25519PublicKeyManager.java b/java/src/main/java/com/google/crypto/tink/signature/Ed25519PublicKeyManager.java
index f6050ad..2ec3956 100644
--- a/java/src/main/java/com/google/crypto/tink/signature/Ed25519PublicKeyManager.java
+++ b/java/src/main/java/com/google/crypto/tink/signature/Ed25519PublicKeyManager.java
@@ -16,10 +16,9 @@
 
 package com.google.crypto.tink.signature;
 
-import com.google.crypto.tink.KeyManagerBase;
+import com.google.crypto.tink.KeyTypeManager;
 import com.google.crypto.tink.PublicKeyVerify;
 import com.google.crypto.tink.proto.Ed25519PublicKey;
-import com.google.crypto.tink.proto.Empty;
 import com.google.crypto.tink.proto.KeyData.KeyMaterialType;
 import com.google.crypto.tink.subtle.Ed25519Verify;
 import com.google.crypto.tink.subtle.Validators;
@@ -31,55 +30,43 @@
  * This key manager produces new instances of {@code Ed25519Verify}. It doesn't support key
  * generation.
  */
-class Ed25519PublicKeyManager extends KeyManagerBase<PublicKeyVerify, Ed25519PublicKey, Empty> {
+class Ed25519PublicKeyManager extends KeyTypeManager<Ed25519PublicKey> {
   public Ed25519PublicKeyManager() {
-    super(PublicKeyVerify.class, Ed25519PublicKey.class, Empty.class, TYPE_URL);
-  }
-  public static final String TYPE_URL = "type.googleapis.com/google.crypto.tink.Ed25519PublicKey";
-
-  private static final int VERSION = 0;
-
-  @Override
-  public PublicKeyVerify getPrimitiveFromKey(Ed25519PublicKey keyProto)
-      throws GeneralSecurityException {
-    return new Ed25519Verify(keyProto.getKeyValue().toByteArray());
+    super(
+        Ed25519PublicKey.class,
+        new PrimitiveFactory<PublicKeyVerify, Ed25519PublicKey>(PublicKeyVerify.class) {
+          @Override
+          public PublicKeyVerify getPrimitive(Ed25519PublicKey keyProto) {
+            return new Ed25519Verify(keyProto.getKeyValue().toByteArray());
+          }
+        });
   }
 
   @Override
-  protected Ed25519PublicKey newKeyFromFormat(Empty unused) throws GeneralSecurityException {
-    throw new GeneralSecurityException("Not implemented");
+  public String getKeyType() {
+    return "type.googleapis.com/google.crypto.tink.Ed25519PublicKey";
   }
 
   @Override
   public int getVersion() {
-    return VERSION;
+    return 0;
   }
 
   @Override
-  protected KeyMaterialType keyMaterialType() {
+  public KeyMaterialType keyMaterialType() {
     return KeyMaterialType.ASYMMETRIC_PUBLIC;
   }
 
   @Override
-  protected Ed25519PublicKey parseKeyProto(ByteString byteString)
-      throws InvalidProtocolBufferException {
+  public Ed25519PublicKey parseKey(ByteString byteString) throws InvalidProtocolBufferException {
     return Ed25519PublicKey.parseFrom(byteString);
   }
 
   @Override
-  protected Empty parseKeyFormatProto(ByteString byteString)
-      throws InvalidProtocolBufferException {
-    return Empty.parseFrom(byteString);
-  }
-
-  @Override
-  protected void validateKey(Ed25519PublicKey keyProto) throws GeneralSecurityException {
-    Validators.validateVersion(keyProto.getVersion(), VERSION);
+  public void validateKey(Ed25519PublicKey keyProto) throws GeneralSecurityException {
+    Validators.validateVersion(keyProto.getVersion(), getVersion());
     if (keyProto.getKeyValue().size() != Ed25519Verify.PUBLIC_KEY_LEN) {
       throw new GeneralSecurityException("invalid Ed25519 public key: incorrect key length");
     }
   }
-
-  @Override
-  protected void validateKeyFormat(Empty unused) throws GeneralSecurityException {}
 }
diff --git a/java/src/main/java/com/google/crypto/tink/signature/SignatureConfig.java b/java/src/main/java/com/google/crypto/tink/signature/SignatureConfig.java
index e871795..6e4065a 100644
--- a/java/src/main/java/com/google/crypto/tink/signature/SignatureConfig.java
+++ b/java/src/main/java/com/google/crypto/tink/signature/SignatureConfig.java
@@ -40,8 +40,10 @@
 public final class SignatureConfig {
   public static final String ECDSA_PUBLIC_KEY_TYPE_URL = new EcdsaVerifyKeyManager().getKeyType();
   public static final String ECDSA_PRIVATE_KEY_TYPE_URL = new EcdsaSignKeyManager().getKeyType();
-  public static final String ED25519_PUBLIC_KEY_TYPE_URL = Ed25519PublicKeyManager.TYPE_URL;
-  public static final String ED25519_PRIVATE_KEY_TYPE_URL = Ed25519PrivateKeyManager.TYPE_URL;
+  public static final String ED25519_PUBLIC_KEY_TYPE_URL =
+      new Ed25519PublicKeyManager().getKeyType();
+  public static final String ED25519_PRIVATE_KEY_TYPE_URL =
+      new Ed25519PrivateKeyManager().getKeyType();
 
   /** @deprecated */
   @Deprecated
@@ -87,8 +89,8 @@
     Registry.registerAsymmetricKeyManagers(
         new EcdsaSignKeyManager(), new EcdsaVerifyKeyManager(), true);
 
-    Registry.registerKeyManager(new Ed25519PrivateKeyManager());
-    Registry.registerKeyManager(new Ed25519PublicKeyManager());
+    Registry.registerAsymmetricKeyManagers(
+        new Ed25519PrivateKeyManager(), new Ed25519PublicKeyManager(), true);
 
     Registry.registerKeyManager(new RsaSsaPkcs1SignKeyManager());
     Registry.registerKeyManager(new RsaSsaPkcs1VerifyKeyManager());
diff --git a/java/src/main/java/com/google/crypto/tink/signature/SignatureKeyTemplates.java b/java/src/main/java/com/google/crypto/tink/signature/SignatureKeyTemplates.java
index b5a1f99..2bb5f9f 100644
--- a/java/src/main/java/com/google/crypto/tink/signature/SignatureKeyTemplates.java
+++ b/java/src/main/java/com/google/crypto/tink/signature/SignatureKeyTemplates.java
@@ -141,7 +141,7 @@
    */
   public static final KeyTemplate ED25519 =
       KeyTemplate.newBuilder()
-          .setTypeUrl(Ed25519PrivateKeyManager.TYPE_URL)
+          .setTypeUrl(new Ed25519PrivateKeyManager().getKeyType())
           .setOutputPrefixType(OutputPrefixType.TINK)
           .build();
 
diff --git a/java/src/test/java/com/google/crypto/tink/signature/Ed25519PrivateKeyManagerTest.java b/java/src/test/java/com/google/crypto/tink/signature/Ed25519PrivateKeyManagerTest.java
index 116e7a4..cf9ff49 100644
--- a/java/src/test/java/com/google/crypto/tink/signature/Ed25519PrivateKeyManagerTest.java
+++ b/java/src/test/java/com/google/crypto/tink/signature/Ed25519PrivateKeyManagerTest.java
@@ -22,7 +22,11 @@
 import static org.junit.Assert.fail;
 
 import com.google.crypto.tink.Config;
+import com.google.crypto.tink.KeyManager;
+import com.google.crypto.tink.KeyManagerImpl;
 import com.google.crypto.tink.KeysetHandle;
+import com.google.crypto.tink.PrivateKeyManager;
+import com.google.crypto.tink.PrivateKeyManagerImpl;
 import com.google.crypto.tink.PublicKeySign;
 import com.google.crypto.tink.PublicKeyVerify;
 import com.google.crypto.tink.TestUtil;
@@ -45,12 +49,13 @@
   @BeforeClass
   public static void setUp() throws GeneralSecurityException {
     Config.register(SignatureConfig.TINK_1_0_0);
-    ;
   }
 
   @Test
   public void testBasic() throws Exception {
-    Ed25519PrivateKeyManager manager = new Ed25519PrivateKeyManager();
+    PrivateKeyManager<PublicKeySign> manager =
+        new PrivateKeyManagerImpl<>(
+            new Ed25519PrivateKeyManager(), new Ed25519PublicKeyManager(), PublicKeySign.class);
     KeyTemplate template = SignatureKeyTemplates.ED25519;
     MessageLite key = manager.newKey(template.getValue());
     assertTrue(key instanceof Ed25519PrivateKey);
@@ -64,7 +69,8 @@
     byte[] signature = signer.sign(message);
     assertEquals(64, signature.length);
 
-    Ed25519PublicKeyManager publicKeyManager = new Ed25519PublicKeyManager();
+    KeyManager<PublicKeyVerify> publicKeyManager =
+        new KeyManagerImpl<>(new Ed25519PublicKeyManager(), PublicKeyVerify.class);
     PublicKeyVerify verifier = publicKeyManager.getPrimitive(keyProto.getPublicKey());
     assertTrue(verifier instanceof Ed25519Verify);
     try {
@@ -79,15 +85,18 @@
   public void testGetPublicKeyData() throws Exception {
     KeysetHandle privateHandle = KeysetHandle.generateNew(SignatureKeyTemplates.ED25519);
     KeyData privateKeyData = TestUtil.getKeyset(privateHandle).getKey(0).getKeyData();
-    Ed25519PrivateKeyManager privateManager = new Ed25519PrivateKeyManager();
+    PrivateKeyManager<PublicKeySign> privateManager =
+        new PrivateKeyManagerImpl<>(
+            new Ed25519PrivateKeyManager(), new Ed25519PublicKeyManager(), PublicKeySign.class);
     KeyData publicKeyData = privateManager.getPublicKeyData(privateKeyData.getValue());
-    assertEquals(Ed25519PublicKeyManager.TYPE_URL, publicKeyData.getTypeUrl());
+    assertEquals(new Ed25519PublicKeyManager().getKeyType(), publicKeyData.getTypeUrl());
     assertEquals(KeyData.KeyMaterialType.ASYMMETRIC_PUBLIC, publicKeyData.getKeyMaterialType());
     Ed25519PrivateKey privateKey = Ed25519PrivateKey.parseFrom(privateKeyData.getValue());
     assertArrayEquals(
         privateKey.getPublicKey().toByteArray(), publicKeyData.getValue().toByteArray());
 
-    Ed25519PublicKeyManager publicManager = new Ed25519PublicKeyManager();
+    KeyManager<PublicKeyVerify> publicManager =
+        new KeyManagerImpl<>(new Ed25519PublicKeyManager(), PublicKeyVerify.class);
     PublicKeySign signer = privateManager.getPrimitive(privateKeyData.getValue());
     PublicKeyVerify verifier = publicManager.getPrimitive(publicKeyData.getValue());
     byte[] message = Random.randBytes(20);
diff --git a/java/src/test/java/com/google/crypto/tink/signature/Ed25519PublicKeyManagerTest.java b/java/src/test/java/com/google/crypto/tink/signature/Ed25519PublicKeyManagerTest.java
index 0e0fdf0..7657a98 100644
--- a/java/src/test/java/com/google/crypto/tink/signature/Ed25519PublicKeyManagerTest.java
+++ b/java/src/test/java/com/google/crypto/tink/signature/Ed25519PublicKeyManagerTest.java
@@ -19,6 +19,10 @@
 import static org.junit.Assert.fail;
 
 import com.google.crypto.tink.Config;
+import com.google.crypto.tink.KeyManager;
+import com.google.crypto.tink.KeyManagerImpl;
+import com.google.crypto.tink.PrivateKeyManager;
+import com.google.crypto.tink.PrivateKeyManagerImpl;
 import com.google.crypto.tink.PublicKeySign;
 import com.google.crypto.tink.PublicKeyVerify;
 import com.google.crypto.tink.TestUtil;
@@ -44,7 +48,9 @@
 
   @Test
   public void testModifiedSignature() throws Exception {
-    Ed25519PrivateKeyManager manager = new Ed25519PrivateKeyManager();
+    PrivateKeyManager<PublicKeySign> manager =
+        new PrivateKeyManagerImpl<>(
+            new Ed25519PrivateKeyManager(), new Ed25519PublicKeyManager(), PublicKeySign.class);
     KeyTemplate template = SignatureKeyTemplates.ED25519;
     MessageLite key = manager.newKey(template.getValue());
     Ed25519PrivateKey keyProto = (Ed25519PrivateKey) key;
@@ -52,7 +58,8 @@
     PublicKeySign signer = manager.getPrimitive(key);
     byte[] message = Random.randBytes(20);
     byte[] signature = signer.sign(message);
-    Ed25519PublicKeyManager publicKeyManager = new Ed25519PublicKeyManager();
+    KeyManager<PublicKeyVerify> publicKeyManager =
+        new KeyManagerImpl<>(new Ed25519PublicKeyManager(), PublicKeyVerify.class);
     PublicKeyVerify verifier = publicKeyManager.getPrimitive(keyProto.getPublicKey());
     try {
       verifier.verify(signature, message);
diff --git a/java/src/test/java/com/google/crypto/tink/signature/SignatureKeyTemplatesTest.java b/java/src/test/java/com/google/crypto/tink/signature/SignatureKeyTemplatesTest.java
index 75dff83..076018c 100644
--- a/java/src/test/java/com/google/crypto/tink/signature/SignatureKeyTemplatesTest.java
+++ b/java/src/test/java/com/google/crypto/tink/signature/SignatureKeyTemplatesTest.java
@@ -120,7 +120,7 @@
   @Test
   public void testED25519() throws Exception {
     KeyTemplate template = SignatureKeyTemplates.ED25519;
-    assertEquals(Ed25519PrivateKeyManager.TYPE_URL, template.getTypeUrl());
+    assertEquals(new Ed25519PrivateKeyManager().getKeyType(), template.getTypeUrl());
     assertEquals(OutputPrefixType.TINK, template.getOutputPrefixType());
     assertTrue(template.getValue().isEmpty()); // Empty format.
   }