@Test
public void testMultipleKeys() throws Exception {

  EcdsaPrivateKey tinkPrivateKey =
      TestUtil.generateEcdsaPrivKey(
          EllipticCurveType.NIST_P521, HashType.SHA512, EcdsaSignatureEncoding.DER);
  Key tink =
      TestUtil.createKey(
          TestUtil.createKeyData(
              tinkPrivateKey,
              new EcdsaSignKeyManager().getKeyType(),
              KeyData.KeyMaterialType.ASYMMETRIC_PRIVATE),
          1,
          KeyStatusType.ENABLED,
          OutputPrefixType.TINK);
  EcdsaPrivateKey legacyPrivateKey =
      TestUtil.generateEcdsaPrivKey(
          EllipticCurveType.NIST_P256, HashType.SHA256, EcdsaSignatureEncoding.DER);
  Key legacy =
      TestUtil.createKey(
          TestUtil.createKeyData(
              legacyPrivateKey,
              new EcdsaSignKeyManager().getKeyType(),
              KeyData.KeyMaterialType.ASYMMETRIC_PRIVATE),
          2,
          KeyStatusType.ENABLED,
          OutputPrefixType.LEGACY);
  EcdsaPrivateKey rawPrivateKey =
      TestUtil.generateEcdsaPrivKey(
          EllipticCurveType.NIST_P384, HashType.SHA512, EcdsaSignatureEncoding.DER);
  Key raw =
      TestUtil.createKey(
          TestUtil.createKeyData(
              rawPrivateKey,
              new EcdsaSignKeyManager().getKeyType(),
              KeyData.KeyMaterialType.ASYMMETRIC_PRIVATE),
          3,
          KeyStatusType.ENABLED,
          OutputPrefixType.RAW);
  EcdsaPrivateKey crunchyPrivateKey =
      TestUtil.generateEcdsaPrivKey(
          EllipticCurveType.NIST_P384, HashType.SHA512, EcdsaSignatureEncoding.DER);
  Key crunchy =
      TestUtil.createKey(
          TestUtil.createKeyData(
              crunchyPrivateKey,
              new EcdsaSignKeyManager().getKeyType(),
              KeyData.KeyMaterialType.ASYMMETRIC_PRIVATE),
          4,
          KeyStatusType.ENABLED,
          OutputPrefixType.CRUNCHY);
  Key[] keys = new Key[] {tink, legacy, raw, crunchy};
  EcdsaPrivateKey[] privateKeys =
      new EcdsaPrivateKey[] {tinkPrivateKey, legacyPrivateKey, rawPrivateKey, crunchyPrivateKey};
  int j = keys.length;
  for (int i = 0; i < j; i++) {
    KeysetHandle keysetHandle =
        TestUtil.createKeysetHandle(
            TestUtil.createKeyset(
                keys[i], keys[(i + 1) % j], keys[(i + 2) % j], keys[(i + 3) % j]));
    // Signs with the primary private key.
    PublicKeySign signer = PublicKeySignFactory.getPrimitive(keysetHandle);
    byte[] plaintext = Random.randBytes(1211);
    byte[] sig = signer.sign(plaintext);
    if (keys[i].getOutputPrefixType() != OutputPrefixType.RAW) {
      byte[] prefix = Arrays.copyOfRange(sig, 0, CryptoFormat.NON_RAW_PREFIX_SIZE);
      assertArrayEquals(prefix, CryptoFormat.getOutputPrefix(keys[i]));
    }
    // Verifying with the primary public key should work.
    PublicKeyVerify verifier =
        PublicKeyVerifyFactory.getPrimitive(
            TestUtil.createKeysetHandle(
                TestUtil.createKeyset(
                    TestUtil.createKey(
                        TestUtil.createKeyData(
                            privateKeys[i].getPublicKey(),
                            new EcdsaVerifyKeyManager().getKeyType(),
                            KeyData.KeyMaterialType.ASYMMETRIC_PUBLIC),
                        keys[i].getKeyId(),
                        KeyStatusType.ENABLED,
                        keys[i].getOutputPrefixType()))));
    try {
      verifier.verify(sig, plaintext);
    } catch (GeneralSecurityException ex) {
      fail("Valid signature, should not throw exception");
    }
    // Verifying with a random public key should fail.
    EcdsaPrivateKey randomPrivKey =
        TestUtil.generateEcdsaPrivKey(
            EllipticCurveType.NIST_P521, HashType.SHA512, EcdsaSignatureEncoding.DER);
    verifier =
        PublicKeyVerifyFactory.getPrimitive(
            TestUtil.createKeysetHandle(
                TestUtil.createKeyset(
                    TestUtil.createKey(
                        TestUtil.createKeyData(
                            randomPrivKey.getPublicKey(),
                            new EcdsaVerifyKeyManager().getKeyType(),
                            KeyData.KeyMaterialType.ASYMMETRIC_PUBLIC),
                        keys[i].getKeyId(),
                        KeyStatusType.ENABLED,
                        keys[i].getOutputPrefixType()))));
    try {
      verifier.verify(sig, plaintext);
      fail("Invalid signature, should have thrown exception");
    } catch (GeneralSecurityException expected) {
      // Expected
    }
  }
}