• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16 
17 package com.google.crypto.tink.signature;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.junit.Assert.assertThrows;
21 
22 import com.google.crypto.tink.aead.ChaCha20Poly1305Key;
23 import com.google.crypto.tink.internal.KeyTester;
24 import com.google.crypto.tink.subtle.Random;
25 import com.google.crypto.tink.util.Bytes;
26 import com.google.crypto.tink.util.SecretBytes;
27 import java.security.GeneralSecurityException;
28 import org.junit.Test;
29 import org.junit.experimental.theories.DataPoints;
30 import org.junit.experimental.theories.FromDataPoints;
31 import org.junit.experimental.theories.Theories;
32 import org.junit.experimental.theories.Theory;
33 import org.junit.runner.RunWith;
34 
35 @RunWith(Theories.class)
36 public final class Ed25519PublicKeyTest {
37 
38   @DataPoints("requireIdVariants")
39   public static final Ed25519Parameters.Variant[] REQUIRE_ID_VARIANTS =
40       new Ed25519Parameters.Variant[] {
41         Ed25519Parameters.Variant.TINK,
42         Ed25519Parameters.Variant.CRUNCHY,
43         Ed25519Parameters.Variant.LEGACY
44       };
45 
46   @Test
buildNoPrefixVariantAndGetProperties()47   public void buildNoPrefixVariantAndGetProperties() throws Exception {
48     Bytes keyBytes = Bytes.copyFrom(Random.randBytes(32));
49 
50     Ed25519PublicKey key = Ed25519PublicKey.create(keyBytes);
51 
52     assertThat(key.getParameters()).isEqualTo(Ed25519Parameters.create());
53     assertThat(key.getPublicKeyBytes()).isEqualTo(keyBytes);
54     assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(new byte[] {}));
55     assertThat(key.getIdRequirementOrNull()).isNull();
56   }
57 
58   @Test
buildNoPrefixVariantExplicitAndGetProperties()59   public void buildNoPrefixVariantExplicitAndGetProperties() throws Exception {
60     Bytes keyBytes = Bytes.copyFrom(Random.randBytes(32));
61 
62     Ed25519PublicKey key =
63         Ed25519PublicKey.create(
64             Ed25519Parameters.Variant.NO_PREFIX, keyBytes, /* idRequirement= */ null);
65 
66     assertThat(key.getParameters()).isEqualTo(Ed25519Parameters.create());
67     assertThat(key.getPublicKeyBytes()).isEqualTo(keyBytes);
68     assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(new byte[] {}));
69     assertThat(key.getIdRequirementOrNull()).isNull();
70   }
71 
72   @Test
buildTinkVariantAndGetProperties()73   public void buildTinkVariantAndGetProperties() throws Exception {
74     Bytes keyBytes = Bytes.copyFrom(Random.randBytes(32));
75 
76     Ed25519PublicKey key =
77         Ed25519PublicKey.create(
78             Ed25519Parameters.Variant.TINK, keyBytes, /* idRequirement= */ 0x0708090a);
79 
80     assertThat(key.getParameters())
81         .isEqualTo(Ed25519Parameters.create(Ed25519Parameters.Variant.TINK));
82     assertThat(key.getPublicKeyBytes()).isEqualTo(keyBytes);
83     assertThat(key.getOutputPrefix())
84         .isEqualTo(Bytes.copyFrom(new byte[] {0x01, 0x07, 0x08, 0x09, 0x0a}));
85     assertThat(key.getIdRequirementOrNull()).isEqualTo(0x708090a);
86   }
87 
88   @Test
buildCrunchyVariantAndGetProperties()89   public void buildCrunchyVariantAndGetProperties() throws Exception {
90     Bytes keyBytes = Bytes.copyFrom(Random.randBytes(32));
91 
92     Ed25519PublicKey key =
93         Ed25519PublicKey.create(
94             Ed25519Parameters.Variant.CRUNCHY, keyBytes, /* idRequirement= */ 0x0708090a);
95 
96     assertThat(key.getParameters())
97         .isEqualTo(Ed25519Parameters.create(Ed25519Parameters.Variant.CRUNCHY));
98     assertThat(key.getPublicKeyBytes()).isEqualTo(keyBytes);
99     assertThat(key.getOutputPrefix())
100         .isEqualTo(Bytes.copyFrom(new byte[] {0x00, 0x07, 0x08, 0x09, 0x0a}));
101     assertThat(key.getIdRequirementOrNull()).isEqualTo(0x708090a);
102   }
103 
104   @Test
buildLegacyVariantAndGetProperties()105   public void buildLegacyVariantAndGetProperties() throws Exception {
106     Bytes keyBytes = Bytes.copyFrom(Random.randBytes(32));
107 
108     Ed25519PublicKey key =
109         Ed25519PublicKey.create(
110             Ed25519Parameters.Variant.LEGACY, keyBytes, /* idRequirement= */ 0x0708090a);
111 
112     assertThat(key.getParameters())
113         .isEqualTo(Ed25519Parameters.create(Ed25519Parameters.Variant.LEGACY));
114     assertThat(key.getPublicKeyBytes()).isEqualTo(keyBytes);
115     assertThat(key.getOutputPrefix())
116         .isEqualTo(Bytes.copyFrom(new byte[] {0x00, 0x07, 0x08, 0x09, 0x0a}));
117     assertThat(key.getIdRequirementOrNull()).isEqualTo(0x708090a);
118   }
119 
120   @Theory
requireIdButIdIsNotSet_fails( @romDataPoints"requireIdVariants") Ed25519Parameters.Variant variant)121   public void requireIdButIdIsNotSet_fails(
122       @FromDataPoints("requireIdVariants") Ed25519Parameters.Variant variant) throws Exception {
123     Bytes keyBytes = Bytes.copyFrom(Random.randBytes(32));
124 
125     assertThrows(
126         GeneralSecurityException.class,
127         () -> Ed25519PublicKey.create(variant, keyBytes, /* idRequirement= */ null));
128   }
129 
130   @Test
doesNotRequireIdButIdIsSet_fails()131   public void doesNotRequireIdButIdIsSet_fails() throws Exception {
132     Bytes keyBytes = Bytes.copyFrom(Random.randBytes(32));
133 
134     assertThrows(
135         GeneralSecurityException.class,
136         () ->
137             Ed25519PublicKey.create(
138                 Ed25519Parameters.Variant.NO_PREFIX, keyBytes, /* idRequirement= */ 1115));
139   }
140 
141   @Test
invalidKeySize()142   public void invalidKeySize() throws Exception {
143     Bytes keyBytes = Bytes.copyFrom(Random.randBytes(64));
144 
145     assertThrows(GeneralSecurityException.class, () -> Ed25519PublicKey.create(keyBytes));
146   }
147 
148   @Test
testEqualities()149   public void testEqualities() throws Exception {
150     Bytes keyBytes = Bytes.copyFrom(Random.randBytes(32));
151     Bytes keyBytesCopy = Bytes.copyFrom(keyBytes.toByteArray());
152     Bytes keyBytesDiff = Bytes.copyFrom(Random.randBytes(32));
153 
154     new KeyTester()
155         .addEqualityGroup(
156             "No prefix, keyBytes",
157             Ed25519PublicKey.create(keyBytes),
158             Ed25519PublicKey.create(
159                 Ed25519Parameters.Variant.NO_PREFIX, keyBytes, /* idRequirement= */ null),
160             Ed25519PublicKey.create(
161                 Ed25519Parameters.Variant.NO_PREFIX, keyBytesCopy, /* idRequirement= */ null))
162         .addEqualityGroup(
163             "No prefix, different key bytes",
164             Ed25519PublicKey.create(
165                 Ed25519Parameters.Variant.NO_PREFIX, keyBytesDiff, /* idRequirement= */ null))
166         .addEqualityGroup(
167             "Tink with key id 1907, keyBytes",
168             Ed25519PublicKey.create(
169                 Ed25519Parameters.Variant.TINK, keyBytes, /* idRequirement= */ 1907),
170             Ed25519PublicKey.create(
171                 Ed25519Parameters.Variant.TINK, keyBytesCopy, /* idRequirement= */ 1907))
172         .addEqualityGroup(
173             "Tink with key id 1908, keyBytes",
174             Ed25519PublicKey.create(
175                 Ed25519Parameters.Variant.TINK, keyBytes, /* idRequirement= */ 1908))
176         .addEqualityGroup(
177             "Crunchy with key id 1907, keyBytes",
178             Ed25519PublicKey.create(
179                 Ed25519Parameters.Variant.CRUNCHY, keyBytes, /* idRequirement= */ 1907))
180         .addEqualityGroup(
181             "Legacy with key id 1908, keyBytes",
182             Ed25519PublicKey.create(
183                 Ed25519Parameters.Variant.LEGACY, keyBytes, /* idRequirement= */ 1907))
184         .doTests();
185   }
186 
187   @Test
testDifferentKeyTypesEquality_fails()188   public void testDifferentKeyTypesEquality_fails() throws Exception {
189     SecretBytes secretKeyBytes = SecretBytes.randomBytes(32);
190     Bytes publicKeyBytes = Bytes.copyFrom(Random.randBytes(32));
191 
192     Ed25519PublicKey ed25519Key = Ed25519PublicKey.create(publicKeyBytes);
193     ChaCha20Poly1305Key chaCha20Poly1305Key = ChaCha20Poly1305Key.create(secretKeyBytes);
194 
195     assertThat(ed25519Key.equalsKey(chaCha20Poly1305Key)).isFalse();
196   }
197 }
198