aboutsummaryrefslogtreecommitdiff
path: root/java_src/src/test/java
diff options
context:
space:
mode:
authorioannanedelcu <ioannanedelcu@google.com>2023-08-07 01:26:51 -0700
committerCopybara-Service <copybara-worker@google.com>2023-08-07 01:27:59 -0700
commit8f20e13e02d77cff41d94837bdaeac2e146ff143 (patch)
tree8d8098bfd30857c55b1c98286591a4e7d1a14b4f /java_src/src/test/java
parent8e84baffd9c94b3dbb561633a8ebf58dae961c52 (diff)
downloadtink-8f20e13e02d77cff41d94837bdaeac2e146ff143.tar.gz
Add serialization for Ecies Private Keys.
PiperOrigin-RevId: 554395954
Diffstat (limited to 'java_src/src/test/java')
-rw-r--r--java_src/src/test/java/com/google/crypto/tink/hybrid/BUILD.bazel3
-rw-r--r--java_src/src/test/java/com/google/crypto/tink/hybrid/EciesProtoSerializationTest.java273
2 files changed, 276 insertions, 0 deletions
diff --git a/java_src/src/test/java/com/google/crypto/tink/hybrid/BUILD.bazel b/java_src/src/test/java/com/google/crypto/tink/hybrid/BUILD.bazel
index 5ce9ce2dd..8b23db591 100644
--- a/java_src/src/test/java/com/google/crypto/tink/hybrid/BUILD.bazel
+++ b/java_src/src/test/java/com/google/crypto/tink/hybrid/BUILD.bazel
@@ -392,6 +392,7 @@ java_test(
"//src/main/java/com/google/crypto/tink/aead:aead_config",
"//src/main/java/com/google/crypto/tink/aead:x_cha_cha20_poly1305_parameters",
"//src/main/java/com/google/crypto/tink/hybrid:ecies_parameters",
+ "//src/main/java/com/google/crypto/tink/hybrid:ecies_private_key",
"//src/main/java/com/google/crypto/tink/hybrid:ecies_proto_serialization",
"//src/main/java/com/google/crypto/tink/hybrid:ecies_public_key",
"//src/main/java/com/google/crypto/tink/internal:key_template_proto_converter",
@@ -404,6 +405,8 @@ java_test(
"//src/main/java/com/google/crypto/tink/subtle:random",
"//src/main/java/com/google/crypto/tink/subtle:x25519",
"//src/main/java/com/google/crypto/tink/util:bytes",
+ "//src/main/java/com/google/crypto/tink/util:secret_big_integer",
+ "//src/main/java/com/google/crypto/tink/util:secret_bytes",
"@maven//:com_google_code_findbugs_jsr305",
"@maven//:com_google_protobuf_protobuf_java",
"@maven//:com_google_truth_truth",
diff --git a/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesProtoSerializationTest.java b/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesProtoSerializationTest.java
index a2ef28f6e..f2b601172 100644
--- a/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesProtoSerializationTest.java
+++ b/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesProtoSerializationTest.java
@@ -35,6 +35,7 @@ import com.google.crypto.tink.proto.EcPointFormat;
import com.google.crypto.tink.proto.EciesAeadDemParams;
import com.google.crypto.tink.proto.EciesAeadHkdfKeyFormat;
import com.google.crypto.tink.proto.EciesAeadHkdfParams;
+import com.google.crypto.tink.proto.EciesAeadHkdfPrivateKey;
import com.google.crypto.tink.proto.EciesAeadHkdfPublicKey;
import com.google.crypto.tink.proto.EciesHkdfKemParams;
import com.google.crypto.tink.proto.EllipticCurveType;
@@ -47,6 +48,8 @@ import com.google.crypto.tink.subtle.Hex;
import com.google.crypto.tink.subtle.Random;
import com.google.crypto.tink.subtle.X25519;
import com.google.crypto.tink.util.Bytes;
+import com.google.crypto.tink.util.SecretBigInteger;
+import com.google.crypto.tink.util.SecretBytes;
import com.google.protobuf.ByteString;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
@@ -865,4 +868,274 @@ public final class EciesProtoSerializationTest {
GeneralSecurityException.class,
() -> registry.parseKey(serialization, InsecureSecretKeyAccess.get()));
}
+
+ // PRIVATE KEY SERIALIZATION =====================================================================
+ @Test
+ public void serializeParseNistPrivateKey_works() throws Exception {
+ String hexX = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6";
+ String hexY = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299";
+ String hexPrivateValue = "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721";
+
+ // Java object
+ EciesParameters parameters =
+ EciesParameters.builder()
+ .setCurveType(EciesParameters.CurveType.NIST_P256)
+ .setHashType(EciesParameters.HashType.SHA256)
+ .setNistCurvePointFormat(EciesParameters.PointFormat.COMPRESSED)
+ .setVariant(EciesParameters.Variant.TINK)
+ .setDemParameters(DEM_PARAMETERS)
+ .setSalt(SALT)
+ .build();
+ EciesPublicKey publicKey =
+ EciesPublicKey.createForNistCurve(
+ parameters, new ECPoint(new BigInteger(hexX, 16), new BigInteger(hexY, 16)), 101);
+ EciesPrivateKey privateKey =
+ EciesPrivateKey.createForNistCurve(
+ publicKey,
+ SecretBigInteger.fromBigInteger(
+ new BigInteger(hexPrivateValue, 16), InsecureSecretKeyAccess.get()));
+
+ // Proto object
+ EciesAeadHkdfPublicKey protoPublicKey =
+ EciesAeadHkdfPublicKey.newBuilder()
+ .setVersion(0)
+ .setParams(
+ validParamsForCurve(com.google.crypto.tink.proto.EllipticCurveType.NIST_P256))
+ .setX(ByteString.copyFrom(Hex.decode("00" + hexX)))
+ .setY(ByteString.copyFrom(Hex.decode("00" + hexY)))
+ .build();
+ EciesAeadHkdfPrivateKey protoPrivateKey =
+ EciesAeadHkdfPrivateKey.newBuilder()
+ .setVersion(0)
+ .setPublicKey(protoPublicKey)
+ // privateValue is currently serialized with an extra zero at the beginning.
+ .setKeyValue(ByteString.copyFrom(Hex.decode("00" + hexPrivateValue)))
+ .build();
+ ProtoKeySerialization serialization =
+ ProtoKeySerialization.create(
+ "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey",
+ protoPrivateKey.toByteString(),
+ KeyMaterialType.ASYMMETRIC_PRIVATE,
+ OutputPrefixType.TINK,
+ /* idRequirement= */ 101);
+
+ // Comparison
+ Key parsed = registry.parseKey(serialization, InsecureSecretKeyAccess.get());
+ assertThat(parsed.equalsKey(privateKey)).isTrue();
+
+ ProtoKeySerialization serialized =
+ registry.serializeKey(
+ privateKey, ProtoKeySerialization.class, InsecureSecretKeyAccess.get());
+
+ assertEqualWhenValueParsed(EciesAeadHkdfPublicKey.parser(), serialized, serialization);
+ }
+
+ @Test
+ public void serializeParseX25519PrivateKey_works() throws Exception {
+ byte[] privateKeyBytes = X25519.generatePrivateKey();
+ byte[] publicKeyBytes = X25519.publicFromPrivate(privateKeyBytes);
+
+ // Java object
+ EciesParameters parameters =
+ EciesParameters.builder()
+ .setCurveType(EciesParameters.CurveType.X25519)
+ .setHashType(EciesParameters.HashType.SHA256)
+ .setVariant(EciesParameters.Variant.TINK)
+ .setDemParameters(DEM_PARAMETERS)
+ .setSalt(SALT)
+ .build();
+ EciesPublicKey publicKey =
+ EciesPublicKey.createForCurveX25519(parameters, Bytes.copyFrom(publicKeyBytes), 101);
+ EciesPrivateKey privateKey =
+ EciesPrivateKey.createForCurveX25519(
+ publicKey, SecretBytes.copyFrom(privateKeyBytes, InsecureSecretKeyAccess.get()));
+
+ // Proto object
+ EciesAeadHkdfPublicKey protoPublicKey =
+ EciesAeadHkdfPublicKey.newBuilder()
+ .setVersion(0)
+ .setParams(validParamsForCurve(EllipticCurveType.CURVE25519))
+ .setX(ByteString.copyFrom(publicKeyBytes))
+ .build();
+ EciesAeadHkdfPrivateKey protoPrivateKey =
+ EciesAeadHkdfPrivateKey.newBuilder()
+ .setVersion(0)
+ .setPublicKey(protoPublicKey)
+ .setKeyValue(ByteString.copyFrom(privateKeyBytes))
+ .build();
+ ProtoKeySerialization serialization =
+ ProtoKeySerialization.create(
+ "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey",
+ protoPrivateKey.toByteString(),
+ KeyMaterialType.ASYMMETRIC_PRIVATE,
+ OutputPrefixType.TINK,
+ /* idRequirement= */ 101);
+
+ // Comparison
+ Key parsed = registry.parseKey(serialization, InsecureSecretKeyAccess.get());
+ assertThat(parsed.equalsKey(privateKey)).isTrue();
+
+ ProtoKeySerialization serialized =
+ registry.serializeKey(
+ privateKey, ProtoKeySerialization.class, InsecureSecretKeyAccess.get());
+
+ assertEqualWhenValueParsed(EciesAeadHkdfPublicKey.parser(), serialized, serialization);
+ }
+
+ @Test
+ public void testParsePrivateKey_noAccess_throws() throws Exception {
+ String hexX = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6";
+ String hexY = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299";
+ String hexPrivateValue = "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721";
+
+ // Proto object
+ EciesAeadHkdfPublicKey protoPublicKey =
+ EciesAeadHkdfPublicKey.newBuilder()
+ .setVersion(0)
+ .setParams(
+ validParamsForCurve(com.google.crypto.tink.proto.EllipticCurveType.NIST_P256))
+ .setX(ByteString.copyFrom(Hex.decode("00" + hexX)))
+ .setY(ByteString.copyFrom(Hex.decode("00" + hexY)))
+ .build();
+ EciesAeadHkdfPrivateKey protoPrivateKey =
+ EciesAeadHkdfPrivateKey.newBuilder()
+ .setVersion(0)
+ .setPublicKey(protoPublicKey)
+ // privateValue is currently serialized with an extra zero at the beginning.
+ .setKeyValue(ByteString.copyFrom(Hex.decode("00" + hexPrivateValue)))
+ .build();
+ ProtoKeySerialization serialization =
+ ProtoKeySerialization.create(
+ "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey",
+ protoPrivateKey.toByteString(),
+ KeyMaterialType.ASYMMETRIC_PRIVATE,
+ OutputPrefixType.TINK,
+ /* idRequirement= */ 101);
+ assertThrows(
+ GeneralSecurityException.class, () -> registry.parseKey(serialization, /* access= */ null));
+ }
+
+ @Test
+ public void testSerializeKeys_noAccess_throws() throws Exception {
+ String hexX = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6";
+ String hexY = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299";
+ String hexPrivateValue = "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721";
+
+ EciesParameters parameters =
+ EciesParameters.builder()
+ .setCurveType(EciesParameters.CurveType.NIST_P256)
+ .setHashType(EciesParameters.HashType.SHA256)
+ .setNistCurvePointFormat(EciesParameters.PointFormat.COMPRESSED)
+ .setVariant(EciesParameters.Variant.TINK)
+ .setDemParameters(DEM_PARAMETERS)
+ .setSalt(SALT)
+ .build();
+ EciesPublicKey publicKey =
+ EciesPublicKey.createForNistCurve(
+ parameters, new ECPoint(new BigInteger(hexX, 16), new BigInteger(hexY, 16)), 101);
+ EciesPrivateKey privateKey =
+ EciesPrivateKey.createForNistCurve(
+ publicKey,
+ SecretBigInteger.fromBigInteger(
+ new BigInteger(hexPrivateValue, 16), InsecureSecretKeyAccess.get()));
+
+ assertThrows(
+ GeneralSecurityException.class,
+ () -> registry.serializeKey(privateKey, ProtoKeySerialization.class, /* access= */ null));
+ }
+
+ private static ProtoKeySerialization[] createInvalidPrivateKeySerializations() {
+ try {
+ String hexX = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6";
+ String hexY = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299";
+ String hexPrivateValue = "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721";
+
+ EciesAeadHkdfPublicKey validProtoPublicKey =
+ EciesAeadHkdfPublicKey.newBuilder()
+ .setVersion(0)
+ .setParams(validParamsForCurve(EllipticCurveType.NIST_P256))
+ .setX(ByteString.copyFrom(Hex.decode("00" + hexX)))
+ .setY(ByteString.copyFrom(Hex.decode("00" + hexY)))
+ .build();
+
+ return new ProtoKeySerialization[] {
+ // Bad private key value
+ ProtoKeySerialization.create(
+ "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey",
+ EciesAeadHkdfPrivateKey.newBuilder()
+ .setVersion(0)
+ .setPublicKey(validProtoPublicKey)
+ .setKeyValue(
+ ByteString.copyFrom(
+ Hex.decode(
+ // modified hexPrivateValue
+ "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6720")))
+ .build()
+ .toByteString(),
+ KeyMaterialType.ASYMMETRIC_PRIVATE,
+ OutputPrefixType.TINK,
+ /* idRequirement= */ 101),
+ // Bad version
+ ProtoKeySerialization.create(
+ "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey",
+ EciesAeadHkdfPrivateKey.newBuilder()
+ .setVersion(1)
+ .setPublicKey(validProtoPublicKey)
+ .setKeyValue(ByteString.copyFrom(Hex.decode(hexPrivateValue)))
+ .build()
+ .toByteString(),
+ KeyMaterialType.ASYMMETRIC_PRIVATE,
+ OutputPrefixType.TINK,
+ /* idRequirement= */ 101),
+ // Unknown prefix
+ ProtoKeySerialization.create(
+ "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey",
+ EciesAeadHkdfPrivateKey.newBuilder()
+ .setVersion(0)
+ .setPublicKey(validProtoPublicKey)
+ .setKeyValue(ByteString.copyFrom(Hex.decode(hexPrivateValue)))
+ .build()
+ .toByteString(),
+ KeyMaterialType.ASYMMETRIC_PRIVATE,
+ OutputPrefixType.UNKNOWN_PREFIX,
+ /* idRequirement= */ 101),
+ // Bad Public Key (X25519 Curve with EC Point Format uncompressed)
+ ProtoKeySerialization.create(
+ "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey",
+ EciesAeadHkdfPrivateKey.newBuilder()
+ .setVersion(0)
+ .setPublicKey(
+ EciesAeadHkdfPublicKey.newBuilder()
+ .setVersion(0)
+ .setParams(
+ validParamsForCurve(EllipticCurveType.CURVE25519).toBuilder()
+ .setEcPointFormat(EcPointFormat.UNCOMPRESSED)
+ .build())
+ .setX(ByteString.copyFrom(Random.randBytes(32)))
+ .build())
+ .setKeyValue(ByteString.copyFrom(Random.randBytes(32)))
+ .build()
+ .toByteString(),
+ KeyMaterialType.ASYMMETRIC_PUBLIC,
+ OutputPrefixType.TINK,
+ /* idRequirement= */ 101),
+ };
+
+ } catch (GeneralSecurityException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @DataPoints("invalidPrivateKeySerializations")
+ public static final ProtoKeySerialization[] INVALID_PRIVATE_KEY_SERIALIZATIONS =
+ createInvalidPrivateKeySerializations();
+
+ @Theory
+ public void testParseInvalidPrivateKeys_throws(
+ @FromDataPoints("invalidPublicKeySerializations") ProtoKeySerialization serialization)
+ throws Exception {
+ assertThrows(
+ GeneralSecurityException.class,
+ () -> registry.parseKey(serialization, InsecureSecretKeyAccess.get()));
+ }
}