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 #include "tink/experimental/pqcrypto/signature/dilithium_verify_key_manager.h" 18 19 #include <memory> 20 21 #include "absl/memory/memory.h" 22 #include "absl/status/status.h" 23 #include "absl/strings/str_cat.h" 24 #include "absl/strings/string_view.h" 25 #include "tink/experimental/pqcrypto/signature/subtle/dilithium_avx2_verify.h" 26 #include "tink/experimental/pqcrypto/signature/subtle/dilithium_key.h" 27 #include "tink/experimental/pqcrypto/signature/util/enums.h" 28 #include "tink/public_key_verify.h" 29 #include "tink/util/errors.h" 30 #include "tink/util/input_stream_util.h" 31 #include "tink/util/protobuf_helper.h" 32 #include "tink/util/secret_data.h" 33 #include "tink/util/status.h" 34 #include "tink/util/statusor.h" 35 #include "tink/util/validation.h" 36 37 extern "C" { 38 #include "third_party/pqclean/crypto_sign/dilithium2/api.h" 39 #include "third_party/pqclean/crypto_sign/dilithium3/api.h" 40 #include "third_party/pqclean/crypto_sign/dilithium5/api.h" 41 } 42 43 namespace crypto { 44 namespace tink { 45 46 using ::crypto::tink::subtle::DilithiumPublicKeyPqclean; 47 using ::crypto::tink::util::Status; 48 using ::crypto::tink::util::StatusOr; 49 using ::google::crypto::tink::DilithiumParams; 50 using ::google::crypto::tink::DilithiumPublicKey; 51 using ::google::crypto::tink::DilithiumSeedExpansion; 52 using ::crypto::tink::util::EnumsPqcrypto; 53 54 StatusOr<std::unique_ptr<PublicKeyVerify>> Create(const DilithiumPublicKey & public_key) const55DilithiumVerifyKeyManager::PublicKeyVerifyFactory::Create( 56 const DilithiumPublicKey& public_key) const { 57 util::StatusOr<DilithiumPublicKeyPqclean> dilithium_public_key = 58 DilithiumPublicKeyPqclean::NewPublicKey( 59 public_key.key_value(), 60 EnumsPqcrypto::ProtoToSubtle(public_key.params().seed_expansion())); 61 62 if (!dilithium_public_key.ok()) return dilithium_public_key.status(); 63 64 return subtle::DilithiumAvx2Verify::New(*dilithium_public_key); 65 } 66 ValidateKey(const DilithiumPublicKey & key) const67Status DilithiumVerifyKeyManager::ValidateKey( 68 const DilithiumPublicKey& key) const { 69 Status status = ValidateVersion(key.version(), get_version()); 70 if (!status.ok()) return status; 71 72 if (key.key_value().length() != PQCLEAN_DILITHIUM2_CRYPTO_PUBLICKEYBYTES && 73 key.key_value().length() != PQCLEAN_DILITHIUM3_CRYPTO_PUBLICKEYBYTES && 74 key.key_value().length() != PQCLEAN_DILITHIUM5_CRYPTO_PUBLICKEYBYTES) { 75 return Status(absl::StatusCode::kInvalidArgument, 76 "Invalid dilithium public key size."); 77 } 78 return util::OkStatus(); 79 } 80 ValidateParams(const DilithiumParams & params) const81Status DilithiumVerifyKeyManager::ValidateParams( 82 const DilithiumParams& params) const { 83 switch (params.seed_expansion()) { 84 case DilithiumSeedExpansion::SEED_EXPANSION_SHAKE: 85 case DilithiumSeedExpansion::SEED_EXPANSION_AES: { 86 break; 87 } 88 default: { 89 return Status(absl::StatusCode::kInvalidArgument, 90 "Invalid seed expansion"); 91 } 92 } 93 94 switch (params.key_size()) { 95 case PQCLEAN_DILITHIUM2_CRYPTO_SECRETKEYBYTES: 96 case PQCLEAN_DILITHIUM3_CRYPTO_SECRETKEYBYTES: 97 case PQCLEAN_DILITHIUM5_CRYPTO_SECRETKEYBYTES: { 98 break; 99 } 100 default: { 101 return Status(absl::StatusCode::kInvalidArgument, "Invalid key size."); 102 } 103 } 104 105 return util::OkStatus(); 106 } 107 108 } // namespace tink 109 } // namespace crypto 110