1 // Copyright 2021 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.testing; 18 19 import com.google.crypto.tink.hybrid.internal.HpkeUtil; 20 import com.google.gson.JsonArray; 21 import com.google.gson.JsonElement; 22 import com.google.gson.JsonObject; 23 import com.google.gson.JsonParser; 24 import java.io.IOException; 25 import java.io.Reader; 26 import java.util.ArrayList; 27 import java.util.Arrays; 28 import java.util.HashMap; 29 import java.util.List; 30 import java.util.Map; 31 32 /** Test utility class for parsing test vectors from the HPKE I.-D. in JSON format. */ 33 public final class HpkeTestUtil { 34 /** 35 * Parses JSON-formatted test vectors from {@code path} into a {@link java.util.Map} from {@link 36 * com.google.crypto.tink.hybrid.internal.HpkeTestId}s to {@link 37 * com.google.crypto.tink.hybrid.internal.HpkeTestVector}s. 38 * 39 * <p>Example test vectors are available at 40 * https://github.com/cfrg/draft-irtf-cfrg-hpke/blob/5f503c564da00b0687b3de75f1dfbdfc4079ad31/test-vectors.json. 41 * 42 * @throws IOException if there's an error opening/parsing the file. 43 */ parseTestVectors(Reader reader)44 public static Map<HpkeTestId, HpkeTestVector> parseTestVectors(Reader reader) throws IOException { 45 Map<HpkeTestId, HpkeTestVector> testVectors = new HashMap<>(); 46 JsonArray testArray = JsonParser.parseReader(reader).getAsJsonArray(); 47 for (JsonElement testElement : testArray) { 48 JsonObject testObject = testElement.getAsJsonObject(); 49 HpkeTestId testId = 50 new HpkeTestId( 51 testObject.get("mode").getAsInt(), 52 testObject.get("kem_id").getAsInt(), 53 testObject.get("kdf_id").getAsInt(), 54 testObject.get("aead_id").getAsInt()); 55 // Filter out test vectors for unsupported modes and/or KEMs. 56 if (Arrays.equals(testId.mode, HpkeUtil.BASE_MODE) 57 || Arrays.equals(testId.mode, HpkeUtil.AUTH_MODE)) { 58 HpkeTestSetup.Builder testSetupBuilder = 59 HpkeTestSetup.builder() 60 .setInfo(testObject.get("info").getAsString()) 61 .setSenderEphemeralPublicKey(testObject.get("pkEm").getAsString()) 62 .setSenderEphemeralPrivateKey(testObject.get("skEm").getAsString()) 63 .setRecipientPublicKey(testObject.get("pkRm").getAsString()) 64 .setRecipientPrivateKey(testObject.get("skRm").getAsString()) 65 .setEncapsulatedKey(testObject.get("enc").getAsString()) 66 .setSharedSecret(testObject.get("shared_secret").getAsString()) 67 .setKeyScheduleContext(testObject.get("key_schedule_context").getAsString()) 68 .setSecret(testObject.get("secret").getAsString()) 69 .setKey(testObject.get("key").getAsString()) 70 .setBaseNonce(testObject.get("base_nonce").getAsString()); 71 if (Arrays.equals(testId.mode, HpkeUtil.AUTH_MODE)) { 72 testSetupBuilder = 73 testSetupBuilder 74 .setSenderPublicKey(testObject.get("pkSm").getAsString()) 75 .setSenderPrivateKey(testObject.get("skSm").getAsString()); 76 } 77 HpkeTestSetup testSetup = testSetupBuilder.build(); 78 JsonArray encryptionsArray = testObject.get("encryptions").getAsJsonArray(); 79 List<HpkeTestEncryption> testEncryptions = new ArrayList<>(); 80 for (JsonElement encryptionElement : encryptionsArray) { 81 JsonObject encryptionObject = encryptionElement.getAsJsonObject(); 82 HpkeTestEncryption testEncryption = 83 new HpkeTestEncryption( 84 testSetup.baseNonce, 85 encryptionObject.get("plaintext").getAsString(), 86 encryptionObject.get("aad").getAsString(), 87 encryptionObject.get("nonce").getAsString(), 88 encryptionObject.get("ciphertext").getAsString()); 89 testEncryptions.add(testEncryption); 90 } 91 testVectors.put(testId, new HpkeTestVector(testId, testSetup, testEncryptions)); 92 } 93 } 94 return testVectors; 95 } 96 HpkeTestUtil()97 private HpkeTestUtil() {} 98 } 99