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.hybrid; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assert.assertThrows; 21 22 import java.security.GeneralSecurityException; 23 import org.junit.Test; 24 import org.junit.experimental.theories.DataPoints; 25 import org.junit.experimental.theories.FromDataPoints; 26 import org.junit.experimental.theories.Theories; 27 import org.junit.experimental.theories.Theory; 28 import org.junit.runner.RunWith; 29 30 @RunWith(Theories.class) 31 public final class HpkeParametersTest { 32 33 @DataPoints("variants") 34 public static final HpkeParameters.Variant[] VARIANTS = 35 new HpkeParameters.Variant[] { 36 HpkeParameters.Variant.TINK, 37 HpkeParameters.Variant.CRUNCHY, 38 HpkeParameters.Variant.NO_PREFIX, 39 }; 40 41 @DataPoints("kemIds") 42 public static final HpkeParameters.KemId[] KEM_IDS = 43 new HpkeParameters.KemId[] { 44 HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256, 45 HpkeParameters.KemId.DHKEM_P384_HKDF_SHA384, 46 HpkeParameters.KemId.DHKEM_P521_HKDF_SHA512, 47 HpkeParameters.KemId.DHKEM_X25519_HKDF_SHA256, 48 }; 49 50 @DataPoints("kdfIds") 51 public static final HpkeParameters.KdfId[] KDF_IDS = 52 new HpkeParameters.KdfId[] { 53 HpkeParameters.KdfId.HKDF_SHA256, 54 HpkeParameters.KdfId.HKDF_SHA384, 55 HpkeParameters.KdfId.HKDF_SHA512, 56 }; 57 58 @DataPoints("aeadIds") 59 public static final HpkeParameters.AeadId[] AEAD_IDS = 60 new HpkeParameters.AeadId[] { 61 HpkeParameters.AeadId.AES_128_GCM, 62 HpkeParameters.AeadId.AES_256_GCM, 63 HpkeParameters.AeadId.CHACHA20_POLY1305, 64 }; 65 66 @Theory buildParameters( @romDataPoints"variants") HpkeParameters.Variant variant, @FromDataPoints("kemIds") HpkeParameters.KemId kemId, @FromDataPoints("kdfIds") HpkeParameters.KdfId kdfId, @FromDataPoints("aeadIds") HpkeParameters.AeadId aeadId)67 public void buildParameters( 68 @FromDataPoints("variants") HpkeParameters.Variant variant, 69 @FromDataPoints("kemIds") HpkeParameters.KemId kemId, 70 @FromDataPoints("kdfIds") HpkeParameters.KdfId kdfId, 71 @FromDataPoints("aeadIds") HpkeParameters.AeadId aeadId) 72 throws Exception { 73 HpkeParameters params = 74 HpkeParameters.builder() 75 .setVariant(variant) 76 .setKemId(kemId) 77 .setKdfId(kdfId) 78 .setAeadId(aeadId) 79 .build(); 80 81 assertThat(params.getVariant()).isEqualTo(variant); 82 assertThat(params.getKemId()).isEqualTo(kemId); 83 assertThat(params.getKdfId()).isEqualTo(kdfId); 84 assertThat(params.getAeadId()).isEqualTo(aeadId); 85 } 86 87 @Theory buildParametersWithDefaultVariant( @romDataPoints"kemIds") HpkeParameters.KemId kemId, @FromDataPoints("kdfIds") HpkeParameters.KdfId kdfId, @FromDataPoints("aeadIds") HpkeParameters.AeadId aeadId)88 public void buildParametersWithDefaultVariant( 89 @FromDataPoints("kemIds") HpkeParameters.KemId kemId, 90 @FromDataPoints("kdfIds") HpkeParameters.KdfId kdfId, 91 @FromDataPoints("aeadIds") HpkeParameters.AeadId aeadId) 92 throws Exception { 93 HpkeParameters params = 94 HpkeParameters.builder().setKemId(kemId).setKdfId(kdfId).setAeadId(aeadId).build(); 95 96 assertThat(params.getVariant()).isEqualTo(HpkeParameters.Variant.NO_PREFIX); 97 assertThat(params.getKemId()).isEqualTo(kemId); 98 assertThat(params.getKdfId()).isEqualTo(kdfId); 99 assertThat(params.getAeadId()).isEqualTo(aeadId); 100 } 101 102 @Test buildParameters_failsWithoutKemId()103 public void buildParameters_failsWithoutKemId() throws Exception { 104 HpkeParameters.Builder builder = 105 HpkeParameters.builder() 106 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 107 .setAeadId(HpkeParameters.AeadId.AES_128_GCM); 108 109 assertThrows(GeneralSecurityException.class, builder::build); 110 } 111 112 @Test buildParameters_failsWithoutKdfId()113 public void buildParameters_failsWithoutKdfId() throws Exception { 114 HpkeParameters.Builder builder = 115 HpkeParameters.builder() 116 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 117 .setAeadId(HpkeParameters.AeadId.AES_128_GCM); 118 119 assertThrows(GeneralSecurityException.class, builder::build); 120 } 121 122 @Test buildParameters_failsWithoutAeadId()123 public void buildParameters_failsWithoutAeadId() throws Exception { 124 HpkeParameters.Builder builder = 125 HpkeParameters.builder() 126 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 127 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256); 128 129 assertThrows(GeneralSecurityException.class, builder::build); 130 } 131 132 @Test hasIdRequirement()133 public void hasIdRequirement() throws Exception { 134 HpkeParameters noPrefixParams = 135 HpkeParameters.builder() 136 .setVariant(HpkeParameters.Variant.NO_PREFIX) 137 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 138 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 139 .setAeadId(HpkeParameters.AeadId.AES_128_GCM) 140 .build(); 141 assertThat(noPrefixParams.hasIdRequirement()).isFalse(); 142 143 HpkeParameters tinkParams = 144 HpkeParameters.builder() 145 .setVariant(HpkeParameters.Variant.TINK) 146 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 147 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 148 .setAeadId(HpkeParameters.AeadId.AES_128_GCM) 149 .build(); 150 assertThat(tinkParams.hasIdRequirement()).isTrue(); 151 152 HpkeParameters crunchyParams = 153 HpkeParameters.builder() 154 .setVariant(HpkeParameters.Variant.CRUNCHY) 155 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 156 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 157 .setAeadId(HpkeParameters.AeadId.AES_128_GCM) 158 .build(); 159 assertThat(crunchyParams.hasIdRequirement()).isTrue(); 160 } 161 162 @Test sameParamsAreEqual()163 public void sameParamsAreEqual() throws Exception { 164 HpkeParameters params = 165 HpkeParameters.builder() 166 .setVariant(HpkeParameters.Variant.NO_PREFIX) 167 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 168 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 169 .setAeadId(HpkeParameters.AeadId.AES_128_GCM) 170 .build(); 171 172 HpkeParameters duplicateParams = 173 HpkeParameters.builder() 174 .setVariant(HpkeParameters.Variant.NO_PREFIX) 175 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 176 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 177 .setAeadId(HpkeParameters.AeadId.AES_128_GCM) 178 .build(); 179 180 assertThat(params).isEqualTo(duplicateParams); 181 assertThat(params.hashCode()).isEqualTo(duplicateParams.hashCode()); 182 } 183 184 @Test differentVariantsAreNotEqual()185 public void differentVariantsAreNotEqual() throws Exception { 186 HpkeParameters params = 187 HpkeParameters.builder() 188 .setVariant(HpkeParameters.Variant.NO_PREFIX) 189 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 190 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 191 .setAeadId(HpkeParameters.AeadId.AES_128_GCM) 192 .build(); 193 194 HpkeParameters differentVariant = 195 HpkeParameters.builder() 196 .setVariant(HpkeParameters.Variant.TINK) 197 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 198 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 199 .setAeadId(HpkeParameters.AeadId.AES_128_GCM) 200 .build(); 201 202 assertThat(params).isNotEqualTo(differentVariant); 203 assertThat(params.hashCode()).isNotEqualTo(differentVariant.hashCode()); 204 } 205 206 @Test differentKemAreNotEqual()207 public void differentKemAreNotEqual() throws Exception { 208 HpkeParameters params = 209 HpkeParameters.builder() 210 .setVariant(HpkeParameters.Variant.NO_PREFIX) 211 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 212 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 213 .setAeadId(HpkeParameters.AeadId.AES_128_GCM) 214 .build(); 215 216 HpkeParameters differentKem = 217 HpkeParameters.builder() 218 .setVariant(HpkeParameters.Variant.NO_PREFIX) 219 .setKemId(HpkeParameters.KemId.DHKEM_P384_HKDF_SHA384) 220 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 221 .setAeadId(HpkeParameters.AeadId.AES_128_GCM) 222 .build(); 223 224 assertThat(params).isNotEqualTo(differentKem); 225 assertThat(params.hashCode()).isNotEqualTo(differentKem.hashCode()); 226 } 227 228 @Test differentKdfsAreNotEqual()229 public void differentKdfsAreNotEqual() throws Exception { 230 HpkeParameters params = 231 HpkeParameters.builder() 232 .setVariant(HpkeParameters.Variant.NO_PREFIX) 233 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 234 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 235 .setAeadId(HpkeParameters.AeadId.AES_128_GCM) 236 .build(); 237 238 HpkeParameters differentKdf = 239 HpkeParameters.builder() 240 .setVariant(HpkeParameters.Variant.NO_PREFIX) 241 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 242 .setKdfId(HpkeParameters.KdfId.HKDF_SHA384) 243 .setAeadId(HpkeParameters.AeadId.AES_128_GCM) 244 .build(); 245 246 assertThat(params).isNotEqualTo(differentKdf); 247 assertThat(params.hashCode()).isNotEqualTo(differentKdf.hashCode()); 248 } 249 250 @Test differentAeadsAreNotEqual()251 public void differentAeadsAreNotEqual() throws Exception { 252 HpkeParameters params = 253 HpkeParameters.builder() 254 .setVariant(HpkeParameters.Variant.NO_PREFIX) 255 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 256 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 257 .setAeadId(HpkeParameters.AeadId.AES_128_GCM) 258 .build(); 259 260 HpkeParameters differentAead = 261 HpkeParameters.builder() 262 .setVariant(HpkeParameters.Variant.NO_PREFIX) 263 .setKemId(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) 264 .setKdfId(HpkeParameters.KdfId.HKDF_SHA256) 265 .setAeadId(HpkeParameters.AeadId.AES_256_GCM) 266 .build(); 267 268 assertThat(params).isNotEqualTo(differentAead); 269 assertThat(params.hashCode()).isNotEqualTo(differentAead.hashCode()); 270 } 271 } 272